1 背景
遠端檔案拉取到本地後,會根據本地機器的作業系統、或檔案編輯器,修改檔案內容的行尾。例如遠端程式碼為適配其程式碼託管的宿主、儲存伺服器與編譯構建環境,通常採用 LF 作為行尾,符合 Linux 檔案系統習慣。而本地為 Windows 的機器則應在獲取檔案後將行尾從 LF 轉換為 CRLF,適配 Windows 檔案系統習慣。在本地做完檔案修改進行提交,並準備推送回遠端,行尾則應從 CRLF 轉換回 LF。而本地為 Linux 的機器則無需對行尾做任何轉換,始終以 LF 為行尾。
如何使檔案的行尾在合適的環境使用合適的格式
- 避免不合適的格式出現在遠端,如以 CRLF 行尾的檔案推送至伺服器。
- 避免行尾因本地環境的不同,而無法達成統一,在遠端被反覆來回修改。
- 避免行尾的適配轉換被識別為常規的變更,影響其他檔案內容變更的跟蹤。
- 避免檔案行尾格式不正確導致無法在特定系統中被執行,如 *.bat 需要 CRLF 行尾在 Windows 中執行,*.sh 需要 LF 行尾在 Linux 中執行。
這就需要能夠自動進行行尾設定的工具來幫忙。恰巧 git / git for windows 內建提供此類設定功能。
2 行尾設定
2.1 通用
在倉庫的根目錄下使用 .gitattributes
檔案設定行尾,此設定將直接影響遠端對於檔案行尾的應用,從而全域性的影響所有從遠端拉取檔案到本地的開發人員。此處需要單獨為 *.bat 和 *.sh 設定其在遠端儲存時所用的行尾,因為這兩類檔案的行尾設定會直接影響檔案是否能夠執行,其他檔案則不受影響,如 *.cs 即使使用 LF 行尾仍然能夠正常的編譯構建。
* text=auto
*.bat text eol=crlf
*.sh text eol=lf
2.2 本地機器為 Windows
每位開發者的本地環境,透過 .gitconfig
檔案設定行尾,僅影響的是本地開發環境,需要每位開發者自行配置。可能有其他更為優秀、妥當且不算複雜的方案,可以避免要求每位開發者配置本地環境,但目前對於 Windows 開發者來說,配置本地環境還是最為簡單有效的方案。
[core]
autocrlf = true
eol = lf
之所以需要設定 core.autocrlf=true
,是因為對於 Windows 使用者而言,無論檔案建立時是 LF 還是 CRLF,都希望拉取到本地時檔案能夠適配 Windows 而將 LF 的檔案自動轉換為 CRLF,當然 *.sh 檔案除外。
- 而不設定
core.autocrlf
將影響- 檔案行尾及檔案的一致性,導致本地變更和工作樹、和索引比較時,出現行尾的變更
- 無法保障檔案可執行性
- 無法保障檔案在本地 Windows 和遠端 Linux 能夠正常讀寫,編輯時可能會有編碼問題,出現亂碼
- 或設定
core.autocrlf=input
所表達的和* text=auto
理論一致,其會在推送遠端時將行尾轉換為 LF,從遠端拉取到本地時會保持檔案建立時的原始行尾。造成本身就是 LF 行尾的檔案在本地仍然是 LF,不會轉換為 CRLF,影響檔案在 Windows 系統中的編輯。
之所以要設定 core.eol=lf
,是為了保障倉庫內的行尾一致使用 LF,而不是某些檔案 LF,某些 CRLF,某些混合。
2.3 本地機器為 Linux / OS X
無需進行 Windows 中所作的配置。
2.4 檢視當前本地工作樹內檔案的行尾
# 檢視所有檔案
git ls-files --eol
# 查詢檔案行尾中有混合了 LF 和 CRLF 的檔案
git ls-files --eol | findstr mixed
git ls-files --eol | grep mixed
# i 表示 index,可以視作遠端行尾
# w 表示 working tree,可以視作本地行尾
### 行尾可能的值有 lf、crlf、mixed,mixed 表示一個檔案中行尾既有 lf 又有 crlf,應避免 ###
# attr 表示 .gitattributes 中的行尾設定
# 最後一列是檔名稱,即當前執行 git ls-files 指令所在目錄下的相對路徑
i/lf w/crlf attr/text=auto .gitattributes
3 行為表現
當正確進行了行尾設定後
- 檔案拉取到本地做了行尾轉換後,git 並不會認為檔案產生了變更,在 git 變更中不會出現新的變更記錄。
- 對於做出常規變更的檔案,git 在將檔案與未修改的版本進行比較時,會將本地檔案的行尾自動轉換為遠端所設定的行尾再進行比對,不會將行尾的變更納入為實際的變更中來。
行尾的變化對使用者來說將變得無感。
4 其他注意事項
單獨在 .editorconfig
設定,如所有檔案型別或 *.cs 檔案型別設定行尾為 CRLF,並不能夠影響 git 的行為,仍然無法避免 git 將行尾修改識別為常規變更,並且導致 CRLF 行尾的檔案被推送到遠端,在遠端也能夠看到行尾的變更。該設定僅能夠為 IDE 如 VS 將在儲存檔案時檢查行尾,將行尾不是 CRLF 的設定為 CRLF。