git 的隱藏文件 .gitattributes
本文以 Spring 在 github 中的代碼爲例,介紹 git 的幾個隱藏文件的作用、寫法、含義。
文章目錄
.gitattributes
介紹
.gitattributes 是一個文本文件,文件中的一行定義一個路徑的若干個屬性,主要用於定義每種文件的屬性,以方便 git
幫我們統一管理。
- .gitattributes 文件格式如下
要匹配的文件模式 屬性1 屬性2 ...
在.gitattributes
文件的一行中,一個屬性(以text屬性爲例)可能有4種狀態:
- 設置text
- 不設置-text
- 設置值text=string
- 未聲明,通常不出現該屬性即可;但是爲了覆蓋其他文件中的聲明,也可以!text
.gitattributes 文件中可以定義的屬性
text
用於控制行尾的規範性。如果一個文本文件是規範的,則Git庫彙總該文件(git 服務器上的文件)的行尾總是LF
。對於工作目錄,除了text屬性之外,還可以設置eol屬性或core.eol配置變量。
eol
設置行末字符。
- eol=lf ,[回車] :入庫時將行尾規範爲LF,檢出時行尾不強制轉換爲 CRLF
- eol=crlf,[換行、回車] :入庫時將行尾規範爲LF,檢出時將行尾轉換爲CRLF
補充:
CRLF
和LF
GRLF
和LF
都是用來表示文本換行的方式。CR代表回車,對應字符\r
。LF
表示換行,對應字符\n
。不同操作系統文本使用的換行符各不相同。Windows系統使用的是CRLF
,Unix系統(包括Linux,MacOS近些年的版本)使用的是LF
。
補充:爲什麼需要去關心行尾是什麼
事實上,可能並不是所有的開發者用的環境都完全一樣,比如有的開發者使用 Windows 環境開發,他們的文本文件的換行符是 ‘\r\n’(CRLF);而有的開發者使用 MacOS 環境開發,這些開發者文本文件的換行符是 ‘\n’(LF)。爲了使得不同系統環境的開發者能開發同一個git項目,便出現了這個。
diff
我們知道 git 主要是用來跟蹤文件版本的,跟蹤文件版本自然離不開比較差異,而diff
就是用來告訴 git 聲明文件需要比較版本差異的。
diff屬性影響Git對特殊文件生成差異的方式。它可以告訴Git是否爲路徑生成文本補丁還是將路徑視爲二進制文件。它也可以影響在hunk頭部顯示的@@ -k,l +n,m @@,告訴Git使用外部命令來生成差異,或者是在生成差異之前讓Git將二進制文件轉換爲文本文件。
-
diff
強制視爲文本文件,即使它包含一些通常從不會出現在文本文件的字節值,例如NUL
。 -
!diff
表示爲非文本文件,沒有設置diff屬性的路徑會生成differ二進制文件(如果啓用了二進制補丁,會生成二進制補丁)。 -
未定義
未指明diff屬性的路徑首先會檢查其內容,如果它看起來像文本文件並且小於大文件閾值(core.bigFileThreshold
),則將其視爲文本文件,否則將生成differ二進制文件。
core.bigFileThreshold:所有平臺上的默認值爲512MiB。大於此大小的文件將被縮減,而不會嘗試增量壓縮。
differ 規則
diff
是使用指定的 diff
驅動程序顯示的。每個驅動程序可以指定一個或多個選項。
- 如何自定義一個外部的diff驅動程序?
diff驅動程序的定義是在gitconfig
中完成的,並不是在gitattributes文件中,所以嚴格來說,這裏並不適合談論它。
.gitattributes
示例
以兩個例子快速熟悉.gitattributes
文件
示例1
以下是 Spring 倉庫的 .gitattributes
文件
# Declare files that will always have LF line endings on checkout.
*.cpp text eol=lf
*.h text eol=lf
*.c text eol=lf
*.hpp text eol=lf
*.cmake text eol=lf
*.sh text eol=lf
*.py text eol=lf
可以看到 Spring 倉庫的 .gitattributes
文件中定義了幾種不同語言源碼文件的行尾換行符(eol
的含義是 End Of Line,即行尾的意思),表示git命令操作的這幾類文件都需要以。
示例2
下面以一個更詳細的規則來介紹
* text=auto
# 文件的行尾自動轉換。如果是文本文件,則在文件入Git庫時,行尾自動轉換爲LF。如果已經在入Git庫中的文件的行尾是GRLF,則文件在入Git庫時,不再轉換爲LF。
*.txt text
# 對於.txt文件,標記爲文本文件,並進行行尾規範化。
*.jpg -text
# 對於`.jpg`文件,標記爲非文本文件
*.vcproj text eol=crlf
# 對於.vcproj文件,標記爲文本文件,在文件入Git庫時進行規範化,行尾轉換爲LF。在檢測到出工作目錄時,行尾自動轉換爲GRLF。
*.sh text eol=lf
# 對於sh文件,標記爲文本文件,在文件入Git庫時進行規範化,即行尾爲LF。在檢出到工作目錄時,行尾也不會轉換爲CRLF(即保持LF)。
*.py eol=lf
# 對於py文件,只針對工作目錄中的文件,行尾爲LF。
.gitattributes
生效順序
在一個Git庫中可以有多個.gitattributes
文件,不同.gitattributes
文件中,屬性設置的優先級(從高到低)如下:
/myproj/info/attributes
文件/myproj/my_path/.gitattributes
文件/myproj/.gitattributes
文件- 同一個
.gitattributes
文件中,遵循覆蓋原則,即後面的行會覆蓋前面的設置,如果一個文件的某個屬性被多次設置,則後設置的優先,類似int a = 1; a = 2;
最終結果a == 2
。
使用
爲新的Git庫設置統一的.gitattributes文件:
- 在倉庫的根目錄下創建名爲 .gitattributes 的文件。
touch .gitattributes
vi .gitattributes
- 編輯這個文件並輸入希望的設置,demo 如下:
*.sh text eol=lf
- 把該文件提交併推送到服務器上。
git add .
git commit -m "add.gitattributes"
git push
爲已有Git庫設置統一的.gitattributes文件(重置 GitAttributes):
在上一步的基礎上(確保倉庫根目錄下已經存在.gitattributes
文件)
git rm --cached -r
git reset --hard
上面的命令就會根據文件 .gitattributes 中的定義,更新文件的結尾行。
任何變更都會自動使用指定文件的文件結尾行格式。
下一步,可以通知團隊成員或者協作者去執行 Git 屬性重置的命令即可。
爲所有Git庫設置統一的.gitattributes文件:
git config --get core.attributesFile
git config --global --get core.attributesFile