Eclipse上GIT插件EGIT使用手冊之九_Rebase和Merge的區別
Rebase和Merge操作最終的結果是一樣的,但是實現原理不一樣。
從上面的MairoBro例子可以知道pull大概對歷史記錄進行了怎樣的合并操作,其實默認pull的操作就是一個分支的merge操作,如下圖重現一下:
Mairo弟弟的提交記錄如下:
Mairo哥哥的提交記錄如下:
首先是Mairo弟弟把更新push到服務器,這樣服務器端的記錄就和Mairo弟弟本地的記錄是一樣的,接著Mairo哥哥執行pull操作,現在分析下pull是如何操作的。
l pull默認就是先把服務器端的最新記錄更新到本地的Remote Tracking中對應的mirror分支
l 接著對Local的mirror分支和Remote Tracking的mirror分支進行merge操作
Merge操作后的結果就是會新增加一個merge記錄節點,如下所示:
從上圖可以看出,mushroomA是在mushroomB之前的,這個時間關系不取決于誰先執行push,而取決于本地倉庫中誰先執行commit。所以merge會按照時間順序嚴格的記錄每一次commit。
接下來看看rebase,其實rebase也是把兩個分支進行合并的操作,當Mairo弟弟push更新后,服務器端的mirror分支的歷史如下:
Mairo哥哥本地的歷史如下:
現在Mairo哥哥不是執行merge操作,而是執行rebase操作,最后結果如下:
很明顯的區別是沒有出現分支的記錄,而且注意到mushroomA*,請注意這個記錄和mushroomA不是同一個記錄,我們先分析下rebase操作下,Mairo哥哥的歷史記錄都做了哪些變化:
l 先將當前分支的更新部分保存到臨時區域,而當前分支重置到上一次pull的記錄
l 然后將服務器端的更新添加到當前分支,此時當前分支和服務器端分支是一樣的
l 最后將原分支的更新部分mushroomA提交到當前分支的后面,就是要在mushroomB的后面添加mushroomA的更新,當然此時更新記錄已經不是之前的mushroomA了,如果出現沖突則使用對比工具解決沖突,最后記錄變成mushroomA*。