將功能分支合併到主發布分支 (main) 後,您可能會發現一個嚴重的錯誤,需要您立即回溯整合。
透過標準提交,您可以使用 git revert <commit-hash> 輕鬆撤銷變更。但是,嘗試恢復合併提交會直接導致 Git 錯誤:fatal: commit <hash> is a merge but no -m option was given.
在本指南中,我們將解釋為什麼合併復原需要特殊處理,逐步使用 git revert -m 選項,並揭示稍後重新合併復原功能的隱藏陷阱。
1. 為什麼 Git 需要 -m 選項?
典型的提交只有一個父提交(其直接前任)。恢復它很簡單,因為 Git 確切地知道要減去什麼。
相反,合併提交有兩個或多個父提交(表示正在合併的分支和正在合併的分支)。 Git 不知道哪個父級應該被視為「主線」歷史記錄。如果沒有指示,Git 無法確定應保留哪些分支的變更以及應丟棄哪些分支。
-m(或 --mainline)選項告訴 Git 要保留哪個父路徑。
2. 逐步合併還原
步驟 1: 檢查合併提交父項
首先,檢查目標合併提交:
git show <merge-commit-hash>
在輸出的頂部,找到 Merge: 行:
commit a1b2c3d4e5f6...
Merge: 9e8d7c6 5a4c3d2
這些哈希值代表父提交:
- 父級 1 (
9e8d7c6):接收合併的分支(例如main)。 - 父級 2 (
5a4c3d2):合併的分支(例如feature)。
步驟 2:執行指定父級 1 的恢復
若要保留 main 分支(父分支 1)的歷史記錄並回溯傳入的更改,請執行:
git revert -m 1 a1b2c3d4e5f6
Git 將開啟編輯器來完成提交訊息。儲存以執行還原。
3. 重組陷阱
當您在修復錯誤後嘗試將相同的功能分支合併回 main 時,會發生恢復合併提交的最棘手的方面。
如果您嘗試簡單的合併,**Git 將僅匯入新的錯誤修復。您的大部分原始功能代碼將會遺失。 **
為什麼會出現這種情況?
Git 會追蹤原始功能分支提交已合併到 main 中的事實。您執行的 revert 操作沒有刪除這些提交;它只是新增了一個新的提交來撤銷他們的修改。因此,Git 假定功能提交已經存在,並在第二次合併期間忽略它們。
解決方案(恢復恢復):
若要成功重新套用功能分支,請勿合併分支本身。相反,恢復原始的恢復提交。
# Reverts the revert commit, re-enabling the original changes
git revert <revert-commit-hash>
這會帶回所有原始功能更改,允許您合併後續的錯誤修復而不會丟失程式碼。
結論
恢復合併是一項關鍵的恢復技能。記住:
- **指定
-m 1來指定目標主線分支。 ** - **了解恢復是新增變更的新提交,而不是刪除歷史記錄。 **
- **透過恢復恢復提交而不是重新合併來恢復恢復的功能。 **
了解這些機制可確保您可以自信地管理版本回溯。

