簡體中文 ▾ 主題 ▾ 最新版本 ▾ git-diff-pairs 最後更新於 2.50.0

名稱

git-diff-pairs - 比較提供的二進位制物件對的內容和模式

概要

git diff-pairs -z [<diff-options>]

描述

顯示透過標準輸入提供的檔案對的更改。此命令的輸入必須是NUL終止的原始輸出格式,如git diff-tree -z -r --raw等命令生成的那樣。預設情況下,當標準輸入關閉時,計算並以補丁格式顯示輸出的差異。

可以在原始輸入行之間向標準輸入寫入單個NUL位元組,以計算截至該點的檔案對差異,而不是等待標準輸入關閉。輸出中也會寫入一個NUL位元組,以分隔這些批次的差異。

使用此命令可以將傳統的差異管道分解為不同的階段,其中diff-pairs充當輸出階段。其他命令,例如diff-tree,可以作為前端來計算用作輸入的原始差異格式。

除了透過git diff-tree -p -M一步計算差異外,diff-tree可以計算檔案對和重新命名資訊,而無需二進位制物件差異。此輸出可以饋送給diff-pairs以生成底層的二進位制物件差異,如下例所示

git diff-tree -z -r -M $a $b |
git diff-pairs -z

提前計算包含重新命名資訊的樹差異,允許diff-pairs的補丁輸出在多次呼叫過程中逐步計算。

diff-pairs目前不支援路徑規範。路徑規範限制應由生成原始差異作為輸入的上游命令執行。

目前不支援樹物件作為輸入,它們將被拒絕。

diff-pairs輸入中不支援縮寫物件ID。輸出的物件ID可以使用--abbrev選項進行縮寫。

選項

-p
-u
--patch

生成補丁(參見 使用 -p 生成補丁文字)。

-s
--no-patch

抑制所有差異機制的輸出。對於預設顯示補丁的命令(如git show)非常有用,可以抑制其輸出,或者在別名中取消命令列上早期--patch--stat等選項的效果。

-U<n>
--unified=<n>

生成包含 <n> 行上下文(而不是通常的三行)的 diff。隱含 --patch

--output=<file>

輸出到特定檔案而不是標準輸出。

--output-indicator-new=<char>
--output-indicator-old=<char>
--output-indicator-context=<char>

指定用於指示生成補丁中新行、舊行或上下文行的字元。通常它們分別是 +- 和 ' '。

--raw

以原始格式生成 diff。這是預設設定。

--patch-with-raw

-p --raw 的同義詞。

--indent-heuristic

啟用啟發式演算法,該演算法會移動差異塊邊界,使補丁更易於閱讀。這是預設設定。

--no-indent-heuristic

停用縮排啟發式演算法。

--minimal

花費額外時間以確保生成最小的差異。

--patience

使用“patience diff”演算法生成差異。

--histogram

使用“histogram diff”演算法生成差異。

--anchored=<text>

使用“anchored diff”演算法生成差異。

此選項可以多次指定。

如果一行在源和目標中都存在,只存在一次,並且以 <text> 開頭,則此演算法會嘗試阻止其在輸出中顯示為刪除或新增。它內部使用“patience diff”演算法。

--diff-algorithm=(patience|minimal|histogram|myers)

選擇一種差異演算法。變體如下:

預設
myers

基本的貪婪差異演算法。目前,這是預設值。

最小

花費額外時間以確保生成最小的差異。

耐心

生成補丁時使用“patience diff”演算法。

直方圖

此演算法擴充套件了 patience 演算法以“支援低出現率的常見元素”。

例如,如果您將 diff.algorithm 變數配置為非預設值,但希望使用預設值,則必須使用 --diff-algorithm=default 選項。

--stat[=<寬度>[,<名稱寬度>[,<計數>]]]

生成差異統計。預設情況下,檔名部分將使用所需的最大空間,其餘空間用於圖表部分。最大寬度預設為終端寬度,如果未連線到終端則為80列,可以透過<width>覆蓋。檔名部分的寬度可以透過在逗號後提供另一個寬度<name-width>來限制,或者透過設定diff.statNameWidth=<name-width>來限制。圖表部分的寬度可以透過使用--stat-graph-width=<graph-width>或設定diff.statGraphWidth=<graph-width>來限制。使用--stat--stat-graph-width會影響所有生成統計圖的命令,而設定diff.statNameWidthdiff.statGraphWidth則不會影響git format-patch。透過給出第三個引數<count>,可以將輸出限制為前<count>行,如果還有更多行,則後面跟著...

這些引數也可以透過--stat-width=<width>--stat-name-width=<name-width>--stat-count=<count>單獨設定。

--compact-summary

輸出擴充套件頭資訊的精簡摘要,例如檔案建立或刪除(“new”或“gone”,如果是符號連結則可選+l)以及模式更改(分別用+x-x表示新增或刪除可執行位)在差異統計中。資訊置於檔名部分和圖表部分之間。隱含--stat

--numstat

--stat類似,但以十進位制表示法顯示新增和刪除的行數,以及不帶縮寫的路徑名,使其更便於機器讀取。對於二進位制檔案,輸出兩個-而不是0 0

--shortstat

僅輸出 --stat 格式的最後一行,其中包含修改檔案的總數,以及新增和刪除的行數。

-X [<引數>,...]
--dirstat[=<引數>,...]

輸出每個子目錄的相對更改量分佈。--dirstat的行為可以透過傳遞逗號分隔的引數列表進行自定義。預設值由diff.dirstat配置變數控制(參見git-config[1])。以下引數可用

更改

透過計算從源中刪除或新增到目標中的行數來計算目錄統計數字。這會忽略檔案中純程式碼移動的數量。換句話說,檔案中行的重新排列不會像其他更改那樣被大量計算。這是未給出引數時的預設行為。

透過執行常規的基於行的差異分析,並彙總刪除/新增的行數來計算目錄統計數字。(對於二進位制檔案,改為計算64位元組的塊,因為二進位制檔案沒有自然的行概念)。這是一種比changes行為更昂貴的--dirstat行為,但它確實會像其他更改一樣計算檔案中重新排列的行。結果輸出與您從其他--*stat選項獲得的輸出一致。

檔案

透過計算更改的檔案數量來計算目錄統計數字。每個更改的檔案在目錄統計分析中同等計數。這是計算成本最低的--dirstat行為,因為它根本不需要檢視檔案內容。

累計

也計算子目錄中對父目錄的更改。請注意,當使用cumulative時,報告的百分比總和可能會超過100%。預設(非累計)行為可以使用noncumulative引數指定。

<限制>

一個整數引數,指定一個截止百分比(預設為 3%)。對更改貢獻低於此百分比的目錄不會顯示在輸出中。

示例:以下將計算更改的檔案,同時忽略更改檔案總數少於10%的目錄,並在父目錄中累積子目錄計數:--dirstat=files,10,cumulative

--cumulative

--dirstat=cumulative 的同義詞。

--dirstat-by-file[=<引數>,...]

--dirstat=files,<param>,... 的同義詞。

--summary

輸出擴充套件頭資訊的精簡摘要,例如建立、重新命名和模式更改。

--patch-with-stat

-p --stat 的同義詞。

-z

當給出--raw--numstat--name-only--name-status時,不混淆路徑名,並使用NUL作為輸出欄位終止符。

如果沒有此選項,包含“不尋常”字元的路徑名將按照配置變數 core.quotePath 的解釋進行引用(參見 git-config[1])。

--name-only

僅顯示後像樹中每個已更改檔案的名稱。檔名通常以 UTF-8 編碼。有關更多資訊,請參閱 git-log[1] 手冊頁中關於編碼的討論。

--name-status

僅顯示每個更改檔案的名稱和狀態。關於狀態字母的含義,請參見--diff-filter選項的描述。與--name-only一樣,檔名通常以UTF-8編碼。

--submodule[=<格式>]

指定如何顯示子模組中的差異。當指定--submodule=short時,使用short格式。此格式僅顯示範圍開頭和結束處的提交名稱。當指定--submodule--submodule=log時,使用log格式。此格式列出範圍內的提交,就像git-submodule[1] summary所做的那樣。當指定--submodule=diff時,使用diff格式。此格式顯示提交範圍內子模組內容更改的內聯差異。預設為diff.submodule,如果未設定配置選項則為short格式。

--color[=<何時>]

顯示彩色差異。--color(即不帶=<when>)與--color=always相同。<when>可以是alwaysneverauto之一。

--no-color

關閉彩色 diff。它與 --color=never 相同。

--color-moved[=<模式>]

移動的程式碼行以不同顏色顯示。如果未給出此選項,*<mode>*預設為no;如果給出不帶模式的選項,則預設為zebra。模式必須是以下之一:

移動的行不進行高亮顯示。

預設

zebra 的同義詞。未來可能會更改為更合理的模式。

普通

在某個位置新增但在另一位置刪除的任何行將使用color.diff.newMoved著色。類似地,在差異中其他地方新增的已刪除行將使用color.diff.oldMoved。此模式會捕獲任何移動的行,但在審查中判斷程式碼塊是否未經置換而移動時,它並不是很有用。

貪婪地檢測至少20個字母數字字元的移動文字塊。檢測到的塊使用color.diff.(old|new)Moved顏色繪製。相鄰塊無法區分。

斑馬

移動文字塊的檢測方式與blocks模式相同。這些塊使用color.diff.(old|new)Moved顏色或color.diff.(old|new)MovedAlternative顏色繪製。兩種顏色之間的變化表示檢測到新的塊。

暗淡斑馬

zebra類似,但會對移動程式碼中不重要的部分進行額外的調暗處理。兩個相鄰塊的邊界行被認為是重要的,其餘部分則不重要。dimmed_zebra是一個已棄用的同義詞。

--no-color-moved

關閉移動檢測。這可以用於覆蓋配置設定。它與 --color-moved=no 相同。

--color-moved-ws=<模式>,...

這配置了在執行 --color-moved 的移動檢測時如何忽略空白。這些模式可以作為逗號分隔的列表給出:

執行移動檢測時不忽略空白。

忽略行尾空格

忽略行尾空格的更改。

忽略空格更改

忽略空格數量的變化。這會忽略行尾的空格,並將所有其他一個或多個空格序列視為等效。

忽略所有空格

比較行時忽略空格。即使一行有空格而另一行沒有,這也忽略了差異。

允許縮排更改

在移動檢測中最初忽略所有空白,然後僅當每行的空白更改相同時,才將移動的程式碼塊分組為一個塊。這與其他模式不相容。

--no-color-moved-ws

執行移動檢測時不忽略空白。這可以用於覆蓋配置設定。它與 --color-moved-ws=no 相同。

--word-diff[=<模式>]

預設情況下,單詞由空白分隔;參見下面的 --word-diff-regex<mode> 預設為 plain,並且必須是以下之一:

彩色

僅使用顏色高亮顯示更改的單詞。隱含 --color

普通

將單詞顯示為[-removed-]{added}。如果分隔符出現在輸入中,不會嘗試轉義,因此輸出可能會有歧義。

porcelain

使用一種特殊的、旨在供指令碼消費的基於行的格式。新增/刪除/未更改的連續部分以常規的統一差異格式列印,行首以+/-/` `字元開始並延伸到行尾。輸入中的換行符由其單獨一行上的波浪號~表示。

再次停用單詞 diff。

請注意,儘管第一個模式的名稱如此,如果啟用,所有模式都使用顏色高亮顯示更改的部分。

--word-diff-regex=<正則表示式>

使用 <regex> 來決定什麼是單詞,而不是將非空白字元的連續序列視為一個單詞。除非已啟用,否則這也隱含 --word-diff

<regex>的每個不重疊匹配都被視為一個單詞。這些匹配之間的任何內容都被視為空格並被忽略(!)以便查詢差異。您可能希望將|[^[:space:]]附加到您的正則表示式中,以確保它匹配所有非空白字元。包含換行符的匹配會在換行符處被靜默截斷(!)

例如,--word-diff-regex=. 會將每個字元視為一個單詞,並相應地逐字元顯示差異。

正則表示式也可以透過差異驅動程式或配置選項設定,參見gitattributes[5]git-config[1]。顯式給出它會覆蓋任何差異驅動程式或配置設定。差異驅動程式會覆蓋配置設定。

--color-words[=<正則表示式>]

相當於 --word-diff=color 加上(如果指定了正則表示式)--word-diff-regex=<regex>

--no-renames

關閉重新命名檢測,即使配置檔案預設開啟。

--[no-]rename-empty

是否使用空 blob 作為重新命名源。

--check

如果更改引入了衝突標記或空白錯誤,則發出警告。空白錯誤由core.whitespace配置控制。預設情況下,行尾空白(包括僅由空白組成的行)以及行初始縮排中緊跟製表符的空格字元被視為空白錯誤。如果發現問題,則以非零狀態退出。與--exit-code不相容。

--ws-error-highlight=<型別>

突出顯示差異的contextoldnew行中的空白錯誤。多個值用逗號分隔,none重置先前的值,default將列表重置為new,而allold,new,context的簡寫。如果未給出此選項,並且未設定配置變數diff.wsErrorHighlight,則僅突出顯示new行中的空白錯誤。空白錯誤將用color.diff.whitespace著色。

--full-index

在生成補丁格式輸出時,不在“index”行上顯示前幾個字元,而是顯示完整的原影像和後圖像 blob 物件名稱。

--binary

除了 --full-index 之外,還輸出一個二進位制 diff,該 diff 可以用 git-apply 應用。隱含 --patch

--abbrev[=<n>]

在差異原始格式輸出和差異樹頭行中,不顯示完整的40位元組十六進位制物件名稱,而是顯示至少<n>個十六進位制數字長的最短字首,該字首唯一引用該物件。在差異補丁輸出格式中,--full-index具有更高的優先順序,即如果指定了--full-index,則無論--abbrev如何,都將顯示完整的二進位制物件名稱。非預設的數字位數可以透過--abbrev=<n>指定。

-B[<n>][/<m>]
--break-rewrites[=[<n>][/<m>]]

將完整的重寫更改分解為刪除和建立對。這有兩個目的:

它影響檔案完全重寫的更改方式,不是作為一系列刪除和插入與少量文字上匹配的上下文行混合在一起,而是作為對所有舊內容的單個刪除,然後是所有新內容的單個插入,數字<m>控制-B選項的這一方面(預設為60%)。-B/70%指定結果中少於30%的原始內容應保留,Git才會將其視為完全重寫(即,否則生成的補丁將是一系列刪除和插入與上下文行混合在一起)。

當與-M一起使用時,完全重寫的檔案也被視為重新命名的源(通常-M僅將消失的檔案視為重新命名的源),數字<n>控制-B選項的這一方面(預設為50%)。-B20%指定,與檔案大小的20%或更多相比,有新增和刪除的更改有資格被視為重新命名到另一個檔案的可能源。

-M[<n>]
--find-renames[=<n>]

檢測重新命名。如果指定了<n>,它將作為相似性索引的閾值(即與檔案大小相比的新增/刪除量)。例如,-M90%表示如果檔案有超過90%未更改,Git應將刪除/新增對視為重新命名。沒有%符號時,數字應讀作小數,小數點在其前面。即,-M5變為0.5,因此與-M50%相同。類似地,-M05-M5%相同。要將檢測限制為精確重新命名,請使用-M100%。預設相似性索引為50%。

-C[<n>]
--find-copies[=<n>]

檢測複製和重新命名。另請參見 --find-copies-harder。如果指定了 <n>,其含義與 -M<n> 相同。

--find-copies-harder

出於效能原因,預設情況下,-C選項僅在複製的原始檔案在同一變更集中被修改時才查詢副本。此標誌使命令檢查未修改的檔案作為複製源的候選。這對於大型專案來說是非常昂貴的操作,因此請謹慎使用。給出多個-C選項具有相同的效果。

-D
--irreversible-delete

省略刪除的原始影像,即只打印頭資訊,而不列印原始影像與/dev/null之間的差異。生成的補丁不適用於patchgit apply;這僅適用於希望專注於審查更改後文本的人。此外,輸出顯然缺乏足夠的資訊來反向應用此類補丁,即使是手動操作也一樣,因此得名此選項。

-B 一起使用時,也會省略刪除/建立對的刪除部分中的原始影像。

-l<數量>

-M-C選項包含一些初步步驟,可以廉價地檢測重新命名/複製的子集,然後是詳盡的後備部分,將所有剩餘的未配對目標與所有相關源進行比較。(對於重新命名,只有剩餘的未配對源是相關的;對於複製,所有原始源都是相關的。)對於N個源和目標,此詳盡檢查的時間複雜度為O(N^2)。如果涉及的源/目標檔案數量超過指定數量,此選項會阻止重新命名/複製檢測的詳盡部分執行。預設為diff.renameLimit。請注意,0值被視為無限制。

--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]

僅選擇以下檔案:新增的(A)、複製的(C)、刪除的(D)、修改的(M)、重新命名的(R)、型別(即常規檔案、符號連結、子模組等)已更改的(T)、未合併的(U)、未知的(X)或配對已損壞的(B)。可以使用任何過濾字元組合(包括無)。當組合中新增*(全部或無)時,如果比較中有任何檔案匹配其他條件,則選擇所有路徑;如果沒有檔案匹配其他條件,則不選擇任何內容。

此外,這些大寫字母可以小寫以進行排除。例如,--diff-filter=ad 會排除已新增和已刪除的路徑。

請注意,並非所有 diff 都能包含所有型別。例如,如果停用對這些型別的檢測,則不會出現已複製和已重新命名條目。

-S<字串>

查詢更改檔案中指定 <string> 出現次數(即新增/刪除)的差異。供指令碼編寫者使用。

當您正在尋找精確的程式碼塊(例如結構體),並想了解該程式碼塊自誕生以來的歷史時,這很有用:迭代使用此功能,將原始影像中有趣的程式碼塊重新輸入到-S中,然後繼續直到獲得該程式碼塊的第一個版本。

二進位制檔案也會被搜尋。

-G<正則表示式>

查詢其補丁文字包含與 <regex> 匹配的新增/刪除行的差異。

為了說明-S<regex> --pickaxe-regex-G<regex>之間的區別,請考慮一個在同一檔案中具有以下差異的提交

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

雖然git log -G"frotz\(nitfol"會顯示此提交,但git log -S"frotz\(nitfol" --pickaxe-regex不會(因為該字串的出現次數沒有改變)。

除非提供了 --text,否則沒有 textconv 過濾器的二進位制檔案的補丁將被忽略。

有關更多資訊,請參見 gitdiffcore[7] 中的 *pickaxe* 條目。

--find-object=<物件ID>

查詢更改指定物件出現次數的差異。類似於 -S,只是引數不同,它不搜尋特定字串,而是搜尋特定物件 ID。

該物件可以是 blob 或子模組提交。它隱含了 git-log 中的 -t 選項,以也查詢樹。

--pickaxe-all

-S-G 找到更改時,顯示該變更集中所有更改,而不僅僅是包含 <string> 更改的檔案。

--pickaxe-regex

將提供給 -S<string> 視為擴充套件的 POSIX 正則表示式進行匹配。

-O<順序檔案>

控制檔案在輸出中出現的順序。這會覆蓋diff.orderFile配置變數(參見git-config[1])。要取消diff.orderFile,請使用-O/dev/null

輸出順序由<orderfile>中全域性模式的順序決定。所有路徑名與第一個模式匹配的檔案首先輸出,所有路徑名與第二個模式匹配(但不與第一個模式匹配)的檔案其次輸出,依此類推。所有路徑名不匹配任何模式的檔案最後輸出,就像檔案末尾有一個隱式匹配所有模式一樣。如果多個路徑名具有相同的等級(它們匹配相同的模式但沒有更早的模式),則它們相對於彼此的輸出順序是正常順序。

<orderfile> 解析如下:

  • 空行被忽略,因此它們可以用作分隔符以提高可讀性。

  • 以井號("#")開頭的行被忽略,因此它們可以用作註釋。如果模式以井號開頭,請在模式開頭新增反斜槓("\")。

  • 其他每行包含一個模式。

模式具有與fnmatch(3)使用的模式相同的語法和語義,但沒有FNM_PATHNAME標誌,除了路徑名如果刪除任意數量的最終路徑名元件後與模式匹配,也匹配該模式。例如,模式“foo*bar”匹配“fooasdfbar”和“foo/bar/baz/asdf”,但不匹配“foobarx”。

--skip-to=<檔案>
--rotate-to=<檔案>

從輸出中丟棄命名為<file>之前的檔案(即*跳過至*),或將它們移動到輸出末尾(即*旋轉至*)。這些選項主要是為git difftool命令的使用而發明,否則可能不太有用。

-R

交換兩個輸入;即,顯示從索引或磁碟檔案到樹內容的差異。

--relative[=<路徑>]
--no-relative

當從專案的子目錄執行時,可以使用此選項指示其排除目錄外的更改並顯示相對於該目錄的路徑名。當您不在子目錄中(例如,在裸倉庫中)時,可以透過提供<path>作為引數來指定輸出相對於哪個子目錄。--no-relative可用於抵消diff.relative配置選項和先前的--relative

-a
--text

將所有檔案視為文字。

--ignore-cr-at-eol

進行比較時忽略行尾的回車符。

--ignore-space-at-eol

忽略行尾空格的更改。

-b
--ignore-space-change

忽略空格數量的變化。這會忽略行尾的空格,並將所有其他一個或多個空格序列視為等效。

-w
--ignore-all-space

比較行時忽略空格。即使一行有空格而另一行沒有,這也忽略了差異。

--ignore-blank-lines

忽略所有空行的更改。

-I<正則表示式>
--ignore-matching-lines=<正則表示式>

忽略所有行都匹配 <regex> 的更改。此選項可以多次指定。

--inter-hunk-context=<數字>

在差異塊之間顯示上下文,最多達指定行數 <number>,從而合併彼此接近的塊。預設為 diff.interHunkContext,如果未設定配置選項則為 0。

-W
--function-context

將整個函式作為每個更改的上下文行顯示。函式名稱的確定方式與git diff計算補丁塊頭的方式相同(參見gitattributes[5]中的“定義自定義塊頭”)。

--exit-code

使程式以類似於 diff(1) 的程式碼退出。也就是說,如果存在差異,則以 1 退出,0 表示無差異。

--quiet

停用程式的所有輸出。隱含--exit-code。停用外部差異幫助程式的執行,其退出程式碼不被信任,即其各自的配置選項diff.trustExitCodediff.<driver>.trustExitCode或環境變數GIT_EXTERNAL_DIFF_TRUST_EXIT_CODE為假。

--ext-diff

允許執行外部差異輔助程式。如果您使用 gitattributes[5] 設定了外部差異驅動程式,則需要與 git-log[1] 等命令一起使用此選項。

--no-ext-diff

禁止外部差異驅動程式。

--textconv
--no-textconv

在比較二進位制檔案時,允許(或不允許)執行外部文字轉換過濾器。有關詳細資訊,請參見gitattributes[5]。由於textconv過濾器通常是單向轉換,因此生成的差異適合人類閱讀,但無法應用。因此,textconv過濾器預設僅對git-diff[1]git-log[1]啟用,而不對git-format-patch[1]或差異底層命令啟用。

--ignore-submodules[=(none|untracked|dirty|all)]

在生成差異時忽略對子模組的更改。all是預設值。使用none會認為子模組已修改,如果它包含未跟蹤或已修改的檔案,或者其HEAD與主專案中記錄的提交不同,並且可用於覆蓋git-config[1]gitmodules[5]ignore選項的任何設定。當使用untracked時,如果子模組僅包含未跟蹤內容,則不將其視為髒(但仍會掃描其修改內容)。使用dirty會忽略子模組工作樹的所有更改,僅顯示主專案中儲存的提交更改(這是1.7.0之前的行為)。使用all會隱藏對子模組的所有更改。

--src-prefix=<字首>

顯示給定的源字首 <prefix> 而不是 "a/"。

--dst-prefix=<字首>

顯示給定的目標字首 <prefix> 而不是 "b/"。

--no-prefix

不顯示任何源或目標字首。

--default-prefix

使用預設的源和目標字首(“a/”和“b/”)。這會覆蓋諸如diff.noprefixdiff.srcPrefixdiff.dstPrefixdiff.mnemonicPrefix等配置變數(參見git-config[1])。

--line-prefix=<字首>

在每行輸出前面新增一個額外的 <prefix>

--ita-invisible-in-index

預設情況下,透過git add -N新增的條目在git diff中顯示為已存在的空檔案,在git diff --cached中顯示為新檔案。此選項使條目在git diff中顯示為新檔案,在git diff --cached中顯示為不存在。此選項可以使用--ita-visible-in-index恢復。這兩個選項都是實驗性的,將來可能會被移除。

有關這些通用選項的更詳細說明,另請參見 gitdiffcore[7]

使用 -p 生成補丁文字

執行帶有-p選項的git-diff[1]git-log[1]git-show[1]git-diff-index[1]git-diff-tree[1]git-diff-files[1]會生成補丁文字。您可以透過GIT_EXTERNAL_DIFFGIT_DIFF_OPTS環境變數(參見git[1])以及diff屬性(參見gitattributes[5])自定義補丁文字的建立。

-p 選項生成的輸出與傳統的 diff 格式略有不同:

  1. 它前面是“git diff”頭,看起來像這樣:

    diff --git a/file1 b/file2

    a/b/檔名是相同的,除非涉及重新命名/複製。特別是,即使是建立或刪除,也不會使用/dev/null來代替a/b/檔名。

    當涉及重新命名/複製時,file1file2 分別顯示重新命名/複製的原始檔名稱和重新命名/複製生成的檔名稱。

  2. 後面跟著一個或多個擴充套件頭行:

    old mode <mode>
    new mode <mode>
    deleted file mode <mode>
    new file mode <mode>
    copy from <path>
    copy to <path>
    rename from <path>
    rename to <path>
    similarity index <number>
    dissimilarity index <number>
    index <hash>..<hash> <mode>

    檔案模式 <mode> 以 6 位八進位制數字列印,包括檔案型別和檔案許可權位。

    擴充套件頭中的路徑名不包含 a/b/ 字首。

    相似度索引是未更改行的百分比,而差異度索引是已更改行的百分比。它是一個向下取整的整數,後跟一個百分號。因此,相似度索引值100%保留給兩個相同的檔案,而100%差異度意味著舊檔案中沒有一行進入新檔案。

    索引行包括更改前後的 blob 物件名稱。如果檔案模式沒有更改,則包含 <mode>;否則,單獨的行指示舊模式和新模式。

  3. 包含“不尋常”字元的路徑名將按照配置變數 core.quotePath 的解釋進行引用(參見 git-config[1])。

  4. 輸出中所有的file1檔案指代提交之前的檔案,所有file2檔案指代提交之後的檔案。順序地將每個更改應用到每個檔案是不正確的。例如,這個補丁將交換a和b

    diff --git a/a b/b
    rename from a
    rename to b
    diff --git a/b b/a
    rename from b
    rename to a
  5. Hunk 頭會提及 hunk 應用到的函式名稱。有關如何根據特定語言進行調整的詳細資訊,請參見 gitattributes[5] 中的“定義自定義 hunk-header”。

組合 diff 格式

任何生成差異的命令都可以接受-c--cc選項,以便在顯示合併時生成*組合差異*。這是使用git-diff[1]git-show[1]顯示合併時的預設格式。另請注意,您可以向這些命令中的任何一個提供合適的--diff-merges選項,以強制生成特定格式的差異。

“組合 diff”格式如下所示:

diff --combined describe.c
index fabadb8,cc95eb0..4866510
--- a/describe.c
+++ b/describe.c
@@@ -98,20 -98,12 +98,20 @@@
	return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
  }

- static void describe(char *arg)
 -static void describe(struct commit *cmit, int last_one)
++static void describe(char *arg, int last_one)
  {
 +	unsigned char sha1[20];
 +	struct commit *cmit;
	struct commit_list *list;
	static int initialized = 0;
	struct commit_name *n;

 +	if (get_sha1(arg, sha1) < 0)
 +		usage(describe_usage);
 +	cmit = lookup_commit_reference(sha1);
 +	if (!cmit)
 +		usage(describe_usage);
 +
	if (!initialized) {
		initialized = 1;
		for_each_ref(get_name);
  1. 它前面是“git diff”頭,看起來像這樣(使用 -c 選項時):

    diff --combined file

    或者像這樣(使用 --cc 選項時):

    diff --cc file
  2. 後面跟著一個或多個擴充套件頭行(此示例顯示了一個包含兩個父級的合併):

    index <hash>,<hash>..<hash>
    mode <mode>,<mode>..<mode>
    new file mode <mode>
    deleted file mode <mode>,<mode>

    mode <mode>,<mode>..<mode>行僅在至少一個<mode>與其他不同時出現。帶有檢測到的內容移動(重新命名和複製檢測)資訊的擴充套件頭旨在與兩個<tree-ish>的差異一起使用,並且不用於組合差異格式。

  3. 後面跟著一個兩行的“原始檔/目標檔案”頭:

    --- a/file
    +++ b/file

    類似於傳統 unified diff 格式的兩行頭,/dev/null 用於指示已建立或已刪除的檔案。

    然而,如果提供了 --combined-all-paths 選項,您將得到一個 N+1 行的“原始檔/目標檔案”頭,而不是兩行的“原始檔/目標檔案”頭,其中 N 是合併提交中父級的數量:

    --- a/file
    --- a/file
    --- a/file
    +++ b/file

    如果重新命名或複製檢測處於活動狀態,這種擴充套件格式會很有用,可以讓您檢視不同父級中檔案的原始名稱。

  4. 塊頭格式已修改,以防止人們意外將其饋送給patch -p1。組合差異格式是為了審查合併提交更改而建立的,並非用於應用。該更改類似於擴充套件索引頭中的更改

    @@@ <from-file-range> <from-file-range> <to-file-range> @@@

    組合 diff 格式的塊頭中有(父級數量 + 1)個 @ 字元。

與傳統的*統一*差異格式不同,後者顯示兩個檔案A和B,其中單列帶有-(減號——出現在A中但在B中刪除)、+(加號——在A中缺失但新增到B中)或" "(空格——未更改)字首,此格式將兩個或更多檔案file1, file2,…​與一個檔案X進行比較,並顯示X與每個檔案N的區別。每個檔案N都有一列附加到輸出行前,以指示X的行與它的不同之處。

列N中的-字元表示該行出現在檔案N中,但未出現在結果中。列N中的+字元表示該行出現在結果中,而檔案N沒有該行(換句話說,從該父級的角度來看,該行已新增)。

在上述示例輸出中,函式簽名從兩個檔案都發生了更改(因此從file1和file2都刪除了兩個-,加上++表示新增的一行未出現在file1或file2中)。此外,還有八行與file1相同但未出現在file2中(因此以+為字首)。

當透過git diff-tree -c顯示時,它將合併提交的父級與合併結果進行比較(即file1..fileN是父級)。當透過git diff-files -c顯示時,它將兩個未解決的合併父級與工作樹檔案進行比較(即file1是階段2,又稱“我們的版本”,file2是階段3,又稱“他們的版本”)。

GIT

Git[1] 套件的一部分

scroll-to-top