當多人協作開發一個分支時,歷史記錄通常如下方左圖所示,比較凌亂。如果希望能像右圖那樣呈線性提交,就需要學習git rebase的用法。
“Merge branch”提交的產生
我們的工作流程是:修改代碼→提交到本地倉庫→拉取遠程改動→推送。正是在git pull這一步產生的Merge branch提交。事實上,git pull等效於get fetch origin和get merge origin/master這兩條命令,前者是拉取遠程倉庫到本地臨時庫,后者是將臨時庫中的改動合並到本地分支中。
要避免Merge branch提交也有一個“土法”:先pull、再commit、最后push。不過萬一commit和push之間遠程又發生了改動,還需要再pull一次,就又會產生Merge branch提交。
使用git pull –rebase
修改代碼→commit→git pull –rebase→git push。也就是將get merge origin/master替換成了git rebase origin/master,它的過程是先將HEAD指向origin/master,然后逐一應用本地的修改,這樣就不會產生Merge branch提交了。具體過程見下文擴展閱讀。
使用git rebase是有條件的,你的本地倉庫要“足夠干凈”。可以用git status命令查看當前改動::
|
本地沒有任何未提交的改動,這是最“干凈”的。稍差一些的是這樣:
|
即本地只有新增文件未提交,沒有改動文件。我們應該盡量保持本地倉庫的“整潔”,這樣才能順利使用git rebase。特殊情況下也可以用git stash來解決問題,有興趣的可自行搜索。
修改git pull的默認行為
每次都加–rebase似乎有些麻煩,我們可以指定某個分支在執行git pull時默認采用rebase方式:
|
如果你覺得所有的分支都應該用rebase,那就設置:
|
這樣對於新建的分支都會設定上面的rebase=true了。已經創建好的分支還是需要手動配置的。
擴展閱讀[1]:git rebase工作原理
先看看git merge的示意圖:
可以看到Some Feature分支的兩個提交通過一個新的提交(藍色)和master連接起來了。
再來看git rebase的示意圖:
Feature分支中的兩個提交被“嫁接”到了Master分支的頭部,或者說Feature分支的“基”(base)變成了 Master,rebase也因此得名。
擴展閱讀[2]:git merge –no-ff
在做項目開發時會用到分支,合並時采用以下步驟:
|
歷史就成了這樣:
可以看到,Merge branch ‘feature-branch'那段可以很好的展現出這些提交是屬於某一特性的。