標籤:
當多人協作開發一個分支時,記錄通常如下方左圖所示,比較淩亂。如果希望能像右圖那樣呈線性提交,就需要學習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 statusOn branch masterYour branch is up-to-date with ‘origin/master‘.nothing to commit, working directory clean
|
本地沒有任何未提交的改動,這是最“乾淨”的。稍差一些的是這樣:
$ git statusOn branch masterYour branch is up-to-date with ‘origin/master‘.Untracked files: (use "git add <file>..." to include in what will be committed) test.txtnothing added to commit but untracked files present (use "git add" to track)
|
即本地只有新增檔案未提交,沒有改動檔案。我們應該盡量保持本地倉庫的“整潔”,這樣才能順利使用git rebase。特殊情況下也可以用git stash來解決問題,有興趣的可自行搜尋。
修改git pull的預設行為
每次都加–rebase似乎有些麻煩,我們可以指定某個分支在執行git pull時預設採用rebase方式:
$ git config branch.master.rebase true
|
如果你覺得所有的分支都應該用rebase,那就設定:
$ git config --global branch.autosetuprebase always
|
這樣對於建立的分支都會設定上面的rebase=true了。已經建立好的分支還是需要手動設定的。
擴充閱讀[1]:git rebase工作原理
先看看git merge的:
圖片來源
可以看到Some Feature分支的兩個提交通過一個新的提交(藍色)和master串連起來了。
再來看git rebase的:
Feature分支中的兩個提交被“嫁接”到了Master分支的頭部,或者說Feature分支的“基”(base)變成了 Master,rebase也因此得名。
擴充閱讀[2]:git merge –no-ff
在做項目開發時會用到分支,合并時採用以下步驟:
$ git checkout feature-branch$ git rebase master$ git checkout master$ git merge --no-ff feature-branch$ git push origin master
|
曆史就成了這樣:
可以看到,Merge branch ‘feature-branch‘那段可以很好的展現出這些提交是屬於某一特性的。
使用git Rebase讓曆史變得清晰