那天在 Windows 做完筆記,準備上傳到 Github Page 時,發現我無法執行 git add .
,並出現了 LF / CRLF 轉換的錯誤訊息 - LF will be replaced by CRLF
,告訴我要把 LF 換行符號轉換成 CRLF。
問題描述與釐清
看到錯誤訊息時,就猜到是因為欲提交的文件中存在 LF 的換行符號,但在 Windows 所使用的換行符號是 CRLF,再加上我有設定 safecrlf 為 true,是不允許提交有 LR 與 CRLF 混合的檔案的,因此 git 直接拒絕我將檔案註冊到索引裡:
1 |
|
不過最讓我疑惑的是,我除了設定 safecrlf 為 true 外,我另外還有設定 autocrlf 為 true。照理來說 git 會在檢出將換行符號換成 CRLF 才對,但為什麼我的文件中還會存在 LR?
1 |
|
解決辦法
為什麼會出現 LR 我還是不得其解,不過對於這條錯誤訊息倒是很好解:
1. 關掉 safecrlf
剛剛提過,由於我將 safecrlf 設為 true,是不允許提交有 LR 與 CRLF 混合的檔案的,所以被 git 給拒絕了。因此網路上一派解法是直接把 safecrlf 關掉。
1 |
|
不過我個人不希望檔案中有 LR 與 CRLF 混合,這在跨平台合作的情況下會是個悲劇…我就被同事坑過…在提交時會滿江紅一片阿(哭
2. 使用指令或編譯器
第二種方法是用指令或編譯器來替換換行符號。先說指令的部分,在使用 Ubuntu 時,若想取代檔案中字元時,我會使用 tr:
1 |
|
這條指令的意思是:「將 input.file 中的 \n\r 字串,轉換成 \r 後,寫到 output.file 去」,在只有一份檔案需要轉換的情況,下這條指令是最迅速的,只是可惜的是…我找不到它在 Dos 中相對應的指令 (好吧!我承認我懶得找)
另一種是使用編譯器,我記得 NodePad++ 做得到,可是我現在改用 VS Code,原本以為更改它的 files:eol 設定就可以了,但 git 還是把我擋下來了 QAQ
3. 此用 DOS2UNIX
沒辦法使好用最後一招了,還好在 Windows 中找的到現成的 dos2unix (a.k.a fromdos) / unix2dos (a.k.a todos) tool。不僅方便,而且這個方法還可以批次處理,當你有多個檔案的時候需要轉換時,用這個方法會比較快。
-
下載 DOS2UNIX and UNIX2DOS for Windows (載點)
-
將解壓縮出來的檔案放到專案根目錄,由於我是要轉 LF 成 CRLF,所以我只將 UNIX2DOS.exe 和 UNIX2DOS.c 兩隻程式搬進去。
- 輸入以下指令,其中 *.md 是所要轉換的檔案路徑。
1
for /f %f IN ( 'dir /b /s *.md' ) DO @unix2dos %f
- 處理完成後,再把剛剛搬進去的 UNIX2DOS.exe 和 UNIX2DOS.c 程式刪除,別不小心放進 git 裡面了。
補充紀錄
1. core.autocrlf
根據 core.autocrlf 的設置規則與建議。
- 當在 Window 系統上開發時
應將 core.autocrlf 設為 true,這樣在提交會將程式碼轉換成 LF,但在檢出則將換行符號換回 CRLF。 - 當在 Linux 或 Mac 系統上開發時
應將 core.autocrlf 設為 input,由於 Linux 與 Mac 本身就是使用 LF,因此檢出不需要進行轉換,但提交時依舊得使用 LF。
- 當專案只會在 Window 系統上開發時
如果你確定你的專案只會在 Window 上開發與執行,這時將 core.autocrlf 設為 false,因此你提交時會是 CRLF。不過個人實在不建議,畢竟你不能確認你的交接者是否還是使用相同的系統開法。
2. core.safecrlf
前面有提過 safecrlf 設定的差別:
1 |
|
不過我想到一件事情 core.autocrlf = true 會將 CRLF 轉成 LF,此時我要提交時 git 中應該都是 LF 才對,應該不是混合的檔案了,那為何又會被 safecrlf 擋下來呢?
後來在Seven是為了紀念賽虎的這篇查到解釋:
當 core.autocrlf 為 true 或者 input 時,算激活了 eol,此時如果 core.safecrlf 為 true,git 檢查 crlf 轉換是否正常,比如 Windows 平台,core.autocrlf 設置為 true,如果工作區的文件中含有 LF,git 就會拒絕,因為 true的情況下,git 認為工作區應該都是 CRLF 才對啊。
總結
簡單來說,若在 window 環境建議設置
1 |
|
反之,Linux 或 Mac 建議設置
1 |
|
若遇到 fatal:LF would be replaced by CRLF
或 fatal:CRLF would be replaced by LF
直接按照錯誤訊息要求,將檔案中錯誤的換行符號替換掉。
參考資料
- 通过阅读git-config文档理解Git如何使用autocrlf、safecrlf、eol和.gitattributes处理line-ending|简书
- Git 解決出現 warning: LF will be replaced by CRLF … The file will have its original line endings in your working directory.|關於網路那些事…
- 使用 Git ADD 指令出現錯誤|Yowko’s Notes
- HowTo: UNIX / Linux Convert DOS Newlines CR-LF to Unix/Linux Format|nixCraft