2013年11月25日 星期一

Git (二) Rebase vs Merge

rebase 跟 merge 做的事情其實很像

主要的差別在於
假設我在 branch下指令  git merge master,
merge 會一次性的將所有master的commit 直接merge進 branch
rebase的話  則會分成多次commit 進來




舉個例子來看看


上面分別有master and branch 兩個分支
我在 branch 上做了兩次commit  branchC  and branchD
然後我在 master 上做了三次commit masterA ,masterB and masterC



Merge

首先我們先使用merge 指令
在branch分支下指令 git merge master
master的資料將會在一次commit 中將 masterA , masterB and masterC
都加進我的branch分支內,我們看到的commit結果會是如上圖
branchC, branchD ,Merge branch 'master' into branch ,
要倒回去的話只需要下指令git reset --hard HEAD^
就可以恢復merge之前的狀態



Rebase 

接著使用 rebase 指令
在branch分支下指令 git rebase master



可以看到原本分為兩個的分支結合再一起了
可以看到git rebase master之後的結果會是  
masterA , masterB, masterC , branchC and branchD 跟git merge master的結果有些差別
不過上圖並不好解釋會何會變成這樣,下面的圖比較能解釋他的原因

原本的基準點為左圖最下的藍色點,
當我們使用 git rebase master時,branch分支會將基準點從最下方的藍色點rebase到 master 的最上方的點,也就是如右圖所示(可以把他想成pointer 將指標指過去的感覺),
所以最後會只看到一條線。
經過rebase之後的分支要倒回並不是那麼的容易,
我的做法會是在create一個新的分支,然後將這次的Rebase都倒回之後再用cherry-pick將原本的commit 拉回來。



結論

            git merge master是一次性的commit ,然而git rebase master是多次性的commit 。


git merge 的commit是依照順序的 branchC, branchD 然後將master commit 進來masterA masterB masterC,
所以結果會是:branchC, branchD masterA masterB masterC
然而git rebase 的commit是先rebase到master分支再將原本的commit apply回來
所以順序會是: masterA masterB masterC branchC, branchD


Merge和Rebase的用途也不太相同

通常Rebase的用途在於  有同事在遠端commit了新的code進來
我希望我現在修改的版本能base到最新的版本
這時候就可以使用rebase command 讓手邊的程式更新到最新的版本

Merge的話比較像是我在某個分支完成了一個大型修正或功能,而且也經過大量測試之後
想要將這個功能導入我現在的working directory,
這時候就可以使用merge, 記住 merge是一次性的commit 所以所有關於該feature的功能將會一次性的導入你並不會在working directory中看到有關於該feature的其他commit




沒有留言:

張貼留言