面試官:說說你對Git Rebase 和 Git Merge的理解?區別?
本文轉載自微信公眾號「JS每日一題 」,作者灰灰 。轉載本文請聯系JS每日一題公眾號。
一、是什么
在使用 git 進行版本管理的項目中,當完成一個特性的開發并將其合并到 master 分支時,會有兩種方式:
- git merge
- git rebase
git rebase 與 git merge都有相同的作用,都是將一個分支的提交合并到另一分支上,但是在原理上卻不相同
用法上兩者也十分的簡單:
git merge
將當前分支合并到指定分支,命令用法如下:
- git merge xxx
git rebase
將當前分支移植到指定分支或指定commit之上,用法如下:
- git rebase -i <commit>
常見的參數有--continue,用于解決沖突之后,繼續執行rebase
- git rebase --continue
二、分析
git merge
通過git merge將當前分支與xxx分支合并,產生的新的commit對象有兩個父節點
如果“指定分支”本身是當前分支的一個直接子節點,則會產生快照合并
舉個例子,bugfix分支是從master分支分叉出來的,如下所示:
合并bugfix分支到master分支時,如果master分支的狀態沒有被更改過,即 bugfix分支的歷史記錄包含master分支所有的歷史記錄
所以通過把master分支的位置移動到bugfix的最新分支上,就完成合并
如果master分支的歷史記錄在創建bugfix分支后又有新的提交,如下情況:
這時候使用git merge的時候,會生成一個新的提交,并且master分支的HEAD會移動到新的分支上,如下:
從上面可以看到,會把兩個分支的最新快照以及二者最近的共同祖先進行三方合并,合并的結果是生成一個新的快照
git rebase
同樣,master分支的歷史記錄在創建bugfix分支后又有新的提交,如下情況:
通過git rebase,會變成如下情況:
在移交過程中,如果發生沖突,需要修改各自的沖突,如下:
rebase之后,master的HEAD位置不變。因此,要合并master分支和bugfix分支
從上面可以看到,rebase會找到不同的分支的最近共同祖先,如上圖的B
然后對比當前分支相對于該祖先的歷次提交,提取相應的修改并存為臨時文件(老的提交X和Y也沒有被銷毀,只是簡單地不能再被訪問或者使用)
然后將當前分支指向目標最新位置D, 然后將之前另存為臨時文件的修改依序應用
三、區別
從上面可以看到,merge和rebasea都是合并歷史記錄,但是各自特性不同:
merge
通過merge合并分支會新增一個merge commit,然后將兩個分支的歷史聯系起來
其實是一種非破壞性的操作,對現有分支不會以任何方式被更改,但是會導致歷史記錄相對復雜
rebase
rebase會將整個分支移動到另一個分支上,有效地整合了所有分支上的提交
主要的好處是歷史記錄更加清晰,是在原有提交的基礎上將差異內容反映進去,消除了 git merge所需的不必要的合并提交
參考文獻
https://zhuanlan.zhihu.com/p/361182707
https://yuweijun.github.io/git-zh/1-git-branching.html#_rebasing
https://backlog.com/git-tutorial/cn/stepup/stepup1_4.html































