Git 分支合併的 3 種方式你掌握了?

大家好,我是七哥,好久不見了。前一陣回老家後事情比較多,包括找工作、新入職的適應等等,還是比較累。

最近也算是告一段落了,新入職的公司感覺也蠻不錯的,後面時間多了會多輸出一些技術文章和視頻,大家期待一波哈😄。

最近新入職,在提交 pr,然後 code review 後,關於分支合併我產生了一個小問題,那就是 squash mergerebase merge 到底有什麼區別呢?公司爲什麼要求使用 git rebase merge 呢?之前我們都是直接一把梭 git merge 分支名來合併。

帶着這兩個疑問我們以一個實際的開發場景來搞明白 merge, squash merge, 和 rebase merge之間的區別,接着往後看吧。

舉個例子,如果我們有一個項目,它包含一個 master 主分支,有 3 個提交,分別是 1、2、3 和 1 個功能開發分支 dev,在功能分支上提交 A、B 、C 如下圖所示。

現在我們完成了 dev 分支的開發測試工作,需要把 dev 分支合併回 master 分支。

git merge

這是最基本的 merge,就是把提交歷史原封不動的拷貝過來,包含完整的提交歷史記錄。

$ git checkout master
$ git merge dev

此時還會生產一個 merge commit (D'),這個 merge commit 不包含任何代碼改動,而包含在 dev 分支上的幾個 commit 列表 (A, B 和 C)。查看 git 的提交歷史(git log) 可以看到所有的這些提交歷史記錄。

git squash merge

根據字面意思,這個操作完成的是壓縮的提交,解決的是什麼問題呢?由於在 dev 分支上執行的是開發工作,有一些很小的提交,或者是糾正前面的錯誤的提交,對於這類提交對整個工程來說不需要單獨顯示出來一次提交,不然導致項目的提交歷史過於複雜。所以基於這種原因,我們可以把 dev 上的所有提交都合併成一個提交;然後提交到主幹。

在這個例子中,我們把 A,B 和 C 的改動合併成了一個 D。

注意,squash merge 並不會替我們產生提交 D,它只是把所有原本屬於 A、B 和 C 的改動合併,然後放在本地文件,需要你再次手動執行 git commit 操作。

此時又要注意了,因爲你要你手動 commit,也就是說這個 commit 是你產生的,不是由原來 dev 分支上的開發人員產生的,提交者本身發生了變化。也可以這麼理解,就是你把 dev 分支上的所有代碼改動一次性提交到 master 分支上而已。

git rebase merge

由於 squash merge 會變更提交者作者信息,這是一個很大的問題,後期問題追溯不好處理 (當然也可以由分支 dev 的所有者來執行 squash merge 操作,以解決部分問題),rebase merge 可以保留提交的作者信息,同時可以合併 commit 歷史,完美的解決了上面的問題。

$ git checkout dev
$ git rebase -i master
$ git checkout master
$ git merge dev

rebase merge 分兩步完成:

**第一步:**執行 rebase 操作,結果是看起來 dev 分支是從主分支的提交 3 拉出來的,而不是從提交 2 拉出來的,然後使用 - i 參數手動調整 commit 歷史,是否合併如何合併。例如 rebase -i 命令會彈出文本編輯框:

pick <A> Message for commit #1
pick <B> Message for commit #2
pick <C> Message for commit #3

假設提交 B 是對提交 A 的一個拼寫錯誤修正,因此可以不需要顯式的指出來,我們把 B 修改爲 fixup:

pick <A> Message for commit #1
fixup <B> Message for commit #2
pick <C> Message for commit #3

rebase 之後的狀態變爲:

A' 是 A 和 B 的合併。

第二步:再執行 merge 操作,把 dev 分支合併到 master 分支:

注意:

  1. 在執行 rebase 的時候可能會出現衝突的問題,此時需要手工解決衝突的問題,然後執行 (git add) 命令;

  2. 所有衝突解決完之後,這時不需要執行 (git commit) 命令,而是運行 (git rebase --continue) 命令,一直到 rebase 完成;如果中途想放棄 rebase 操作,可以運行 (git rebase --abort) 命令回到 rebase 之前的狀態。

使用 git merge 和 git rebase 的時機

因爲 rebase 會修改歷史記錄,將當前分支的提交記錄先取消,更新遠程分支的記錄進來作爲基礎版本,然後在應用當前分支的提交記錄,所以如果當前分支別人也在使用,還是需要小心,因爲改變了歷史記錄有可能會對別人產生影響,但是如果是你自己的分支就可以合併以及隱藏你的具體提交記錄和創建的分支。

因此如果 branch 是私有分支,rebase 可以有效幫你「重整版本」來保持 commit 記錄是呈線性整齊,我們公司目前是一個任務拉一個分支,在合併之前可以使用 git rebase master 將主幹分支其他人的提交記錄做爲基礎版本然後應用你個人分支的變更,這樣可以保持提交記錄的有序性,然後在 pr 通過後使用 squahs merge 來合併分支。

因爲有可能你個人分支上做了很多次 commit,這個對於主幹分支來說是不需要關注的,其他人只需要關注你這某一個需求做完了合併進來即可,所以合併爲一次是比較合理的,可以避免太多的提交記錄造成困擾。

到這裏 git 合併分支的三種方式你應該都理解了,如果還有啥疑問歡迎一起交流學習。也歡迎給文末點個贊哦👍。

作者介紹: 七哥,非科班轉行程序員,靠努力學習一步步成功,寫文章也經常拍視頻,專注編程技術與個人成長乾貨分享,願望是陪家人平淡快樂的度過一生!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/_gpwFS7g3VvRyaHAQUtsZg