?
This document uses PHP Chinese website manual Release
gitdiffcore - Tweaking diff output
git diff *
該DIFF命令git diff-index
,git diff-files
以及git diff-tree
可以告訴操作展示之前,他們在非傳統(tǒng)的方式找到差異diff
的輸出。操作統(tǒng)稱為“diffcore轉換”。本短文描述了它們是什么以及如何使用它們來產(chǎn)生diff
比傳統(tǒng)類型更容易理解的輸出。
git diff-*
系列的工作原理是:第一比較兩組文件:
git diff-index
比較“樹”對象和工作目錄(當--cached
不使用標志時)或“樹”對象和索引文件(使用--cached
標志時)的內容;
git diff-files
比較索引文件和工作目錄的內容;
git diff-tree
比較兩個“樹”對象的內容;
在所有這些情況下,命令本身首先可選地通過在它們的命令行上給出的任何路徑規(guī)格限制兩組文件,并比較兩組得到的文件中的對應路徑。
pathspecs用于限制差異操作的世界。他們刪除指定的路徑名集外的文件對。例如,如果文件對的輸入集包括:
:100644 100644 bcd1234... 0123456... M junkfile
但是命令調用是git diff-files myfile
,那么junkfile條目將從列表中刪除,因為只考慮“myfile”。
比較結果從這些命令傳遞到內部稱為“diffcore”的內容,格式類似于不使用-p選項時輸出的格式。例如
in-place edit :100644 100644 bcd1234... 0123456... M file0 create :000000 100644 0000000... 1234567... A file4delete :100644 000000 1234567... 0000000... D file5 unmerged :000000 000000 0000000... 0000000... U file6
diffcore機制提供了一個這樣的比較結果的列表(每一個稱為“文件對”,盡管此時每個人都在討論單個文件),并將這樣的列表轉換為另一個列表。目前有5個這樣的轉換:
diffcore-break
diffcore-rename
diffcore-merge-broken
diffcore-pickaxe
diffcore-order
這些按順序應用。filepairs git diff-*
命令查找的集合用作diffcore-break的輸入,diffcore-break的輸出用作下一個轉換的輸入。然后將最終結果傳遞給輸出例程,并生成diff-raw格式(請參閱git diff-*
命令手冊的輸出格式部分)或diff-patch格式。
鏈中的第二個轉換是diffcore-break,并由git diff-*
命令的-B選項控制。這用于檢測表示“完全重寫”的文件對,并將該文件對分成兩個文件對,分別表示刪除和創(chuàng)建。例如,如果輸入包含此文件對:
:100644 100644 bcd1234... 0123456... M file0
并且如果它檢測到文件“file0”被完全重寫,則它將其更改為:
:100644 000000 bcd1234... 0000000... D file0:000000 100644 0000000... 0123456... A file0
為了打破文件對,diffcore-break檢查修改之前和之后文件內容之間的變化程度(即具有“bcd1234 ...”和“0123456 ...”作為其SHA-1內容ID的內容在上面的例子中)。原始內容的刪除量和新素材的插入量相加在一起,如果超過“中斷分數(shù)”,則文件對被分成兩部分。中斷分數(shù)默認為原始大小和結果大小的50%(即,如果編輯縮小文件,則使用結果的大小;如果編輯延長文件,則使用原始大?。⑶铱梢酝ㄟ^在“-B”選項之后給出一個數(shù)字來進行定制(例如“-B75”告訴它使用75%)。
此轉換用于檢測重命名和副本,并由-M選項(以檢測重命名)和-C選項(以檢測副本)控制git diff-*
命令。如果輸入包含這些文件對象:
:100644 000000 0123456... 0000000... D fileX:000000 100644 0000000... 0123456... A file0
并且刪除的文件fileX的內容與創(chuàng)建的文件file0的內容相似,則重命名檢測將合并這些文件對并創(chuàng)建:
:100644 100644 0123456... 0123456... R100 fileX file0
當使用“-C”選項時,修改文件的原始內容和刪除的文件(以及未修改的文件,如果使用“--find-copies-harder”選項)被認為是源文件的候選重命名/復制操作。如果輸入類似這些文件對,那就說說修改過的文件fileY和一個新創(chuàng)建的文件file0:
:100644 100644 0123456... 1234567... M fileY:000000 100644 0000000... bcd3456... A file0
fileY的原始內容和file0的結果內容進行比較,如果它們足夠相似,它們將更改為:
:100644 100644 0123456... 1234567... M fileY:100644 100644 0123456... bcd3456... C100 fileY file0
在重命名和復制檢測中,diffcore-break中使用的相同“變化程度”算法用于確定兩個文件是否“足夠相似”,并且可以定制為使用與默認值50%相似的得分在“-M”或“-C”選項之后給出一個數(shù)字(例如“-M8”來告訴它使用8/10 = 80%)。
注意。當“-C”選項與--find-copies-harder
選項一起使用時,git diff-*
命令將未修改的文件對提供給diffcore機制以及修改的機制。這可以讓復制檢測器將未修改的文件視為復制源候選項,代價是速度較慢。如果沒有--find-copies-harder
,git diff-*
只有當被復制的文件在相同的變更集中被修改時,命令才能檢測到拷貝。
此轉換用于合并由diffcore-break打破的文件對,而不是通過diffcore-rename轉換為rename/copy,返回到單個修改中。當使用diffcore-break時,它總是運行。
為了合并破損的文件對,它使用了diffcore-break和diffcore-rename使用的不同的“變化范圍”計算。它只計算從原始的刪除,并不計入插入。如果您從100行文檔中只刪除了10行,即使您添加了910行來創(chuàng)建新的1000行文檔,也沒有執(zhí)行完全重寫。diffcore-break打破了這種情況,以幫助diffcore-rename將文件對視為rename/copy檢測的候選對象,但是如果文件對以這種方式打破與其他文件對不匹配以創(chuàng)建rename/copy,則該轉換將它們合并回來進入原來的“修改”。
“extent of changes”參數(shù)可以從默認的80%調整(也就是說,除非超過80%的原始材料被刪除,破碎的對會重新合并為一個修改),給第二個數(shù)字為-B選項,如下所示:
-B50/60(給予50%的“破裂得分”以彌補破裂,使用60%作為diffcore-merge-broken)。
-B/60(與上面相同,因為diffcore-break默認為50%)。
請注意,早期的實現(xiàn)會將一對損壞的對作為單獨的創(chuàng)建和刪除補丁程序。這是一種不必要的破解,最新的實現(xiàn)總是將所有破損的對重新合并到修改中,但是由此產(chǎn)生的修補程序輸出格式不同,以便在完全重寫的情況下更容易查看,方法是顯示舊版本前綴的全部內容-
,隨后新版本的全部內容都以前綴+
。
此轉換將文件對的集合限制為那些以某種方式在預映像和postimage之間更改指定字符串的文件對。-S <文本塊>和-G <正則表達式>選項用于指定查找這些字符串的不同方式。
“-S <block of text>”檢測文件對象,其前像和后像具有不同的指定文本塊的出現(xiàn)次數(shù)。根據(jù)定義,它不會檢測文件中的移動。另外,當變更集移動批量文件而不影響有趣的字符串時,diffcore-rename像往常一樣踢,并-S
省略文件對(因為該字符串的出現(xiàn)次數(shù)在該重命名檢測的文件對中沒有變化)。使用時--pickaxe-regex
,將<文本塊>視為擴展的POSIX正則表達式進行匹配,而不是文字字符串。
“-G <regular expression>”(助記符:grep)檢測文本對,其文本差異的添加行或刪除行與給定正則表達式匹配。這意味著它會檢測文件中(或重命名檢測認為是同一個文件)的移動,這是噪聲。該實現(xiàn)運行差異兩次,greps,這可能是相當昂貴的。
如果使用-S
或-G
不使用--pickaxe-all
,則只有符合其各自標準的文件對保留在輸出中。何時--pickaxe-all
使用,如果即使一個文件對在變更集中與其各自的標準相匹配,整個變更集也會保留。此行為旨在使整個變更集環(huán)境中的審閱更容易。
這用于根據(jù)用戶(或項目)的口味重新排列文件對,并由git diff-*
命令的-O選項控制。
這需要一個文本文件,每個文件的行都是一個shell glob模式。匹配文件中較早行的全局模式的文件對在比較后一行匹配之前輸出,并且最后輸出不匹配任何全局模式的文件對。
舉個例子,核心Git的一個典型的命令文件可能看起來像這樣:
README Makefile Documentation*.h*.c t
git-diff[1], git-diff-files[1], git-diff-index[1], git-diff-tree[1], git-format-patch[1], git-log[1], gitglossary[7], The Git User’s Manual