git 代碼合并
在Git中, git merge 和 git rebase 都是用來將一個分支的修改并入另一個分支,只不過方式不同。
在日常工作中基本都會有一個工作主分支,一般我們會新建一個新的分支開始我們的工作,以免影響主分支。我們假設以下的情景來說明代碼合并。
小李需要開發FeatureA,因此他在項目主分支的基礎上新建了一個FeatureA的分支開始了他的工作,在他工作的同時,同事修復了兩個bug,并且都合入了主分支,于是代碼分支變成 了下面這種情況:
分支狀況
這時候小李想基于修復好bug的版本繼續之前的開發,那么就需要將自己的代碼和已經分叉的主分支進行合并,采取的方法可以是 git merge ,也可以是 git rebase .
git merge
一般來說,最簡單的操作就是執行下面的步驟:
git checkout featureA git merge master
或者直接:
git merge master featureA
這樣就會產生一個三路合并:
git merge
git merge 的優點就是簡單,并且產生一個合并的歷史,但是如果master分支的歷史很活躍,你又想始終保持與master一致,那么多多少少那么多的合并歷史會影響到你分支歷史的整潔性。這時候 git rebase 就可以登場了。
關于更多 git merge 的詳細述說可以看我上一篇文章:git 分支管理
git rebase
作為 merge 的替代,我們可以這樣執行 rebase :
git checkout featureA git rebase master
它會把整個featureA的分支直接移到現在master分支的后面:
git rebase
git rebase 最大的特點就是會使你的項目歷史非常干凈,呈現出一條線性提交,因為它不會引入合并提交,這讓你更容易使用 git log 、 git bisect 和 gitk 來查看項目歷史。
不過說 git rebase 也是 git 中的黑魔法,如果不遵守使用 git rebase 的黃金法則,也會給你的項目歷史帶來災難性的影響, rebase 使你的 feature 分支沒有合并提交歷史,所以你也看不出 feature 合并進了上游的哪些修改。
交互式的rebase
這里假設小A在他的 featureA 分支已經有三個提交了,這時候如果直接 rebase 就會把 這三個提交歷史都接到 master 分支后面。
帶有三次提交歷史的feature分支
而交互式的 rebase 則可以對 featureA 的分支歷史進行清理。
加上 -i ,我們執行交互式的 rebase :
git checkout featureA git rebase -i master
它會打開你 git 的文本編輯器:
pick 33d5b7a Message for commit #1 pick 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3
這個列表顯示了你fetureA的歷史,你可以通過更改順序,更改pick或者使用fixup來合并你的歷史。比如如果 #2 和 #3 包含了修復性的更改,你想合并他們,那么你可以加上一個fixup:
pick 33d5b7a Message for commit #1 pick 9480b3d Message for commit #2 fixup 5c67e61 Message for commit #3
fixup
如圖所示, #2 和 #3 被合并為一次提交,這樣在合并的過程中還能簡化項目歷史,這是 git merge 辦不到的。
Rebase黃金法則
當你使用 Rebase 更加方便地處理你的分支時,你也必須懂得有哪些潛在的風險。使用 rebase 的一條黃金法則就是,絕對不要在公共分支上使用它。假設你使用了,那么便會發生下面的情況:
在主分支上rebase
如上圖,你在主分支上的 git rebase 將 master 分支移到了 featureA 分支的后面,而其他開發者還是基于原有的 master 分支進行開發,這時候你的 master 分支就和別人的分叉了,如果需要同步,則需要額外的一次 git merge ,以讓你目前的 master 和別人的 master 合并,你的項目歷史更加令人迷惑。
所以,在進行 git rebase 時,務必確認有沒有別人在此分支上工作,如果有的話,那么你就得考慮一種無害的方式來進行你的提交,比如 git revert 這樣的操作。
來自:http://www.jianshu.com/p/b15574f50939