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