git 多平臺統一換行符

DaleZhang發表於2018-04-14

最近工作使用 sourceTree 的時候經常發現,儘管只是很小的程式碼改動,但是在檔案 diff 的區域莫名的多了很多空格,即使選擇忽略空格,一項項提交仍有很大機率報錯,很是煩惱。最初的想法是通過指令碼去除掉空格,但經過一番努力依然沒有徹底解決問題。

偶然的,通過對同事提交的檔案使用命令列執行diff的時候,發現存在大量的 ^M 符號,考慮到同事使用的是 windows 系統,終於意識到很有可能是換行符的問題。經過排查終於發現在 sublime 中設定了 line Endings 為 windows (CRLF),而作為主力開發的 IDEA 設定為 LF。最終導致了專案換行符混亂。剩餘內容為著力於解決問題。

背景

首先在不同作業系統中,換行符並不統一,Linux 系統中使用 0x0A(LF), windows 系統中使用 0x0D0A(CRLF), 而 MAC OS 系統起初使用0x0D(CR) 後來和 Linux 系統保持一致。而 git 預設採用 Linux 的換行符(當然這一點並不奇怪)。

git 為了解決不同平臺換行符不一致的問題,在 windows 作業系統中預設在檢出程式碼時將 LF 轉換為 CRLF,而在提交的時候再轉換為 LF,但是看似完美的解決方案在中文環境中卻失效了。

解決方案

設定 git 全域性引數

git 中有三個引數於換行符有關:

  • eol: 設定工作目錄中檔案的換行符,有三個值 lf, crlf 和 native(預設,同作業系統)
  • autocrlf:
    • true 表示檢出是轉換CRLF, 提交時轉換為 LF
    • input 表示檢出是不轉換,提交時轉換為 LF
    • false 表示不做轉換
  • safecrlf:
    • true 表示不允許提交時包含不同換行符
    • warn 則只在有不同換行符時警告
    • false 則允許提價時有不同換行符存在

配置方法:

<!--統一換行符為 lf-->
git config --global core.eol lf
<!--將自動轉換關閉,避免轉換失敗不能不同進行提交-->
git config --global core.autocrlf false
<!--禁止混用 lf 和 crlf 兩種換行符-->
git config --global core.safecrlf true
複製程式碼

增加配置檔案 .gitattributes

雖然通過設定了 git 全域性引數解決了問題,但是作為團隊協作的話,並不能保證所有人都正確配好了。git 提供了.gitattributes檔案解決了這個問題。在專案根目錄新建.gitattributes檔案,新增一下內容:

# Set the default behavior, in case people don't have core.autocrlf set.
* text eol=lf
複製程式碼

通過這種方式避免有人沒有設定 core.autocrlf 引數,並且將該檔案加入版本控制中。

另外根據需要 .gitattributes 檔案可以在專案不同目錄中建立,而一些非文字檔案可以設定為二進位制檔案,不用考慮換行符問題。

專案已有內容轉換換行符

對於專案已有內容如何進行轉換呢,推薦使用dos2unix工具,在mac中可以很方便的使用brew安裝,而windows系統中git bash也自帶了該工具。 以轉換專案中 java 原始碼為例:

cd <project_path>
find . -type file -name '*.java' -exec dos2unix {} +
複製程式碼

最後使用編輯器的時候也確保換行符設定正確

相關文章