淺談 Git 的 Merge 和 Rebase 的差異
TLDR
git merge保留完整歷程與合併點,適合異質性分支(如main與develop)合併。git rebase改寫歷程以維持線性,適合同質性分支(如origin/main與main)同步。git merge最多只需解決一次衝突;git rebase過程中若多個 Commit 發生衝突,可能需要多次解決。- 絕對禁止在已推送(Push)至遠端的共用分支上執行
git rebase,以免造成團隊協作災難。 - 使用
git pull --rebase可避免因同步遠端變更而產生不必要的合併 Commit。
合併分支的兩種方式
在 Git 中,合併分支主要有 git merge 與 git rebase 兩種做法,兩者對 Commit History 的影響截然不同。
git merge
什麼情況下會遇到:當需要將兩個具有不同開發目標的分支(異質性分支)整合在一起時。
- 優點:
- 保留完整的歷程記錄,包括每次合併的時間點。
- 在異質性分支間合併時,能清楚看到變更是如何整合進來的。
- 只需判斷與目標分支最新的 Commit 是否發生衝突,最多只需解決一次衝突。
- 缺點:
- 頻繁合併會使歷程記錄變得複雜。
- 產生大量合併 Commit,導致歷程顯得雜亂。
git rebase
什麼情況下會遇到:當需要整理分支歷程,使其看起來簡潔且呈線性發展時。
- 優點:
- 整理 Commit 歷程,使其看起來更簡潔和線性。
- 缺點:
- 改寫歷程會導致失去原始的合併點記錄。
- 若有多人合作開發,改寫歷程會造成混亂。
- 在移動過程中,每個 Commit 都會判斷是否衝突,可能需要多次解決衝突。
分支圖示例
以下透過 Mermaid 視覺化呈現兩者的差異:
原本的分支歷程:
Merge 的結果:
Rebase 的結果:
使用時機與建議
分支同質性判斷
- 同質性分支:指同一分支在遠端與本地的不同版本(如
origin/main與main)。建議使用git rebase。 - 異質性分支:指具有不同目標的分支(如
main與develop)。建議使用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 初版文件建立。
