原因:
在各操作系統(tǒng)下嗅绰,文本文件所使用的換行符是不一樣的。UNIX/Linux 使用的是?0x0A(LF)向族,早期的 Mac OS 使用的是0x0D(CR)呵燕,后來的 OS X 在更換內(nèi)核后與 UNIX 保持一致了。但 DOS/Windows 一直使用?0x0D0A(CRLF)作為換行符炸枣。
這種不統(tǒng)一確實對跨平臺的文件交換帶來麻煩。雖然靠譜的文本編輯器和 IDE 都支持這幾種換行符弄唧,但文件在保存時總要有一個固定的標(biāo)準(zhǔn)啊适肠,比如跨平臺協(xié)作的項目源碼,到底保存為哪種風(fēng)格的換行符呢候引?
Git 作為一個源碼版本控制系統(tǒng)侯养,對這個問題提供了一個“解決方案”。Git 由大名鼎鼎的 Linus 開發(fā)澄干,最初只可運行于 *nix 系統(tǒng)逛揩,因此推薦只將 UNIX 風(fēng)格的換行符保存入庫柠傍。但它也考慮到跨平臺協(xié)作的場景,并且提供了一個“換行符自動轉(zhuǎn)換”功能辩稽。
這個功能默認(rèn)處于“自動模式”惧笛,當(dāng)你在簽出文件時,它試圖將 UNIX 換行符(LF)替換為 Windows 的換行符(CRLF)逞泄;當(dāng)你在提交文件時患整,它又試圖將 CRLF 替換為 LF。
Git:
Git 的“換行符自動轉(zhuǎn)換”功能聽起來似乎很智能喷众、很貼心各谚,因為它試圖一方面保持倉庫內(nèi)文件的一致性(UNIX 風(fēng)格),一方面又保證本地文件的兼容性(Windows 風(fēng)格)到千。但遺憾的是昌渤,這個功能是有 bug 的,而且在短期內(nèi)都不太可能會修正憔四。
問題具體表現(xiàn)在膀息,如果你手頭的這個文件是一個包含中文字符的 UTF-8 文件,那么這個“換行符自動轉(zhuǎn)換”功能 在提交時是不工作的(但簽出時的轉(zhuǎn)換處理沒有問題)加矛。我猜測可能這個功能模塊在處理中文字符 + CRLF 這對組合時直接崩潰返回了履婉。
示例:
你在 Windows 下用默認(rèn)狀態(tài)的 Git 簽出一個文件,寫了一行中文注釋(或者這個文件本來就包含中文)斟览,然后存盤提交……不經(jīng)意間毁腿,你的文件就被毀掉了。
問題分析:
因為你提交到倉庫的文件已經(jīng)完全變成了 Windows 風(fēng)格(簽出時把 UNIX 風(fēng)格轉(zhuǎn)成了 Windows 風(fēng)格但提交時并沒有轉(zhuǎn)換)苛茂,每一行都有修改(參見本文開頭的示意圖)已烤,而這個修改又不可見(大多數(shù) diff 工具很難清楚地顯示出換行符),這最終導(dǎo)致誰也看不出你這次提交到底修改了什么妓羊。
參考文檔:https://help.github.com/articles/dealing-with-line-endings/#platform-all