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