Git
English ▾ 主題 ▾ 最新版本 ▾ git-rerere 最後更新於 2.39.0

名稱

git-rerere - 重複使用已記錄的衝突合併解決方案

概要

git rerere [clear | forget <pathspec>…​ | diff | status | remaining | gc]

描述

在使用相對長時間存在的主題分支的工作流程中,開發人員有時需要重複解決相同的衝突,直到主題分支完成(合併到「發布」分支,或發送並被上游接受)。

此命令通過記錄初始手動合併時衝突的自動合併結果和相應的手動解決結果,並將先前記錄的手動解決方案應用於其對應的自動合併結果,來協助開發人員完成此過程。

注意
您需要設定組態變數 rerere.enabled 才能啟用此命令。

命令

通常,git rerere 在沒有參數或使用者干預的情況下執行。但是,它具有多個命令,允許它與其工作狀態交互。

clear

如果要中止合併解決方案,請重設 rerere 使用的中繼資料。呼叫 git am [--skip|--abort]git rebase [--skip|--abort] 將自動叫用此命令。

forget <路徑規格>

重設 rerere 為 <路徑規格> 中目前的衝突記錄的衝突解決方案。

diff

顯示目前解決方案狀態的差異。它對於追蹤使用者在解決衝突時所做的變更很有用。其他參數會直接傳遞到 PATH 中安裝的系統 diff 命令。

status

列印具有衝突的路徑,rerere 將記錄其合併解決方案。

remaining

列印未被 rerere 自動解決的衝突路徑。這包括無法由 rerere 追蹤其解決方案的路徑,例如衝突的子模組。

gc

修剪很久以前發生的衝突合併記錄。預設情況下,會修剪 15 天以上的未解決衝突和 60 天以上的已解決衝突。這些預設值分別由 gc.rerereUnresolvedgc.rerereResolved 組態變數控制。

討論

當您的主題分支修改了您的主分支(或上游)自您的主題分支從其分支以來接觸的重疊區域時,您可能希望使用最新的主分支對其進行測試,即使在您的主題分支準備好推送到上游之前。

              o---*---o topic
             /
    o---o---o---*---o---o master

對於這樣的測試,您需要以某種方式合併主分支和主題分支。一種方法是將主分支拉取到主題分支中。

	$ git switch topic
	$ git merge master

              o---*---o---+ topic
             /           /
    o---o---o---*---o---o 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

然而,當您的主題分支長期存在時,您的主題分支最終會有很多這樣的「從主分支合併」提交,這會不必要地混亂開發歷史。Linux 核心郵件列表的讀者可能還記得,Linus 抱怨過當一個子系統維護者要求從一個充滿「無用合併」的分支中拉取時,這種過於頻繁的測試合併。

或者,為了讓主題分支沒有測試合併,您可以清除測試合併,並在測試合併之前繼續建構在提示之上

	$ 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

當您的主題分支最終準備好並合併到主分支時,這只會留下一個合併提交。此合併將要求您解決由標記為 * 的提交引入的衝突。但是,此衝突通常是您在建立您清除的測試合併時解決的相同衝突。git rerere 可協助您使用先前的手動解決方案中的資訊解決此最終的衝突合併。

在衝突的自動合併後立即執行 git rerere 命令會記錄衝突的工作樹檔案,其中包含常見的衝突標記 <<<<<<<=======>>>>>>>。稍後,在您完成解決衝突之後,再次執行 git rerere 將記錄這些檔案的已解決狀態。假設您在將主分支的測試合併建立到主題分支時執行此操作。

下次,在看到相同的衝突自動合併後,執行 git rerere 將在先前的衝突自動合併、先前的解決方案和目前的衝突自動合併之間執行三方合併。如果此三方合併可以順利解決,則結果會寫入您的工作樹檔案,因此您不必手動解決。請注意,git rerere 不會變更索引檔案,因此當您感到滿意時,您仍然需要使用 git diff(或 git diff -c)和 git add 進行最終的健全性檢查。

作為一種便利措施,git merge 會在自動合併失敗退出時自動叫用 git rerere,當它是新的衝突時,git rerere 會記錄手動解決方案,當它不是時,則重複使用先前的解決方案。在提交合併結果時,git commit 也會叫用 git rerere。這表示您不必自己做任何特殊的事情(除了啟用 rerere.enabled 組態變數之外)。

在我們的範例中,當您進行測試合併時,會記錄手動解決方案,並且只要記錄的解決方案仍然適用,當您稍後使用更新的主分支和主題分支進行實際合併時,就會重複使用。

當執行 git rebase 時,也會使用 git rerere 記錄的資訊。在清除測試合併並繼續在主題分支上進行開發之後

              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] 套件的一部分

scroll-to-top