git rebase 用法

Jc
5 min readOct 28, 2019

rebase 字面上的意思就是 重新定義基底,所以當一串 commit 的分支(branch)被重新定義基底之後,就某種角度來看就是在更改歷史記錄的動作。

目前有兩隻 branch,分別是 masterxyz-branch,而 xyz-branch 則是由在 commit C 的時候分出來的分支,而 master 在之後多了增加的 D、E commit 功能,而且都已經推上去遠端的 repository 了,如下圖的狀態。

Rebase 前的 git 線圖

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
Rebase 後的 git 線圖

這時候 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 的用法,感謝收看囉。

--

--