前些天有位小夥伴告訴我說 git 改了某個重要文件的換行符,導致文件的哈希變了,於是文件校驗出現錯誤。之前一直沒問題而最近纔有問題是因爲最近換了部署服務器,git 的換行符配置不一樣。
其實,我們不應該讓代碼倉庫如此容易受到外界環境的影響。所以本文會解釋 git 的全局配置如何影響了 git 對換行符的處理,然後說說如何徹底解決這個問題。
關於換行符
- \r = CR = Carriage-Return = 回車
- \n = LF = Line-Feed = 換行
- \r\n = CRLF = Carriage-Return Line-Feed = 回車換行
Windows 下默認的文本換行符是 \r\n
,Linux 下默認的換行符是 \n
,Mac 下默認的換行符是 \r
。因爲這些差異,如果某部分文本文件會跨操作系統處理,那麼換行符的處理就必須考慮了。git 允許開發者設置如何處理換行符在跨平臺上的處理方式,不過不合適的設置可能帶來文件發生不期望的修改。
問題
問題本身在本文一開始已經說得比較清楚了,現在疏理一下:
- 有個文本文件,被 git 改了換行符,導致哈希變化,文件校驗出現了錯誤;
- 部署服務器以前 git 全局配置和現在不同,所以以前沒問題,現在出了問題。
解決
當時,林德熙 小夥伴是負責部署服務器配置的,看到出事了立刻想到去服務器把配置改“正確”。
然而我阻止了。因爲現在因爲換服務器出問題,將來也會因爲換服務器出問題,更普遍的,換任何環境都可能出問題。所以這問題應該從倉庫着手,避免此文件被修改換行符。
於是我和小夥伴結對打開了 .gitattribute 文件,在末尾加了一行:
*.bmp binary
*.jpg binary
++ *.inf binary
這樣,*.inf 文件會被 git 視爲二進制文件,也就不會處理換行符了。
當然,因爲項目很小,所以直接改了位於項目根目錄的 .gitattribute 文件。如果項目比較大,那麼建議考慮在那個 .inf 文件所在的文件夾新建一個 .gitignore 文件,避免全局的設置對可能不需要生效的文件也起了作用。
原因
git 有個全局配置,在 %USERPROFILE%\.gitconfig
文件裏面,可以指定如何處理文本文件的換行符:
[core]
autocrlf = true
有三個可選值:
- true
- false
- input
在 Windows 系統上:
true
表示在推送時轉成\n
,在拉取時轉成\r\n
。這樣的設置讓 Windows 的開發者能兼容很多的開發工具(比如早期的記事本,新的已經支持\r\n
了),不至於遇到很多換行符問題。false
表示在推送時和拉取時都原樣保留換行符。這樣的設置在所有程序員都在同一個平臺開發時很有用,git 完全不處理換行符,全部改由開發者自行解決。input
表示在推送時轉成\n
,在拉取時原樣保留換行符。注意到,這樣的設置會讓倉庫裏所有的換行符都變成\n
不再有什麼時候有\r\n
了,所以對 Windows 平臺的開發者並不友好。
以前的服務器全局配置沒有問題,是因爲服務器配置爲 true
,於是拉下來時一定都是 \r\n
哈希正確。而現在全局配置是 false
,於是會原樣把 git 倉庫裏的拉下來,哈希錯誤。
是的,你沒看錯!遠程 git 倉庫裏的是錯的!這是因爲有小夥伴使用了 true
或者 input
的配置,導致推送時統一把換行符改成了 \r\n
。
我的博客會首發於 https://blog.walterlv.com/,而 CSDN 會從其中精選發佈,但是一旦發佈了就很少更新。
如果在博客看到有任何不懂的內容,歡迎交流。我搭建了 dotnet 職業技術學院 歡迎大家加入。
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名呂毅(包含鏈接:https://walterlv.blog.csdn.net/),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我聯繫。