Git 行尾轉換

最後更新: 2026-04-29 00:23:56 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

Git 可以在儲存庫邊界將文字正規化為 LF,同時在工作目錄中呈現 LF 或 CRLF。穩定的 .gitattributes 政策可避免受平台影響的提交,並讓編輯器 只負責簽出後的形式。

區分 HEAD、索引與工作目錄的位元組 #

一個受追蹤路徑有三種相關的表示形式:

  1. HEAD 指向目前提交所儲存的 blob。
  2. 索引保存預計納入下一次提交的 blob。
  3. 工作目錄保存供編輯器和建置工具使用的位元組。

對於經過正規化的文字,git add 會執行從 CRLF 到 LF 的清理轉換。 簽出則會執行塗抹轉換,將索引中的 LF 轉成所選的工作目錄行尾。 既有提交不會被重寫。

sh
git ls-files --eol -- path/to/file
git show HEAD:path/to/file | od -An -t x1
git check-attr -a -- path/to/file

git ls-files --eol 會回報索引、工作目錄及實際套用的屬性形式。 在處理轉換警告前,請先檢查這些形式。

使用 .gitattributes 宣告儲存庫政策 #

請提交屬性設定,因為如此每個複製出的儲存庫都會共用該政策:

gitattributes
*       text=auto
*.sh    text eol=lf
*.py    text eol=lf
*.bat   text eol=crlf
*.png   binary
*.pdf   binary

text=auto 讓 Git 對未指定的路徑進行分類。text 強制正規化; -text 停用正規化;binary 則是 -diff -merge -text 的內建屬性巨集。 明確指定 eol=lf 或 eol=crlf 會將路徑標記為文字,並控制其簽出形式。 請將封存檔、影像、產生的二進位格式和已簽署成品標記為非文字,因為轉換會 改變其位元組。

僅將設定作為後備方案 #

當路徑的屬性未做出更明確的決定時,core.autocrlf 和 core.eol 才會 影響該路徑:

core.autocrlf清理至索引從索引簽出
false不進行 autocrlf 轉換不進行 autocrlf 轉換
inputCRLF 轉為 LFLF 維持 LF
trueCRLF 轉為 LFLF 轉為 CRLF

core.eol 可為正規化文字選擇 lf、crlf 或 native,但具有明確 eol 屬性的文字除外。core.safecrlf=true 會拒絕不可逆的轉換;warn 則會回報 這類轉換。這兩項設定都無法取代已提交的屬性政策。

sh
git config --show-origin --get core.autocrlf
git config --show-origin --get core.eol
git config --show-origin --get core.safecrlf

安全地重新正規化 #

新增或修正屬性後,請從乾淨的工作目錄開始,或先保留尚未提交的工作。 接著刻意暫存正規化變更並加以檢查:

sh
git add --renormalize .
git diff --cached --check
git diff --cached

請將行尾正規化與語意變更分開提交,因為獨立提交可以維持程式碼審查、 blame 和回復操作的品質。該操作會更新索引;不會變更被忽略或未追蹤的檔案。

請讓編輯器設定符合簽出政策,尤其是強制使用 CRLF 的檔案。編輯器設定會 影響工作目錄中的位元組,而 .gitattributes 則定義版本控制的邊界。 不要為了實驗而反覆加入和簽出尚未提交的重要檔案;請先檢查實際套用的屬性 並儲存工作。

評論

在 GitHub 上閱讀或評論(發表評論需要登入)