設定與組態
取得與建立專案
基本快照
分支與合併
分享與更新專案
檢查與比較
修補
除錯
電子郵件
外部系統
伺服器管理
指南
- gitattributes
- 命令列介面規範
- Git 日常使用
- 常見問題 (FAQ)
- 詞彙表
- 掛鉤 (Hooks)
- gitignore
- gitmodules
- 修訂版本 (Revisions)
- 子模組
- 教學
- 工作流程
- 所有指南...
管理
底層命令 (Plumbing Commands)
- 2.55.0 無變更
-
2.54.0
2026-04-20
- 2.39.1 → 2.53.0 無變更
-
2.39.0
2022-12-12
- 2.23.1 → 2.38.5 無變更
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 無變更
-
2.22.0
2019-06-07
- 2.20.1 → 2.21.4 無變更
-
2.20.0
2018-12-09
- 2.16.6 → 2.19.6 無變更
-
2.15.4
2019-12-06
- 2.5.6 → 2.14.6 無變更
-
2.4.12
2017-05-05
- 2.1.4 → 2.3.10 無變更
-
2.0.5
2014-12-17
描述
在採用相對長期的專題分支(topic branches)工作流時,開發人員有時需要反覆解決相同的衝突,直到專題分支完成(即合併到「release」分支,或發送到上游並被接受)。
此指令透過記錄初始手動合併時的衝突自動合併結果與對應的手動解決結果,並將先前記錄的手動解決方案應用於對應的自動合併結果,來協助開發人員完成此過程。
|
注意
|
您需要設定配置變數 rerere.enabled 才能啟用此指令。 |
指令
通常,git rerere 在執行時無需參數或使用者介入。然而,它提供多個指令允許使用者與其工作狀態互動。
- clear
-
如果需要中止合併解決,則重設 rerere 所使用的元數據。呼叫 git am [--skip|--abort] 或 git rebase [--skip|--abort] 會自動呼叫此指令。
- forget <pathspec>
-
重設 rerere 為符合 <pathspec> 路徑中目前衝突所記錄的衝突解決方案。
- diff
-
顯示目前解決狀態的差異。這對於在使用者解決衝突時追蹤變更非常有用。額外的參數會直接傳遞給安裝在 PATH 中的系統 diff 指令。
- status
-
列印 rerere 將會記錄其合併解決方案的衝突路徑。
- remaining
-
列印那些尚未被 rerere 自動解決的衝突路徑。這包括 rerere 無法追蹤其解決方案的路徑,例如衝突的子模組(submodules)。
- gc
-
清理很久以前發生的衝突合併記錄。預設情況下,未解決的衝突超過 15 天,且已解決的衝突超過 60 天會被清理。這些預設值分別透過
gc.rerereUnresolved和gc.rerereResolved配置變數進行控制。
討論
當您的專題分支修改了自從該專題分支分叉後,主分支(master 或上游)所觸及的重疊區域時,即使在您的專題分支準備推送到上游之前,您可能也會想用最新的 master 分支進行測試。
o---*---o topic
/
o---o---o---*---o---o master
對於此類測試,您需要以某種方式合併 master 和專題分支。其中一種方法是將 master 拉取(pull)到專題分支中。
$ git switch topic
$ git merge master
o---*---o---+ topic
/ /
o---o---o---*---o---o master
標記為 * 的提交觸及了同一個檔案中的相同區域;您需要在建立標記為 + 的提交時解決衝突。然後您可以測試結果,以確保您的進行中工作仍然能與最新 master 分支中的內容相容。
在此測試合併之後,有兩種方法可以繼續您的專題分支工作。最簡單的方法是在測試合併提交 + 之上繼續開發,當您的專題分支工作最終準備就緒時,將專題分支拉取到 master,和/或要求上游從您這裡拉取。然而,到那時,master 或上游可能已經在測試合併 + 之後又有了進展,這種情況下最終的提交圖表看起來會像這樣。
$ git switch topic
$ git merge master
$ ... work on both topic and master branches
$ git switch master
$ git merge topic
o---*---o---+---o---o topic
/ / \
o---o---o---*---o---o---o---o---+ master
然而,當您的專題分支是長期的,您的專題分支最終會有許多這類「從 master 合併」的提交,這會不必要地使開發歷史變得混亂。Linux 核心郵件列表的讀者可能記得,當一位子系統維護者要求從充滿「無用合併」的分支進行拉取時,Linus 曾抱怨過這種過於頻繁的測試合併。
作為替代方案,為了保持專題分支不受測試合併的影響,您可以刪除測試合併,並在測試合併之前的頂端(tip)基礎上繼續開發。
$ git switch topic
$ git merge master
$ git reset --hard HEAD^ ;# rewind the test merge
$ ... work on both topic and master branches
$ git switch master
$ git merge topic
o---*---o-------o---o topic
/ \
o---o---o---*---o---o---o---o---+ master
當您的專題分支最終準備好並合併到 master 分支時,這只會留下一個合併提交。此合併需要您解決由標記為 * 的提交所引入的衝突。然而,此衝突通常與您在建立被刪除的測試合併時所解決的衝突相同。git rerere 協助您使用先前手動解決的資訊來解決這個最終的衝突合併。
在衝突的自動合併後立即執行 git rerere 指令,會記錄衝突的工作樹檔案,其中包含常見的衝突標記 <<<<<<<、======= 和 >>>>>>>。稍後,在您解決衝突完成後,再次執行 git rerere 將會記錄這些檔案的已解決狀態。假設您在建立將 master 合併到專題分支的測試合併時執行了此操作。
下一次,在看到相同的衝突自動合併後,執行 git rerere 將會在先前的衝突自動合併、先前的自動解決方案和目前的衝突自動合併之間進行三向合併(three-way merge)。如果此三向合併順利解決,結果會寫入您的工作樹檔案,因此您無需手動解決它。請注意,git rerere 不會更動索引檔(index file),因此您仍然需要使用 git diff(或 git diff -c)進行最終的健全性檢查,並在滿意時執行 git add。
作為一種便利措施,git merge 在自動合併失敗時會自動呼叫 git rerere,若為新的衝突,git rerere 會記錄手動解決方案,若非新衝突,則會重用先前的解決方案。git commit 在提交合併結果時也會呼叫 git rerere。這意味著您自己不需要執行任何特別的操作(除了啟用 rerere.enabled 配置變數之外)。
在我們的範例中,當您進行測試合併時,會記錄手動解決方案;只要記錄的解決方案仍然適用,當您稍後使用更新後的 master 和專題分支進行實際合併時,它將會被重用。
git rerere 記錄的資訊在執行 git rebase 時也會被使用。在刪除測試合併並繼續在專題分支上開發之後
o---*---o-------o---o topic
/
o---o---o---*---o---o---o---o master
$ git rebase master topic
o---*---o-------o---o topic
/
o---o---o---*---o---o---o---o master
您可以執行 git rebase master topic,在您的專題分支準備好發送到上游之前進行同步更新。這會導致退回到三向合併,並且會與您之前解決的測試合併產生相同的衝突。git rebase 將會執行 git rerere 來協助您解決此衝突。
[注意] git rerere 依賴檔案中的衝突標記來偵測衝突。如果檔案中已經包含了與衝突標記行看起來相同的行,git rerere 可能會無法記錄衝突解決方案。為了解決此問題,可以使用 gitattributes[5] 中的 conflict-marker-size 設定。
GIT
git[1] 套件的一部分