rebase 字面上的意思就是 重新定義基底
,所以當一串 commit 的分支(branch)被重新定義基底之後,就某種角度來看就是在更改歷史記錄的動作。
目前有兩隻 branch,分別是 master
與 xyz-branch
,而 xyz-branch
則是由在 commit C 的時候分出來的分支,而 master
在之後多了增加的 D、E commit 功能,而且都已經推上去遠端的 repository 了,如下圖的狀態。
master logs :
703c410 E commit
a2a8535 D commit
ccab950 C commit
2f5ecdc B commit
4b9af79 A commit
xyz-branch logs:
9886c3b Z commit
efb76ba Y commit
fff823a X commit
ccab950 C commit
2f5ecdc B commit
4b9af79 A commit
因爲在 xyz-branch
的時候需要之後才加進去 master 的 D、E commit
,所以當你現在正在 xyz-branch 的分支,
執行了 :
$ git checkout xyz-branch$ git rebase master
這時候 xyz-branch
的基礎就會從 C commit ,變成 E commit 了,所以以 xyz-branch
的角度來說,就藉由 rebase(重新定義基底)
,來得到之後才加進去 master 的 D、E commit
的功能。
rebase 後的 xyz-branch logs:
d1c0f88 Z commit
e681ab1 Y commit
d76d1b0 X commit
703c410 E commit
a2a8535 D commit
ccab950 C commit
2f5ecdc B commit
4b9af79 A commit
這邊要注意的是:
此時 rebase 後的 xyz-branch 的 X、Y、Z 的 commit id 的跟原先的版本已經完全不一樣了,因爲 rebase 過後的 X、Y、Z 的 commit 是經過重新計算後所產生的,所以才會造成雖然內容物與 commit message 相同,但是 commit id 已經不一樣的現象。
馬上會遇到的是:當你想要在推 xyx-branch 到遠端的時候馬上會出現下面的訊息:
$ git push origin xyz-branch
To git@github.com:Jessie75919/git-rebase-demo.git
! [rejected] xyz-branch -> xyz-branch (non-fast-forward)
error: failed to push some refs to 'git@github.com:Jessie75919/git-rebase-demo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
最直覺的方式就是 force
強制推上去(不推薦):
$ git push --force origin xyz-branch
但是這個做法只限於只有自己單人作業(不會影響到他人)的情況下,如果這個專案是會需要與他人合作的專案的話,當你使用了 — force 就很有可能會刪除掉他人所提交的 commit 資訊。
後來發現有個更安全的方式 force-with-lease
:
$ git push --force-with-lease origin xyz-branch
如果用這個方式推送的話,如果有其他人的 commit 在上面了,那就會這次的推送就會被拒絕,但如果沒有的話,就可以順利的推送上去囉。
更詳細的用法請參考: https://blog.walterlv.com/post/safe-push-using-force-with-lease.html
下次在來講講 git rebase -i
的用法,感謝收看囉。