Git Merge 與 Rebase 合併分支整理


git rebase

保持提交歷史乾淨

  • rebase 會重播提交紀錄,使提交歷史呈現為一條「乾淨直線」。
  • 讓功能分支(如 feature/login)看起來像是直接從主幹(如 main)建立並開發。
  • 避免產生無意義的 merge commit,使 commit graph 更清晰。
# 當 main 有新提交,而 feature/login 尚未同步時
git checkout feature/login
git rebase main
# 將 feature/login 的提交重播到最新 main 之後

協同開發前整理提交

  • 使用 interactive rebase 可整理多個 commit,例如修改 commit 訊息、合併多個 commit 等。
# 假設想編輯最近 5 筆 commit
git rebase -i HEAD~5

# 將不必要的 commit 合併(例如改 pick 為 squash)

適用於需要線性歷史的團隊

  • 有些團隊會要求提交歷史保持線性,因此禁止使用 merge commit,改用 rebase 處理主幹合併。

工作原理(實際發生什麼事)

假設目前的提交歷史如下:

main:    A---B---C
              \
feature:       D---E

執行:

git checkout feature
git rebase main

步驟如下:

  1. 找出 featuremain 的共同祖先(此例為 B)。
  2. 暫存 feature 上的提交(D、E)。
  3. main 分支的新提交(C)移動到 feature
  4. 將 D、E 重播在 C 後面,形成新的提交 D'、E'。

結果:

main:    A---B---C
                   \
feature:            D'--E'

副作用與風險

  1. 改寫歷史

    • rebase 會重寫原有 commit,造成 SHA 值變動。
    • 若該分支已 push 到遠端,其他協作者拉取時會遇到衝突。
  2. 衝突處理繁瑣

    • 若提交數量多或變更範圍大,可能需手動解決多次衝突。

    • 若中途不想繼續,可取消操作:

      ​​​​​git rebase --abort
      
  3. 需要強制推送

    ​​​git push --force-with-lease
    
    • 請務必使用 --force-with-lease 而非 --force,以避免覆蓋他人提交。

git merge

將功能分支合併回主幹

  • 將功能分支(如 feature/login)合併回主幹(如 main),會產生一個 merge commit
git checkout main
git merge feature/login

合併他人變更到自己分支

  • 團隊成員提交的新分支也可透過 merge 合併至自己的開發分支。

保留多人協作紀錄

  • 使用 merge 可以完整保留每個分支的歷史與合併點,便於查閱開發流程。

用於 hotfix、release 合併流程

  • 在修補 bug 或整合版本時,常用 merge 合併至主幹或其他維護分支。

工作原理(實際發生什麼事)

假設目前歷史如下:

main:    A---B---C
                  \
feature:           D---E

執行:

git checkout main
git merge feature

結果:

  1. Git 找出共同祖先(此例為 C)。
  2. feature 分支的新提交(D、E)整合進 main
  3. 產生一個新的 merge commit(F),記錄此次合併。
main:    A---B---C-------F
                  \     /
feature:           D---E

副作用與風險

  • 過多的 merge commit

    • 每次小變更都 merge 會造成提交歷史混亂。
  • 非線性歷史

    • 使用 merge 會讓 git log --graph 顯示複雜分支結構。
  • 合併衝突

    • 若兩邊修改同一區塊,會發生衝突,需解決後手動完成合併:

      ​​​​git add .
      ​​​​git commit
      
  • 合併順序影響結果

    • 合併順序不同可能產生不同的 merge commit SHA,影響自動化流程。