筆記目錄

Skip to content

淺談 Git 的 Merge 和 Rebase 的差異

TLDR

  • git merge 保留完整歷程與合併點,適合異質性分支(如 maindevelop)合併。
  • git rebase 改寫歷程以維持線性,適合同質性分支(如 origin/mainmain)同步。
  • git merge 最多只需解決一次衝突;git rebase 過程中若多個 Commit 發生衝突,可能需要多次解決。
  • 絕對禁止在已推送(Push)至遠端的共用分支上執行 git rebase,以免造成團隊協作災難。
  • 使用 git pull --rebase 可避免因同步遠端變更而產生不必要的合併 Commit。

合併分支的兩種方式

在 Git 中,合併分支主要有 git mergegit rebase 兩種做法,兩者對 Commit History 的影響截然不同。

git merge

什麼情況下會遇到:當需要將兩個具有不同開發目標的分支(異質性分支)整合在一起時。

  • 優點:
    • 保留完整的歷程記錄,包括每次合併的時間點。
    • 在異質性分支間合併時,能清楚看到變更是如何整合進來的。
    • 只需判斷與目標分支最新的 Commit 是否發生衝突,最多只需解決一次衝突。
  • 缺點:
    • 頻繁合併會使歷程記錄變得複雜。
    • 產生大量合併 Commit,導致歷程顯得雜亂。

git rebase

什麼情況下會遇到:當需要整理分支歷程,使其看起來簡潔且呈線性發展時。

  • 優點:
    • 整理 Commit 歷程,使其看起來更簡潔和線性。
  • 缺點:
    • 改寫歷程會導致失去原始的合併點記錄。
    • 若有多人合作開發,改寫歷程會造成混亂。
    • 在移動過程中,每個 Commit 都會判斷是否衝突,可能需要多次解決衝突。

分支圖示例

以下透過 Mermaid 視覺化呈現兩者的差異:

原本的分支歷程:

Merge 的結果:

Rebase 的結果:

使用時機與建議

分支同質性判斷

  • 同質性分支:指同一分支在遠端與本地的不同版本(如 origin/mainmain)。建議使用 git rebase
  • 異質性分支:指具有不同目標的分支(如 maindevelop)。建議使用 git merge

實務建議

  • git pull 本質上是 git fetch 加上 git merge。若希望保持線性,建議使用 git pull --rebase,將本地更改整合到遠端變更之上。
  • 在發送 MR(Merge Request)前,建議先使用 git rebase 將當前分支移至目標分支的最新狀態,確保無衝突後再提交。

TIP

有關解決衝突的權責應該是在審核者還是 MR 提交者,不同團隊作法不同,請依各團隊規定。

WARNING

除了 git pull --rebase 以外,Rebase 相關操作應僅用於自身開發的分支上進行,請勿在共用的分支上操作。

對共用分支的 Rebase 操作應僅在尚未執行 git push 前執行,因為一旦 git push 又變更本地儲存庫的 Commit 歷程,會導致本地與遠端的歷程不一致,如果使用 git push --force 強制變更遠端儲存庫,則會換成其他人的本地遠端儲存庫歷程和不一致。這樣的操作不僅影響團隊協作,還可能引發爭議。

異動歷程

  • 2024-08-23 初版文件建立。