?
This document uses PHP Chinese website manual Release
gitattributes - 定義每個路徑的屬性
$GIT_DIR/info/attributes, .gitattributes
一個gitattributes
文件是一個給attributes
路徑名的簡單文本文件。
gitattributes
文件中的每一行都是以下格式:
pattern attr1 attr2 ...
也就是說,一個模式后跟一個屬性列表,由空格分隔。前導(dǎo)空白和尾隨空白被忽略。開頭的行#
被忽略。以雙引號開頭的模式以 C 風(fēng)格引用。當(dāng)模式與所討論的路徑相匹配時,行中列出的屬性被賦予路徑。
對于給定路徑,每個屬性可以處于以下狀態(tài)之一:
Set
該路徑具有特殊值“true”的屬性; 這是通過僅列出屬性列表中屬性的名稱來指定的。
Unset
路徑具有特殊值“false”的屬性; 這是通過列出-
在屬性列表中以短劃線為前綴的屬性的名稱來指定的。
Set to a value
路徑具有指定字符串值的屬性; 這是通過=
在屬性列表中列出屬性的名稱,后跟等號和其值來指定的。
Unspecified
沒有模式匹配路徑,并且沒有任何說明路徑是否具有該屬性,路徑的屬性被稱為未指定。
當(dāng)多于一個模式匹配路徑時,稍后的一行覆蓋較早的一行。這個重寫是按屬性完成的。模式如何匹配路徑的規(guī)則與.gitignore
文件中的相同;見 gitignore [5]。不像.gitignore
,消極的模式是禁止的。
當(dāng)決定哪些屬性被分配給一個路徑時,Git 會咨詢$GIT_DIR/info/attributes
文件(其優(yōu)先級最高),將.gitattributes
文件放在與所討論的路徑相同的目錄中,并將其父目錄存儲到工作樹的頂級目錄中包含.gitattributes
來自有問題的路徑,其優(yōu)先級越低)。最后考慮全局和全系統(tǒng)文件(它們的優(yōu)先級最低)。
當(dāng).gitattributes
文件從工作樹中丟失時,索引中的路徑被用作回退。在結(jié)帳過程中,在索引中使用.gitattributes
,然后使用工作樹中的文件作為回退。
如果您希望僅影響單個存儲庫(即,將屬性分配給特定于該存儲庫的一個用戶工作流的$GIT_DIR/info/attributes
文件),則屬性應(yīng)放置在該文件中。應(yīng)該版本控制并分發(fā)到其他存儲庫(即所有用戶感興趣的屬性)的屬性應(yīng)該放入.gitattributes
文件中。應(yīng)該影響單個用戶的所有存儲庫的屬性應(yīng)放置在由core.attributesFile
配置選項指定的文件中(請參閱 git-config [1])。它的默認(rèn)值是 $ XDG_CONFIG_HOME / git / attributes。如果 $ XDG_CONFIG_HOME 未設(shè)置或為空,則改為使用 $ HOME / .config / git / attributes。系統(tǒng)中所有用戶的屬性應(yīng)放置在$(prefix)/etc/gitattributes
文件中。
有時您需要覆蓋一個要指定Unspecified
狀態(tài)的路徑的屬性設(shè)置。這可以通過列出帶有感嘆號!
前綴的屬性名稱來完成。
Git的某些操作可以通過將特定屬性分配給路徑來影響。目前,以下操作是可識別屬性的。
這些屬性會影響存儲在庫中的內(nèi)容復(fù)制到工作樹中的文件時,命令,如git checkout
和git merge
運(yùn)行。它們也會影響 Git 如何將存儲在庫中工作樹中的內(nèi)容存儲在git add
和git commit
之上。
text
該屬性啟用并控制行結(jié)束標(biāo)準(zhǔn)化。當(dāng)一個文本文件被標(biāo)準(zhǔn)化時,它的行尾將在存儲庫中轉(zhuǎn)換為 LF。要控制工作目錄中使用的行結(jié)束風(fēng)格,請使用單個文件的eol
屬性和所有文本文件的core.eol
配置變量。請注意,core.autocrlf
覆蓋core.eol
Set
text
在路徑上設(shè)置屬性可啟用行結(jié)束標(biāo)準(zhǔn)化并將路徑標(biāo)記為文本文件。換行轉(zhuǎn)換不需要猜測內(nèi)容類型。
Unset
取消設(shè)置text
路徑上的屬性會告訴 Git 在簽入或結(jié)帳時不要嘗試任何換行轉(zhuǎn)換。
Set to string value "auto"
當(dāng)text
設(shè)置為“自動”時,該路徑被標(biāo)記為自動換行結(jié)束。如果 Git 確定內(nèi)容是文本,則它的行尾在登記時會轉(zhuǎn)換為 LF。用 CRLF 提交文件時,不進(jìn)行轉(zhuǎn)換。
Unspecified
如果text
屬性未指定,Git 使用core.autocrlf
配置變量來確定文件是否應(yīng)該轉(zhuǎn)換。
任何其他值都會導(dǎo)致 Git 去扮演就像text
未被指定一樣。
eol
該屬性設(shè)置了要在工作目錄中使用的特定行結(jié)束樣式。它可以在沒有任何內(nèi)容檢查的情況下實(shí)現(xiàn)行尾轉(zhuǎn)換,從而有效地設(shè)置text
屬性。請注意,在具有 CRLF 行結(jié)尾的索引中的路徑上設(shè)置此屬性可能會使路徑被認(rèn)為是臟的。再次將路徑添加到索引將標(biāo)準(zhǔn)化索引中的行尾。
Set to string value "crlf"
此設(shè)置強(qiáng)制 Git 在簽入時對該文件的行結(jié)束進(jìn)行標(biāo)準(zhǔn)化,并在文件簽出時將其轉(zhuǎn)換為 CRLF。
Set to string value "lf"
此設(shè)置強(qiáng)制 Git 在簽入時將行尾標(biāo)準(zhǔn)化為 LF,并在簽出文件時阻止轉(zhuǎn)換為 CRLF。
crlf
屬性為了向后兼容,該crlf
屬性被解釋如下:
crlf text-crlf -text crlf=input eol=lf
雖然 Git 通常只保留文件內(nèi)容,但可以將其配置為在存儲庫中將行尾標(biāo)準(zhǔn)化為 LF,并可選擇將文件檢出時轉(zhuǎn)換為 CRLF。
如果您只是想在工作目錄中擁有 CRLF 行結(jié)束符,而不考慮您正在使用的存儲庫,則可以在不使用任何屬性的情況下設(shè)置配置變量“core.autocrlf”。
[core] autocrlf = true
這不會強(qiáng)制對文本文件進(jìn)行標(biāo)準(zhǔn)化,但會確保引入到存儲庫的文本文件的行結(jié)束符在添加時標(biāo)準(zhǔn)化為 LF,并且存儲庫中已經(jīng)標(biāo)準(zhǔn)化的文件保持標(biāo)準(zhǔn)化。
如果您想確保任何貢獻(xiàn)者向存儲庫引入的文本文件的行結(jié)束都已標(biāo)準(zhǔn)化,則可以將all
文件的text
屬性設(shè)置為“自動” all
。
* text=auto
這些屬性允許進(jìn)行細(xì)粒度的控制,如何轉(zhuǎn)換行結(jié)束符。下面是一個例子,它將使Git規(guī)范化 .txt,.vcproj 和 .sh 文件,確保.vcproj 文件具有 CRLF,并且.sh 文件在工作目錄中具有 LF,并防止.jpg 文件無論其內(nèi)容如何標(biāo)準(zhǔn)化。
* text=auto*.txt text*.vcproj text eol=crlf*.sh text eol=lf*.jpg -text
注意 | 當(dāng)使用推送到中央存儲庫的跨平臺項目中啟用 text = auto 轉(zhuǎn)換時,應(yīng)該對包含 CRLF 的文本文件進(jìn)行規(guī)范化。 |
---|
從一個干凈的工作目錄:
$ echo "* text=auto" >.gitattributes $ git read-tree --empty # Clean index, force re-scan of working directory $ git add .$ git status # Show files that will be normalized $ git commit -m "Introduce end-of-line normalization"
如果有任何不應(yīng)歸一化的文件在git status
出現(xiàn),請在運(yùn)行git add -u
之前取消其text
屬性。
manual.pdf -text
相反,Git 未檢測到的文本文件可以手動啟用規(guī)范化。
weirdchars.txt text
如果core.safecrlf
設(shè)置為“true”或“warn”,Git 將驗證轉(zhuǎn)換對于當(dāng)前core.autocrlf
設(shè)置是否可逆。對于“真實(shí)”,Git 拒絕不可逆轉(zhuǎn)的轉(zhuǎn)換; 對于“警告”,Git 僅打印警告,但接受不可逆轉(zhuǎn)的轉(zhuǎn)換。安全觸發(fā)器阻止對工作樹中的文件執(zhí)行這種轉(zhuǎn)換,但有一些例外。即使...
git add
本身不會觸摸工作樹中的文件,下一次檢出會觸發(fā)安全觸發(fā)器;
git apply
使用補(bǔ)丁更新文本文件確實(shí)會觸摸工作樹中的文件,但操作是關(guān)于文本文件和 CRLF 轉(zhuǎn)換是關(guān)于修復(fù)行結(jié)束的不一致性,因此安全性不會觸發(fā);
git diff
本身不會觸摸工作樹中的文件,它通常會運(yùn)行以檢查您打算接下來的git add
更改。為了及早發(fā)現(xiàn)潛在的問題,安全觸發(fā)器。
ident
當(dāng)ident
為路徑設(shè)置屬性時,Git 用blob對象中的$Id:
替換$Id$
,后面跟著40個字符的十六進(jìn)制 blob 對象名稱,后面跟著美元符號$
。任何以worktree文件開頭$Id:
和結(jié)尾的字節(jié)序列$
在登記時被$Id$
替換。
filter
一個filter
屬性可以設(shè)置為一個字符串值,用于命名配置中指定的過濾器驅(qū)動程序。
過濾器驅(qū)動程序由一個clean
命令和一個smudge
命令組成,其中任何一個都可以不指定。結(jié)帳時,當(dāng)smudge
指定命令時,該命令從其標(biāo)準(zhǔn)輸入中輸入blob對象,其標(biāo)準(zhǔn)輸出用于更新工作樹文件。同樣,該clean
命令用于在簽入時轉(zhuǎn)換工作文件的內(nèi)容。默認(rèn)情況下,這些命令只處理一個blob并終止。例如git add --all
,如果使用長時間運(yùn)行的process
過濾器來替代clean
和/或smudge
過濾器,則例如,Git 可以在單個Git 命令的整個生命周期內(nèi)通過單個過濾器命令調(diào)用來處理所有 blob 。如果長時間運(yùn)行process
過濾器配置,那么它始終優(yōu)先于配置的單個 blob 過濾器。有關(guān)用于與process
過濾器通信的協(xié)議的說明,請參閱下面的部分。
內(nèi)容過濾的一個用途是將內(nèi)容按摩成更適合平臺,文件系統(tǒng)和用戶使用的形狀。對于這種操作模式,這里的關(guān)鍵詞是“更方便”,而不是“把某些不可用的東西變成可用的”。換句話說,目的是如果某人取消了過濾器驅(qū)動程序的定義,或者沒有合適的過濾器程序,該項目仍然可以使用。
內(nèi)容過濾的另一個用途是存儲不能直接在存儲庫中使用的內(nèi)容(例如,引用 Git 外部存儲的真實(shí)內(nèi)容的 UUID 或加密的內(nèi)容),并在結(jié)帳時將其轉(zhuǎn)換為可用的形式(例如下載外部內(nèi)容或解密加密的內(nèi)容)。
這兩個過濾器的行為不同,默認(rèn)情況下,過濾器被視為前者,將內(nèi)容按摩到更方便的形狀。配置中缺少的過濾器驅(qū)動程序定義或以非零狀態(tài)退出的過濾器驅(qū)動程序不是錯誤,而是使過濾器成為無操作中繼。
您可以聲明過濾器通過將過濾器<driver> .需要配置變量設(shè)置為true
,將本身不可用的內(nèi)容轉(zhuǎn)換為可用內(nèi)容。
例如,在.gitattributes 中,您可以為路徑分配filter
屬性。
*.c filter=indent
然后,您可以在.git / config 中定義一個“filter.indent.clean”和“filter.indent.smudge”配置來指定一對命令,以在源文件簽入時修改C程序的內(nèi)容(“clean “運(yùn)行)并檢出(因為命令是”cat“,所以不做任何更改)。
[filter "indent"] clean = indent smudge = cat
為了獲得最佳效果,clean
如果運(yùn)行兩次(“清潔→清潔”應(yīng)該相當(dāng)于“清潔”),并且多個smudge
命令不應(yīng)該改變clean
輸出(“污跡→污跡→清潔”應(yīng)當(dāng)相當(dāng)以“清潔”)。請參閱下面的合并部分。
“indent”過濾器在這方面表現(xiàn)良好:它不會修改已經(jīng)正確縮進(jìn)的輸入。在這種情況下,缺少污跡過濾器意味著干凈的過濾器must
接受自己的輸出而不修改它。
如果過濾器must
成功以使存儲的內(nèi)容可用,則可以在配置中聲明過濾器是required
:
[filter "crypt"] clean = openssl enc ... smudge = openssl enc -d ... required
過濾器命令行上的序列“%f”被替換為過濾器正在處理的文件的名稱。過濾器可能會在關(guān)鍵字替換中使用它。例如:
[filter "p4"] clean = git-p4-filter --clean %f smudge = git-p4-filter --smudge %f
請注意,“%f”是正在處理的路徑的名稱。根據(jù)正在過濾的版本,磁盤上的相應(yīng)文件可能不存在,或者可能具有不同的內(nèi)容。所以,smudge 和 clean 命令不應(yīng)該嘗試訪問磁盤上的文件,而只能用作標(biāo)準(zhǔn)輸入提供給他們的內(nèi)容的過濾器。
如果過濾器命令(字符串值)是通過filter.<driver>.process
定義的,那么 Git 可以在單個 Git 命令的整個生命周期內(nèi)使用單個過濾器調(diào)用來處理所有 blob。這是通過使用基于標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出的數(shù)據(jù)包格式(pkt-line,參見technical / protocol-common.txt)來實(shí)現(xiàn)的,如下所示。除“* CONTENT”數(shù)據(jù)包和“0000”清除數(shù)據(jù)包之外的所有數(shù)據(jù)包都被視為文本,因此以LF結(jié)尾。
Git在遇到需要清理或弄臟的第一個文件時啟動過濾器。過濾器啟動后,Git 發(fā)送一個歡迎消息(“git-filter-client”),一個支持的協(xié)議版本號列表和一個 flush 數(shù)據(jù)包。Git希望從先前發(fā)送的列表中讀取一個歡迎響應(yīng)消息(“git-filter-server”),一個協(xié)議版本號和一個 flush 數(shù)據(jù)包。所有進(jìn)一步的溝通將基于選定的版本。下面的其余協(xié)議描述文檔“version= 2”。請注意,以下示例中的“version = 42”不存在,僅用于說明協(xié)議在多個版本中的外觀。
版本協(xié)商之后,Git 發(fā)送它支持的所有功能和清除數(shù)據(jù)包的列表。Git 希望讀取所需功能的列表,該列表必須是支持的功能列表的一個子集,以及作為響應(yīng)的 flush 數(shù)據(jù)包:
packet: git> git-filter-client packet: git> version=2packet: git> version=42packet: git> 0000packet: git< git-filter-server packet: git< version=2packet: git< 0000packet: git> capability=clean packet: git> capability=smudge packet: git> capability=not-yet-invented packet: git> 0000packet: git< capability=clean packet: git< capability=smudge packet: git< 0000
版本2中支持的過濾器功能是“干凈”,“污跡”和“延遲”( "clean", "smudge", and "delay")。
之后,Git 發(fā)送一個以 flush 數(shù)據(jù)包結(jié)尾的“key = value”對的列表。該列表將至少包含 filter 命令(基于支持的功能)以及要相對于存儲庫根目錄過濾的文件的路徑名。在沖洗數(shù)據(jù)包之后,Git 發(fā)送分割零或多個 pkt-line 數(shù)據(jù)包的內(nèi)容和一個 flush 數(shù)據(jù)包來終止內(nèi)容。請注意,過濾器在收到內(nèi)容和最終清除數(shù)據(jù)包之前不得發(fā)送任何響應(yīng)。另請注意,“key = value”對的“值”可以包含“=”字符,而該鍵不會包含該字符。
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> 0000packet: git> CONTENT packet: git> 0000
預(yù)計過濾器將以一個以“flush =”數(shù)據(jù)包結(jié)尾的“key = value”對列表作為響應(yīng)。如果過濾器沒有遇到問題,則列表必須包含“成功”狀態(tài)。在這些數(shù)據(jù)包之后,過濾器應(yīng)該在零或多個 pkt-line 數(shù)據(jù)包中發(fā)送內(nèi)容,并在最后發(fā)送一個flush數(shù)據(jù)包。最后,預(yù)計會有一個以 flush 數(shù)據(jù)包結(jié)尾的“key = value”對的第二個列表。過濾器可以更改第二個列表中的狀態(tài)或保持狀態(tài)為空列表。請注意,空列表必須以 flush 數(shù)據(jù)包終止,無論如何。
packet: git< status=success packet: git< 0000packet: git< SMUDGED_CONTENT packet: git< 0000packet: git< 0000 # empty list, keep "status=success" unchanged!
如果結(jié)果內(nèi)容為空,則預(yù)計過濾器將以“成功”狀態(tài)和清除數(shù)據(jù)包來響應(yīng)空信息。
packet: git< status=success packet: git< 0000packet: git< 0000 # empty content!packet: git< 0000 # empty list, keep "status=success" unchanged!
如果過濾器不能或不想處理內(nèi)容,則預(yù)期會以“錯誤”狀態(tài)進(jìn)行響應(yīng)。
packet: git< status=error packet: git< 0000
如果過濾器在處理過程中遇到錯誤,則可以在內(nèi)容(部分或完全)發(fā)送后發(fā)送狀態(tài)“錯誤”。
packet: git< status=success packet: git< 0000packet: git< HALF_WRITTEN_ERRONEOUS_CONTENT packet: git< 0000packet: git< status=error packet: git< 0000
如果過濾器無法或不想處理內(nèi)容以及 Git 進(jìn)程生命周期內(nèi)的任何未來內(nèi)容,則預(yù)計會在協(xié)議中的任何時間以“中止”狀態(tài)進(jìn)行響應(yīng)。
packet: git< status=abort packet: git< 0000
如果設(shè)置了“錯誤”/“中止”狀態(tài),Git 既不停止也不重新啟動過濾器進(jìn)程。但是,Git 根據(jù)filter.<driver>.required
標(biāo)志設(shè)置退出代碼,模仿filter.<driver>.clean
/ filter.<driver>.smudge
機(jī)制的行為。
如果過濾器在通信過程中死亡或者不遵守協(xié)議,則 Git 將停止過濾器過程,并使用下一個需要處理的文件重新啟動它。根據(jù)filter.<driver>.required
標(biāo)志,Git會將其解釋為錯誤。
過濾器處理完一個命令后,需要等待包含下一個命令的“key = value”列表。Git 會在退出時關(guān)閉命令管道。預(yù)計過濾器會檢測 EOF 并自行退出。Git 將等待,直到過濾器進(jìn)程停止。
如果過濾器支持“延遲”功能,則 Git 可以在過濾器命令和路徑名后面發(fā)送“can-delay”標(biāo)志。這個標(biāo)志表示過濾器可以通過沒有內(nèi)容但響應(yīng)狀態(tài)“延遲”和清除數(shù)據(jù)包來延遲過濾當(dāng)前 blob(例如以補(bǔ)償網(wǎng)絡(luò)等待時間)。
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> can-delay=1packet: git> 0000packet: git> CONTENT packet: git> 0000packet: git< status=delayed packet: git< 0000
如果過濾器支持“延遲”功能,那么它必須支持“l(fā)ist_available_blobs”命令。如果Git發(fā)送這個命令,那么過濾器應(yīng)該會返回一個路徑名列表,這些路徑名代表早先被延遲并且現(xiàn)在可用的斑點(diǎn)。該列表必須以 flush 數(shù)據(jù)包結(jié)尾,后跟“success”狀態(tài),該數(shù)據(jù)也以 flush 數(shù)據(jù)包終止。如果沒有用于延遲路徑的斑點(diǎn)可用,則過濾器預(yù)計將阻止該響應(yīng),直到至少有一個斑點(diǎn)可用。過濾器可以通過發(fā)送一個空列表來告訴 Git 它沒有更多的延遲斑點(diǎn)。只要過濾器響應(yīng)一個空的列表,Git 就會停止詢問。此時 Git 尚未收到的所有斑點(diǎn)都將被視為丟失,并會導(dǎo)致錯誤。
packet: git> command=list_available_blobs packet: git> 0000packet: git< pathname=path/testfile.dat packet: git< pathname=path/otherfile.dat packet: git< 0000packet: git< status=success packet: git< 0000
After Git received the pathnames, it will request the corresponding blobs again. These requests contain a pathname and an empty content section. The filter is expected to respond with the smudged content in the usual way as explained above.
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> 0000packet: git> 0000 # empty content!packet: git< status=success packet: git< 0000packet: git< SMUDGED_CONTENT packet: git< 0000packet: git< 0000 # empty list, keep "status=success" unchanged!
長時間運(yùn)行的過濾器演示實(shí)現(xiàn)可以在contrib/long-running-filter/example.pl
位于 Git 核心存儲庫中找到。如果您開發(fā)自己的長時間運(yùn)行的過濾器進(jìn)程,那么GIT_TRACE_PACKET
環(huán)境變量對調(diào)試非常有幫助(請參閱 git [1])。
請注意,由于前兩者使用不同的進(jìn)程間通信協(xié)議,因此不能使用現(xiàn)有filter.<driver>.clean
或filter.<driver>.smudge
命令filter.<driver>.process
。
在簽入代碼路徑中,首先使用filter
驅(qū)動程序(如果指定了相應(yīng)的驅(qū)動程序并將其定義)轉(zhuǎn)換為工作樹文件,那么使用ident
(如果已指定)處理結(jié)果,然后使用text
(如果指定并適用,則再次)處理結(jié)果。
在簽出代碼路徑中,blob 內(nèi)容首先被text
轉(zhuǎn)換,然后被ident
提交filter
。
如果您已將屬性添加到導(dǎo)致該文件的規(guī)范存儲庫格式發(fā)生更改的文件(如添加干凈/污跡過濾器或 text / eol / ident 屬性),那么合并屬性不在位的任何東西通常會導(dǎo)致合并沖突。
為了防止這些不必要的合并沖突,可以通過設(shè)置merge.renormalize
配置變量來解決三向合并問題時,可以讓 Git 運(yùn)行虛擬檢出和檢入文件的所有三個階段。這樣可以防止轉(zhuǎn)換文件與未轉(zhuǎn)換文件合并時由檢入轉(zhuǎn)換引起的更改導(dǎo)致虛假合并沖突。
只要“污跡→清理”與“干凈”相同,即使對已經(jīng)被污染的文件也會產(chǎn)生相同的輸出,此策略將自動解決所有與過濾器有關(guān)的沖突。不以這種方式操作的過濾器可能會導(dǎo)致額外的合并沖突,必須手動解決。
diff
該屬性diff
影響 Git 如何為特定文件生成差異。它可以告訴 Git 是為路徑生成文本補(bǔ)丁還是將路徑視為二進(jìn)制文件。它也可以影響在 Hunk 標(biāo)題@@ -k,l +n,m @@
行上顯示的行,告訴 Git 使用外部命令來生成 diff,或者在生成 diff 之前讓 Git 將二進(jìn)制文件轉(zhuǎn)換為文本格式。
Set
將diff
屬性設(shè)置的路徑視為文本,即使它們包含通常從不出現(xiàn)在文本文件中的字節(jié)值(例如 NUL)。
Unset
diff
屬性未設(shè)置的路徑將生成Binary files differ
(如果啟用了二進(jìn)制修補(bǔ)程序,則會生成二進(jìn)制修補(bǔ)程序)。
Unspecified
diff
首先未指定屬性的路徑將檢查其內(nèi)容,如果它看起來像文本且小于 core.bigFileThreshold,則將其視為文本。否則會產(chǎn)生Binary files differ
。
String
Diff 使用指定的 diff 驅(qū)動程序顯示。每個驅(qū)動程序可以指定一個或多個選項,如以下部分所述。diff 驅(qū)動程序“foo”的選項由 Git 配置文件的“diff.foo”部分中的配置變量定義。
差異驅(qū)動程序的定義是在gitconfig
,而非gitattributes
文件中完成的,所以嚴(yán)格來說,這個手冊頁是一個錯誤的地方來談?wù)撍?。然?..
要定義一個外部差異驅(qū)動程序jcdiff
,添加一個部分到你的$GIT_DIR/config
文件(或$HOME/.gitconfig
文件),像這樣:
[diff "jcdiff"] command = j-c-diff
當(dāng) Git 需要向diff
屬性設(shè)置為jcdiff
的路徑顯示 diff 時,它會調(diào)用您使用上述配置指定的命令,即j-c-diff
使用7個參數(shù),就像GIT_EXTERNAL_DIFF
調(diào)用程序一樣。有關(guān)詳細(xì)信息,請參閱 git [1]。
文本差異輸出中的每組變化(稱為“大塊”)都以以下格式的行作為前綴:
@@ -k,l +n,m @@ TEXT
這被稱為a hunk header
。默認(rèn)情況下,“TEXT”部分是以字母,下劃線或美元符號開頭的行; 這匹配了 GNU diff -p
輸出使用的內(nèi)容。但是,此默認(rèn)選擇不適用于某些內(nèi)容,您可以使用自定義模式進(jìn)行選擇。
首先,在.gitattributes 中,您將為diff
路徑分配屬性。
*.tex diff=tex
然后,您將定義一個“diff.tex.xfuncname”配置來指定一個正則表達(dá)式,該正則表達(dá)式與您希望顯示為大塊頭“TEXT”的行匹配。添加一個部分到你的$GIT_DIR/config
文件(或$HOME/.gitconfig
文件),像這樣:
[diff "tex"] xfuncname = "^(\\\\(sub)*section\\{.*)$"
注意。配置文件解析器會使用單級反斜杠,因此您需要將反斜杠加倍; 上面的模式選擇一行以反斜杠開始的行,以及零個或多個出現(xiàn)的sub
緊跟著section
的開放大括號,直到行尾。
有一些內(nèi)置模式可以使這更容易,并且tex
是其中之一,所以您不必在配置文件中編寫上述內(nèi)容(您仍然需要使用屬性機(jī)制來啟用它,通過.gitattributes
)。以下內(nèi)置模式可用:
ada
適用于 Ada 語言的源代碼。
bibtex
適用于帶有 BibTeX 編碼參考的文件。
cpp
適用于 C和C ++語言的源代碼。
csharp
適用于 C#語言的源代碼。
css
適合級聯(lián)樣式表。
fortran
適用于 Fortran 語言的源代碼。
fountain
適合噴泉文件。
html
適用于 HTML / XHTML 文檔。
java
適用于 Java 語言的源代碼。
matlab
適用于 MATLAB 語言的源代碼。
objc
適用于 Objective-C 語言的源代碼。
pascal
適用于 Pascal / Delphi 語言的源代碼。
perl
適用于 Perl 語言的源代碼。
php
適用于 PHP 語言的源代碼。
python
適用于 Python 語言的源代碼。
ruby
適用于 Ruby 語言的源代碼。
tex
適用于 LaTeX 文檔的源代碼。
您可以git diff --word-diff
通過在“diff。*。wordRegex”配置變量中指定適當(dāng)?shù)恼齽t表達(dá)式來自定義用于在一行中拆分單詞的規(guī)則。例如,在TeX中,反斜杠后面跟著一系列字母形成一個命令,但是幾個這樣的命令可以一起運(yùn)行而不干預(yù)空白。要將它們分開,請在$GIT_DIR/config
文件(或$HOME/.gitconfig
文件)中使用正則表達(dá)式,如下所示:
[diff "tex"] wordRegex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+"
為上一節(jié)中列出的所有語言提供了內(nèi)置模式。
有時需要查看某些二進(jìn)制文件的文本轉(zhuǎn)換版本的差異。例如,文字處理器文檔可以轉(zhuǎn)換為 ASCII 文本表示,并顯示文本的差異。即使這種轉(zhuǎn)換丟失了一些信息,但由此產(chǎn)生的差異對于人類觀看是有用的(但不能直接應(yīng)用)。
textconv
配置選項被用來定義用于執(zhí)行這種轉(zhuǎn)換的程序。程序應(yīng)該采用一個參數(shù),即要轉(zhuǎn)換的文件的名稱,并在 stdout 上生成結(jié)果文本。
例如,要顯示文件的exif信息的差異而不是二進(jìn)制信息(假設(shè)已安裝 exif 工具),請將以下部分添加到$GIT_DIR/config
文件(或$HOME/.gitconfig
文件)中:
[diff "jpg"] textconv = exif
注意 | 文本轉(zhuǎn)換通常是單向轉(zhuǎn)換; 在這個例子中,我們失去了實(shí)際的圖像內(nèi)容,只關(guān)注文本數(shù)據(jù)。這意味著由textconv生成的差異不適合應(yīng)用。出于這個原因,只有 git diff 和 git log 命令系列(即 log,whatchanged,show)才會執(zhí)行文本轉(zhuǎn)換。git format-patch 永遠(yuǎn)不會生成這個輸出。如果你想向某人發(fā)送一個二進(jìn)制文件的文本轉(zhuǎn)換差異(例如,因為它能夠快速傳達(dá)你所做的改變),你應(yīng)該單獨(dú)生成它并作為注釋發(fā)送,除了你可能會使用的通常的二進(jìn)制差異發(fā)送。 |
---|
由于文本轉(zhuǎn)換速度較慢,特別是在進(jìn)行大量文本轉(zhuǎn)換時git log -p
,Git 提供了一種緩存輸出并在未來差異中使用它的機(jī)制。要啟用緩存,請在 diff 驅(qū)動程序的配置中設(shè)置“cachetextconv”變量。例如:
[diff "jpg"] textconv = exif cachetextconv = true
這將無限期地緩存每個 blob 上運(yùn)行“exif”的結(jié)果。如果您更改 diff 驅(qū)動程序的 textconv 配置變量,Git 將自動使緩存項無效并重新運(yùn)行 textconv 過濾器。如果您想手動使緩存失效(例如,因為您的“exif”版本已更新,現(xiàn)在可以產(chǎn)生更好的輸出),您可以手動刪除緩存git update-ref -d refs/notes/textconv/jpg
(其中“jpg”是 diff 驅(qū)動程序的名稱,如上面的例子)。
如果要顯示存儲庫中二進(jìn)制或特殊格式的斑點(diǎn)之間的差異,可以選擇使用外部 diff 命令,或使用 textconv 將它們轉(zhuǎn)換為可區(qū)分的文本格式。您選擇哪種方法取決于您的具體情況。
使用外部 diff 命令的優(yōu)點(diǎn)是靈活性。您不一定會發(fā)現(xiàn)面向行的更改,也不一定需要輸出類似統(tǒng)一差異。您可以自由地以最適合您數(shù)據(jù)格式的方式查找和報告更改。
相比之下,textconv 更受限制。您將數(shù)據(jù)轉(zhuǎn)換為面向行的文本格式,Git 使用其常規(guī)差異工具生成輸出。選擇此方法有幾個優(yōu)點(diǎn):
使用方便。編寫二進(jìn)制文本轉(zhuǎn)換通常要比執(zhí)行自己的diff更簡單。在很多情況下,現(xiàn)有的程序可以用作 textconv 過濾器(例如,exif,odt2txt)。
Git diff 功能。通過自己執(zhí)行轉(zhuǎn)換步驟,您仍然可以使用許多Git的差異功能,包括著色,文字差異和組合差異進(jìn)行合并。
緩存。Textconv 緩存可以加速重復(fù)的差異,比如可能通過運(yùn)行git log -p
觸發(fā)的差異。
Git 通常會通過檢查內(nèi)容的開始來正確猜測 blob 是否包含文本或二進(jìn)制數(shù)據(jù)。但是,有時您可能想要覆蓋其決定,要么是因為 blob 稍后在文件中包含二進(jìn)制數(shù)據(jù),要么是因為在技術(shù)上由文本字符組成的內(nèi)容對于人類讀者而言是不透明的。例如,許多 postscript 文件只包含 ASCII 字符,但會產(chǎn)生嘈雜和無意義的差異。
將文件標(biāo)記為二進(jìn)制文件的最簡單方法是在文件中取消設(shè)置 diff 屬性.gitattributes
:
*.ps -diff
這將導(dǎo)致 Git 生成Binary files differ
(或二進(jìn)制補(bǔ)丁,如果啟用二進(jìn)制補(bǔ)丁)而不是常規(guī)差異。
但是,也可能需要指定其他diff驅(qū)動程序?qū)傩?。例如,您可能希望使?code>textconv將 postscript 文件轉(zhuǎn)換為 ASCII 表示以供人類查看,否則將它們視為二進(jìn)制文件。您不能指定兩者-diff
和diff=ps
屬性。解決方案是使用diff.*.binary
配置選項:
[diff "ps"] textconv = ps2ascii binary = true
merge
該屬性merge
影響如何在文件級合并過程git merge
中合并文件的三個版本,以及其他命令(如git revert
和git cherry-pick
)。
Set
內(nèi)置3路合并驅(qū)動程序用于以類似于套件merge
命令的方式合并內(nèi)容RCS
。這適用于普通的文本文件。
Unset
以當(dāng)前分支的版本作為暫定合并結(jié)果,并聲明合并有沖突。這適用于沒有明確定義的合并語義的二進(jìn)制文件。
Unspecified
默認(rèn)情況下,它使用與merge
設(shè)置屬性時相同的內(nèi)置3路合并驅(qū)動程序。但是,merge.default
配置變量可以將不同的合并驅(qū)動程序命名為與未指定merge
屬性的路徑一起使用。
String (字符串)
使用指定的自定義合并驅(qū)動程序執(zhí)行3路合并。內(nèi)置的3路合并驅(qū)動程序可以通過詢問“文本”驅(qū)動程序來明確指定; 內(nèi)置的“取當(dāng)前分支”驅(qū)動程序可以用“二進(jìn)制”來請求。
有幾個內(nèi)置的低級合并驅(qū)動程序可以通過merge
屬性進(jìn)行定義。
text
文本文件的常用3路文件級別合并。沖突地區(qū)標(biāo)有沖突標(biāo)記<<<<<<<
,=======
并且>>>>>>>
。分支中的版本出現(xiàn)在=======
標(biāo)記之前,并且合并分支中的版本出現(xiàn)在=======
標(biāo)記之后。
二進(jìn)制
將分支的版本保留在工作樹中,但讓路徑處于沖突狀態(tài)以供用戶整理。
聯(lián)合
對文本文件運(yùn)行3路文件級別合并,但從兩個版本中取出一行,而不是留下沖突標(biāo)記。這往往會以隨機(jī)順序在結(jié)果文件中留下添加的行,并且用戶應(yīng)該驗證結(jié)果。如果您不了解其含義,請不要使用它。
合并驅(qū)動程序的定義是在.git/config
文件中完成的,而不是在gitattributes
文件中完成的,所以嚴(yán)格來說,這個手冊頁是一個討論它的錯誤地方。然而...
要定義一個自定義合并驅(qū)動程序filfre
,請向您的$GIT_DIR/config
文件(或$HOME/.gitconfig
文件)添加一個部分,如下所示:
[merge "filfre"] name = feel-free merge driver driver = filfre %O %A %B %L %P recursive = binary
該merge.*.name
變量為驅(qū)動程序提供了一個人類可讀的名稱。
該merge.*.driver
變量的值用于構(gòu)造一個命令來運(yùn)行以合并祖先的版本(%O
),當(dāng)前版本(%A
)和其他分支的版本(%B
)。當(dāng)構(gòu)建命令行時,這三個標(biāo)記被替換為保存這些版本內(nèi)容的臨時文件的名稱。此外,%L將替換為沖突標(biāo)記大?。ㄕ垍㈤喯挛模?/p>
合并驅(qū)動程序預(yù)計會通過覆蓋文件而將合并結(jié)果留在名稱為%A
的文件中,如果設(shè)法將它們完全合并,則以零狀態(tài)退出;如果存在沖突,則退出非零。
該merge.*.recursive
變量指定在共有祖先之間進(jìn)行內(nèi)部合并時調(diào)用合并驅(qū)動程序時要使用的其他合并驅(qū)動程序(當(dāng)存在多個合并驅(qū)動程序時)。如果未指定,則驅(qū)動程序本身用于內(nèi)部合并和最終合并。
合并驅(qū)動程序可以學(xué)習(xí)合并結(jié)果將通過%P
占位符存儲的路徑名。
conflict-marker-size
此屬性控制沖突合并期間工作樹文件中留下的沖突標(biāo)記的長度。只有將值設(shè)置為正整數(shù)才會產(chǎn)生有意義的效果。
例如,.gitattributes
在合并文件Documentation/git-merge.txt
導(dǎo)致沖突時,此行可以用于告訴合并機(jī)制離開更長的時間(而不是通常的7個字符長)的沖突標(biāo)記。
Documentation/git-merge.txt conflict-marker-size=32
whitespace
該core.whitespace
配置變量允許您定義diff
和apply
應(yīng)該考慮項目中的所有路徑空白錯誤(請查看 git-配置[1])。該屬性為您提供了更好的每個路徑控制。
Set
注意 Git 已知的所有類型的潛在空白錯誤。選項卡寬度取自core.whitespace
配置變量的值。
Unset
沒有注意到任何錯誤。
Unspecified
使用core.whitespace
配置變量的值決定要注意的錯誤。
String
使用與core.whitespace
配置變量相同的格式指定逗號分隔的常見空白問題列表。
export-ignore
具有該屬性的文件和目錄export-ignore
不會被添加到存檔文件中。
export-subst
如果該屬性export-subst
是為一個文件設(shè)置的,那么 Git 將在將該文件添加到存檔時展開多個占位符。擴(kuò)展取決于提交 ID 的可用性,也就是說,如果 git-archive [1]被賦予樹而不是提交或標(biāo)簽,則不會執(zhí)行替換。占位符與用于git-log [1]的--pretty=format:
git-log [1] 選項的占位符相同,只不過它們需要像這樣包裝:$Format:PLACEHOLDERS$
在文件中。例如,字符串$Format:%H$
將被提交散列替換。
delta
對于屬性delta
設(shè)置為 false 的路徑,不會嘗試使用塊壓縮增量壓縮。
encoding
這個屬性的值指定了 GUI 工具應(yīng)該使用的字符編碼(例如 gitk [1]和 git-gui [1])來顯示相關(guān)文件的內(nèi)容。請注意,由于性能方面的考慮,gitk [1]不使用此屬性,除非在其選項中手動啟用每個文件的編碼。
如果這個屬性沒有設(shè)置或者有一個無效值,那么gui.encoding
會改用配置變量的值(參見 git-config [1])。
您不希望對任何跟蹤的二進(jìn)制文件應(yīng)用任何行尾轉(zhuǎn)換,也不希望為其生成文本差異。你需要指定例如
*.jpg -text -diff
但是當(dāng)你有很多屬性時,這可能會變得很麻煩。使用宏屬性,可以定義一個屬性,該屬性在設(shè)置時還可以同時設(shè)置或取消設(shè)置多個其他屬性。系統(tǒng)知道一個內(nèi)置的宏屬性,binary
:
*.jpg binary
設(shè)置“binary”屬性也會取消上面的“text”和“diff”屬性。請注意,宏屬性只能是“設(shè)置”,盡管設(shè)置一個屬性可能會影響設(shè)置或取消設(shè)置其他屬性,甚至將其他屬性返回到“未指定”狀態(tài)。
自定義宏屬性只能定義在頂層 gitattributes 文件($GIT_DIR/info/attributes
,該.gitattributes
文件在工作樹的頂層,或者全球或全系統(tǒng) gitattributes 文件),而不是.gitattributes
在工作樹子目錄中的文件。內(nèi)置宏屬性“binary”相當(dāng)于:
[attr]binary -diff -merge -text
如果你有這三個gitattributes
文件:
(in $GIT_DIR/info/attributes) a* foo !bar -baz (in .gitattributes) abc foo bar baz (in t/.gitattributes) ab* merge=filfre abc -foo -bar *.c frotz
給路徑的屬性t/abc
計算如下:
通過檢查t/.gitattributes
(與目標(biāo)路徑在同一目錄中),Git 發(fā)現(xiàn)第一行匹配。merge
屬性設(shè)置。它還認(rèn)為,第二行相匹配,和屬性foo
和bar
都沒有設(shè)置。
然后,它會檢查.gitattributes
(這是在父目錄),并發(fā)現(xiàn)第一個行匹配,但t/.gitattributes
文件已經(jīng)決定如何merge
,foo
和bar
屬性應(yīng)該給予這條道路,所以它的葉子foo
和bar
未設(shè)置。屬性baz
已設(shè)置。
最后它檢查$GIT_DIR/info/attributes
。該文件用于覆蓋樹中設(shè)置。第一行是匹配,并被foo
設(shè)置,bar
被還原為未指定狀態(tài),并且baz
未設(shè)置。
結(jié)果,分配的屬性t/abc
變?yōu)椋?/p>
foo set to true bar unspecified baz set to false merge set to string value "filfre" frotz unspecified