簡體中文 ▾ 主題 ▾ 最新版本 ▾ 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 <pathspec>

重置 rerere 為 <pathspec> 中當前衝突記錄的衝突解決。

diff

顯示當前解決狀態的 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 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] 套件的一部分