Git
English ▾ 主題 ▾ 最新版本 ▾ git-mergetool 最後更新於 2.45.0

名稱

git-mergetool - 執行合併衝突解決工具以解決合併衝突

概要

git mergetool [--tool=<tool>] [-y | --[no-]prompt] [<file>…​]

說明

使用 git mergetool 執行數個合併工具之一來解決合併衝突。它通常在執行 *git merge* 後執行。

如果給定一個或多個 <file> 參數,將會執行合併工具程式來解決每個檔案中的差異(跳過沒有衝突的檔案)。指定一個目錄將包含該路徑中所有未解決的檔案。如果未指定 <file> 名稱,則 *git mergetool* 將在每個有合併衝突的檔案上執行合併工具程式。

選項

-t <tool>
--tool=<tool>

使用 <tool> 指定的合併解決程式。有效值包括 emerge、gvimdiff、kdiff3、meld、vimdiff 和 tortoisemerge。執行 git mergetool --tool-help 以取得有效 <tool> 設定的清單。

如果未指定合併解決程式,則 *git mergetool* 將使用組態變數 merge.tool。如果未設定組態變數 merge.tool,則 *git mergetool* 將選擇合適的預設值。

您可以透過設定組態變數 mergetool.<tool>.path,明確提供工具的完整路徑。例如,您可以透過設定 mergetool.kdiff3.path 來配置 kdiff3 的絕對路徑。否則,*git mergetool* 假設該工具在 PATH 中可用。

除了執行已知的合併工具程式之一外,還可以透過在組態變數 mergetool.<tool>.cmd 中指定要調用的命令列,來自訂 *git mergetool* 以執行替代程式。

當使用此工具(透過 -t--tool 選項或 merge.tool 組態變數)調用 *git mergetool* 時,設定的命令列將被調用,其中 $BASE 設定為包含合併的常見基礎的臨時檔案名稱(如果有的話);$LOCAL 設定為包含目前分支上檔案內容的臨時檔案名稱;$REMOTE 設定為包含要合併的檔案內容的臨時檔案名稱,以及 $MERGED 設定為合併工具應將合併解決結果寫入的檔案名稱。

如果自訂合併工具正確地透過其結束代碼指示合併解決的成功,則可以將組態變數 mergetool.<tool>.trustExitCode 設定為 true。否則,*git mergetool* 將提示使用者在自訂工具結束後指示解決方案是否成功。

--tool-help

列印可與 --tool 搭配使用的合併工具清單。

-y
--no-prompt

在每次調用合併解決程式之前,不要提示。如果使用 --tool 選項或 merge.tool 組態變數明確指定合併解決程式,則此為預設值。

--prompt

在每次調用合併解決程式之前提示,讓使用者有機會跳過路徑。

-g
--gui

當使用 -g--gui 選項調用 *git-mergetool* 時,預設合併工具將從已設定的 merge.guitool 變數讀取,而不是 merge.tool。如果未設定 merge.guitool,我們會回復到 merge.tool 下配置的工具。這可以使用組態變數 mergetool.guiDefault 自動選取。

--no-gui

這會覆寫先前的 -g--gui 設定或 mergetool.guiDefault 組態,並從已設定的 merge.tool 變數讀取預設合併工具。

-O<orderfile>

依照 <orderfile> 中指定的順序處理檔案,該檔案每行有一個 shell glob 模式。這會覆寫 diff.orderFile 組態變數(請參閱 git-config[1])。若要取消 diff.orderFile,請使用 -O/dev/null

組態

此節中此行以下的所有內容都是從 git-config[1] 文件中選擇性包含的。內容與在那裡找到的相同

mergetool.<tool>.path

覆寫給定工具的路徑。如果您的工具不在 PATH 中,這會很有用。

mergetool.<tool>.cmd

指定調用指定合併工具的命令。指定的命令會在 shell 中評估,其中以下變數可用:*BASE* 是包含要合併的檔案的常見基礎的臨時檔案名稱(如果有的話);*LOCAL* 是包含目前分支上檔案內容的臨時檔案名稱;*REMOTE* 是包含要合併的分支中的檔案內容的臨時檔案名稱;*MERGED* 包含合併工具應將成功合併的結果寫入的檔案名稱。

mergetool.<tool>.hideResolved

允許使用者覆寫特定工具的整體 mergetool.hideResolved 值。請參閱 mergetool.hideResolved 以取得完整說明。

mergetool.<tool>.trustExitCode

對於自訂合併命令,指定是否可以使用合併命令的結束代碼來判斷合併是否成功。如果未將此設定為 true,則會檢查合併目標檔案時間戳記,如果檔案已更新,則會假定合併已成功;否則,會提示使用者指示合併是否成功。

mergetool.meld.hasOutput

舊版 meld 不支援 --output 選項。Git 會嘗試透過檢查 meld --help 的輸出,偵測 meld 是否支援 --output。配置 mergetool.meld.hasOutput 將使 Git 跳過這些檢查,並改為使用已配置的值。將 mergetool.meld.hasOutput 設定為 true 會告知 Git 無條件使用 --output 選項,而 false 則會避免使用 --output

mergetool.meld.useAutoMerge

當給定 --auto-merge 時,meld 將自動合併所有無衝突的部分,反白顯示衝突的部分,並等待使用者決定。將 mergetool.meld.useAutoMerge 設定為 true 會告知 Git 無條件地將 --auto-merge 選項與 meld 搭配使用。將此值設定為 auto 會使 git 偵測是否支援 --auto-merge,並且只在可用時使用 --auto-merge。值 false 會完全避免使用 --auto-merge,並且是預設值。

mergetool.<vimdiff 變體>.layout

設定 vimdiff 的 <變體> 的分割視窗佈局,其中 <變體> 可以是 vimdiffnvimdiffgvimdiff。當使用 --tool=<變體> 執行 git mergetool 時(或者當 merge.tool 設定為 <變體> 時不使用 --tool),Git 會參考 mergetool.<變體>.layout 來決定工具的佈局。如果沒有變體特定的設定,則會使用 vimdiff 的設定作為回退。如果連 vimdiff 的設定也沒有,則會使用預設的四視窗佈局。若要設定佈局,請參閱「後端特定提示」章節。

mergetool.hideResolved

在合併期間,Git 會自動解決盡可能多的衝突,並寫入包含衝突標記的 *MERGED* 檔案,標記出任何無法解決的衝突;*LOCAL* 和 *REMOTE* 通常代表 Git 衝突解決之前的檔案版本。這個旗標會覆寫 *LOCAL* 和 *REMOTE*,以便只將未解決的衝突呈現給合併工具。可以透過 mergetool.<工具>.hideResolved 設定變數針對每個工具進行設定。預設值為 false

mergetool.keepBackup

執行合併後,包含衝突標記的原始檔案可以儲存為副檔名為 .orig 的檔案。如果這個變數設定為 false,則不會保留此檔案。預設值為 true(即保留備份檔案)。

mergetool.keepTemporaries

當呼叫自訂合併工具時,Git 會使用一組暫存檔案傳遞給工具。如果工具傳回錯誤且此變數設定為 true,則會保留這些暫存檔案;否則,它們會在工具結束後被移除。預設值為 false

mergetool.writeToTemp

預設情況下,Git 會將衝突檔案的暫存 *BASE*、*LOCAL* 和 *REMOTE* 版本寫入工作目錄。當設定為 true 時,Git 會嘗試使用暫存目錄來儲存這些檔案。預設值為 false

mergetool.prompt

在每次呼叫合併解決程式之前進行提示。

mergetool.guiDefault

設定為 true 以預設使用 merge.guitool (相當於指定 --gui 參數),或設定為 auto 以根據 DISPLAY 環境變數值是否存在來選擇 merge.guitoolmerge.tool。預設值為 false,其中必須明確提供 --gui 參數才能使用 merge.guitool

暫存檔案

git mergetool 在解決合併時會建立 *.orig 備份檔案。一旦檔案已合併並且其 git mergetool 工作階段已完成,即可安全移除這些檔案。

mergetool.keepBackup 設定變數設定為 false 會導致 git mergetool 在檔案成功合併時自動移除備份檔案。

後端特定提示

vimdiff

說明

當在 git mergetool 中指定 --tool=vimdiff 時,Git 會開啟 Vim,並使用以下方式分佈的四個視窗佈局

------------------------------------------
|             |           |              |
|   LOCAL     |   BASE    |   REMOTE     |
|             |           |              |
------------------------------------------
|                                        |
|                MERGED                  |
|                                        |
------------------------------------------

LOCALBASEREMOTE 是唯讀緩衝區,顯示衝突檔案在特定提交中的內容(分別是「您正在合併到的提交」、「共同祖先提交」和「您正在從中合併的提交」)。

MERGED 是一個可寫入的緩衝區,您必須在其中解決衝突(使用其他唯讀緩衝區作為參考)。完成後,像往常一樣儲存並退出 Vim(:wq),或者如果想要中止,請使用 :cq 退出。

佈局設定

您可以透過設定組態變數 mergetool.vimdiff.layout 來變更 Vim 使用的視窗佈局,該變數接受一個字串,其中以下分隔符號具有特殊含義

  • + 用於「開啟新的標籤頁」

  • , 用於「開啟新的垂直分割」

  • / 用於「開啟新的水平分割」

  • @ 用於指示在解決衝突後包含最終版本的檔案。如果不存在,則預設會使用 MERGED

運算子的優先順序如下(您可以使用括號來變更它)

`@` > `+` > `/` > `,`

讓我們看一些範例來了解它是如何運作的

  • layout = "(LOCAL,BASE,REMOTE)/MERGED"

    這與我們已經看到的預設佈局完全相同。

    請注意,/ 的優先順序高於 ,,因此在此情況下不需要括號。下一個佈局定義是等效的

    layout = "LOCAL,BASE,REMOTE / MERGED"
  • layout = "LOCAL,MERGED,REMOTE"

    如果出於某種原因,我們對 BASE 緩衝區不感興趣。

    ------------------------------------------
    |             |           |              |
    |             |           |              |
    |   LOCAL     |   MERGED  |   REMOTE     |
    |             |           |              |
    |             |           |              |
    ------------------------------------------
  • layout = "MERGED"

    僅會顯示 MERGED 緩衝區。但是請注意,所有其他緩衝區仍然會載入 Vim 中,您可以使用「buffers」命令來存取它們。

    ------------------------------------------
    |                                        |
    |                                        |
    |                 MERGED                 |
    |                                        |
    |                                        |
    ------------------------------------------
  • layout = "@LOCAL,REMOTE"

    當佈局中不存在 MERGED 時,您必須使用星號「標記」其中一個緩衝區。這將成為您在解決衝突後需要編輯和儲存的緩衝區。

    ------------------------------------------
    |                   |                    |
    |                   |                    |
    |                   |                    |
    |     LOCAL         |    REMOTE          |
    |                   |                    |
    |                   |                    |
    |                   |                    |
    ------------------------------------------
  • layout = "LOCAL,BASE,REMOTE / MERGED + BASE,LOCAL + BASE,REMOTE"

    將會開啟三個標籤頁:第一個是預設佈局的副本,而其他兩個標籤頁僅顯示(BASELOCAL)以及(BASEREMOTE)之間的差異。

    ------------------------------------------
    | <TAB #1> |  TAB #2  |  TAB #3  |       |
    ------------------------------------------
    |             |           |              |
    |   LOCAL     |   BASE    |   REMOTE     |
    |             |           |              |
    ------------------------------------------
    |                                        |
    |                MERGED                  |
    |                                        |
    ------------------------------------------
    ------------------------------------------
    |  TAB #1  | <TAB #2> |  TAB #3  |       |
    ------------------------------------------
    |                   |                    |
    |                   |                    |
    |                   |                    |
    |     BASE          |    LOCAL           |
    |                   |                    |
    |                   |                    |
    |                   |                    |
    ------------------------------------------
    ------------------------------------------
    |  TAB #1  |  TAB #2  | <TAB #3> |       |
    ------------------------------------------
    |                   |                    |
    |                   |                    |
    |                   |                    |
    |     BASE          |    REMOTE          |
    |                   |                    |
    |                   |                    |
    |                   |                    |
    ------------------------------------------
  • layout = "LOCAL,BASE,REMOTE / MERGED + BASE,LOCAL + BASE,REMOTE + (LOCAL/BASE/REMOTE),MERGED"

    與上一個範例相同,但新增了第四個標籤頁,其中包含與第一個標籤頁相同的資訊,但具有不同的佈局。

    ---------------------------------------------
    |  TAB #1  |  TAB #2  |  TAB #3  | <TAB #4> |
    ---------------------------------------------
    |       LOCAL         |                     |
    |---------------------|                     |
    |       BASE          |        MERGED       |
    |---------------------|                     |
    |       REMOTE        |                     |
    ---------------------------------------------

    請注意,在第三個標籤頁定義中,我們需要使用括號來使 , 的優先順序高於 /

變體

除了 --tool=vimdiff 之外,您也可以使用以下其他變體之一

  • --tool=gvimdiff,開啟 gVim 而不是 Vim。

  • --tool=nvimdiff,開啟 Neovim 而不是 Vim。

當使用這些變體時,為了指定自訂佈局,您必須設定組態變數 mergetool.gvimdiff.layoutmergetool.nvimdiff.layout,而不是 mergetool.vimdiff.layout (雖然如果未設定變體特定的組態變數,則會使用後者作為回退)。

此外,為了與先前版本的 Git 相容,您也可以在 vimdiff 或任何變體後附加 123(例如:vimdiff3nvimdiff1 等…​)以使用預先定義的佈局。換句話說,使用 --tool=[g,n,]vimdiffx 與使用 --tool=[g,n,]vimdiff 並將組態變數 mergetool.[g,n,]vimdiff.layout 設定為…​

  • x=1"@LOCAL, REMOTE"

  • x=2"LOCAL, MERGED, REMOTE"

  • x=3"MERGED"

範例:使用 --tool=gvimdiff2 將會開啟 gvim,其中包含三個欄位(LOCAL、MERGED 和 REMOTE)。

GIT

屬於 git[1] 套件的一部分

scroll-to-top