Git 合併 (Merge)
git merge 把一個分支的變更合併到另一個分支,是團隊協作中最常用的操作之一。
基本用法
假設你在 feature 分支完成了開發,要合併回 main:
# 1. 切換到目標分支
git checkout main
# 2. 合併來源分支
git merge feature
這會把 feature 分支的變更合併到 main。
合併的類型
Fast-forward 合併
當目標分支沒有新的 commit 時,Git 會執行 fast-forward 合併:
合併前:
main: A --- B
\
feature: C --- D
合併後:
main: A --- B --- C --- D
git checkout main
git merge feature
# Fast-forward
這種合併不會產生新的 merge commit,只是把 main 的指標移動到 feature 的最新位置。
三方合併 (3-way merge)
當兩個分支都有新的 commit 時,Git 會執行三方合併:
合併前:
main: A --- B --- E
\
feature: C --- D
合併後:
main: A --- B --- E --- M
\ /
feature: C --- D
git checkout main
git merge feature
# Merge made by the 'ort' strategy.
三方合併會產生一個新的 merge commit(M),有兩個父 commit。
合併選項
禁止 Fast-forward
git merge --no-ff feature
即使可以 fast-forward,也會建立一個 merge commit。這樣可以保留分支的歷史:
main: A --- B --------- M
\ /
feature: C --- D
只允許 Fast-forward
git merge --ff-only feature
如果不能 fast-forward,就會失敗。適合用在希望保持線性歷史的情況。
Squash 合併
git merge --squash feature
把 feature 分支的所有變更壓縮成一個 commit,但不會自動 commit:
git merge --squash feature
git commit -m "Add feature (squashed)"
結果:
main: A --- B --- C (包含 feature 的所有變更)
Squash 合併不會保留原本的 commit 歷史,適合不想保留細節的情況。
指定 Commit 訊息
git merge feature -m "Merge feature branch"
合併策略
Git 有多種合併策略,大部分情況下自動選擇就好:
# 使用特定策略
git merge -s recursive feature
git merge -s ours feature
git merge -s theirs feature
recursive:預設策略,適合大多數情況ours:保留我們的版本,忽略對方的變更resolve:較舊的策略
合併遠端分支
# 先取得遠端更新
git fetch origin
# 合併遠端分支
git merge origin/main
或者一步到位:
git pull origin main
git pull = git fetch + git merge
查看合併狀態
查看即將合併的內容
# 先不合併,只查看
git log main..feature # feature 有哪些 commit
git diff main...feature # 差異是什麼
查看合併歷史
git log --merges # 只顯示 merge commit
git log --graph # 圖形化顯示
取消合併
合併前取消
如果還沒開始合併,但想取消:
git merge --abort
合併後取消
如果合併已完成,想回到合併前:
# 如果還沒推送到遠端
git reset --hard HEAD~1
# 如果已經推送(產生新的 revert commit)
git revert -m 1 HEAD
處理合併衝突
當兩個分支修改了同一個檔案的同一個部分,Git 無法自動合併,就會產生衝突。
詳細說明請參考下一篇「解決合併衝突」。
實際範例
合併功能分支
# 確保 main 是最新的
git checkout main
git pull
# 合併功能分支
git merge feature/login --no-ff
# 推送
git push
合併多個分支
git checkout main
git merge feature1 feature2 feature3
合併特定 Commit
如果只想合併特定的 commit,用 cherry-pick:
git cherry-pick a1b2c3d
最佳實踐
合併前先更新:先
git pull確保你的main是最新的用
--no-ff保留歷史:讓合併的來龍去脈更清楚刪除已合併的分支:保持分支列表乾淨
git branch -d feature/login
避免長期分支:分支存在越久,合併衝突的機會越大
小步合併:經常合併,避免大規模衝突
合併 vs Rebase
合併和 Rebase 都可以整合分支,差異在於:
- Merge:保留分支的歷史,產生 merge commit
- Rebase:重寫歷史,讓 commit 變成線性
詳細比較請參考「Git rebase」。