.gitattributes 作用詳細講解(git大佬必會技能)

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

補充:CRLFLF
GRLFLF都是用來表示文本換行的方式。CR代表回車,對應字符 \rLF 表示換行,對應字符 \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

參考:https://git-scm.com/docs/gitattributes

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章