Git 2.56:--resolved 讓解決衝突更安全
Git v2.56.0 Release Notes(git/git)· 2026-09-28
git add 多了一個新選項 --resolved,專門用來在合併衝突解完之後,只 stage 真正處理過的衝突路徑,不會把工作目錄裡其他還沒處理的改動一起捲進暫存區。這是 Git v2.56.0 release notes 的第一條 UI 改動,版本隨 Junio C Hamano 於 2026 年 9 月 28 日在 git 郵件論壇發出的公告一起釋出。
背景
合併出現衝突之後,過去要把解完的檔案交回 index,常見做法是對每個檔案手動 git add <path>,或圖方便直接下 git add -u / git add .。後兩種寫法的問題在於它們不分青紅皂白:只要路徑出現在 unmerged 清單或工作目錄有改動,就會被整批 stage,包括跟這次衝突無關、順手改掉的其他檔案。
更麻煩的是第二個風險:如果某個衝突檔案其實沒解乾淨,編輯器殘留的 <<<<<<<、=======、>>>>>>> 標記還留在檔案裡,git add -u 一樣會照 stage 不誤,衝突標記本身可能就這樣被提交進歷史。這種狀況在人工 review 沒抓到、或流程直接自動 commit 時特別容易發生,輕則造成編譯失敗,重則讓帶著標記的半殘檔案跑進正式分支,事後還得再開一個 commit 補救。這兩個問題以往都得靠人工檢查 diff 來把關,沒有工具層面的防呆,--resolved 出現以前 Git 本身並不會替使用者做這層檢查。
核心改動
release notes 原文寫道:「'git add' has been taught a new '--resolved' option to stage conflict-resolved paths, while leaving unrelated local changes unstaged. It scans the unmerged paths for leftover conflict markers and aborts if any are found.」--resolved 只掃描 unmerged 路徑,逐一檢查是否還留有衝突標記,只要找到就直接中止、不 stage 任何東西;確認乾淨後,才把這些路徑加入 index,工作目錄裡其他不相關的改動維持 unstaged。
## 解完衝突後,舊寫法
$ git add -u
# src/main.c(衝突路徑)與 README.md(不相關的順手修改)
# 一起被 stage,若 src/main.c 仍殘留 <<<<<<< 標記也照樣 stage
## Git 2.56 新寫法
$ git add --resolved
# 只掃描 unmerged 路徑;發現殘留衝突標記就中止並回報
# 通過檢查後只 stage 這些衝突路徑,README.md 維持 unstaged只要掃描到任何一個 unmerged 路徑仍有殘留標記,整個指令就會中止並回報,不會挑好的路徑先 stage、壞的路徑留著這種折衷做法——要嘛全部通過檢查,要嘛什麼都不動,逼使用者回頭把真正沒解乾淨的檔案修好,而不是帶著半殘檔案繼續往下走。
同一版 release notes 也提到 pack-objects 的更新:「The pack-objects command has been updated to support reachability bitmaps and delta-islands concurrently with the --path-walk option, allowing faster packaging by falling back to path-walk when bitmaps cannot fully satisfy the request.」過去 --path-walk 沒辦法跟 reachability bitmap、delta-islands 同時生效,等於在「用 bitmap 加速」跟「用 path-walk 分組打包」之間二選一;2.56 之後兩者可以同時啟用,當 bitmap 沒辦法完全覆蓋這次要打包的物件時,會自動退回用 path-walk 補齊,而不是整個放棄加速路徑。reachability bitmap 本身只涵蓋建立 bitmap 當下已知的歷史物件,遇到 bitmap 建立之後新增、或分支結構特殊而未被涵蓋的物件,過去就等同 bitmap 加速失效;2.56 讓這種「bitmap 涵蓋不到的部分」改由 path-walk 依檔案路徑分組去補打包,兩種機制銜接起來,而不是遇到涵蓋不到就整批退回慢速路徑。
影響範圍
在腳本、Git hook 或 CI 流程裡自動化處理合併衝突的團隊,如果目前是呼叫 git add -u 或 git add . 來收尾,值得檢查是否該換成 --resolved,尤其是那種「合併完直接 commit」的自動化路徑,換掉之後能避免殘留衝突標記被誤提交,也能避免不小心把無關改動一起帶進合併 commit。
對於維運大型 repository、定期跑 git repack 或 git pack-objects --path-walk 的管理者,尤其是同時啟用 delta-islands 的多 fork 代管環境(如程式碼代管平台),這項改動代表 repack 不用再放棄 bitmap 帶來的速度,就能吃到 path-walk 依路徑分組打包的效益,兩者疊加後對大型 monorepo 的 repack 時間會有幫助。升級到 2.56 前,建議先確認自家 CI 或部署腳本是否有寫死呼叫 git add 的舊參數組合,避免新選項改變預設行為時措手不及。
原始來源:Git v2.56.0 Release Notes、LWN.net: Git v2.56.0 released