git換行符問題

1.問題描述:windows平臺下使用git add,git deploy 文件時經常出現“warning: LF will be replaced by CRLF” 的提示
2.註解:

(1)換行符‘\n’和回車符‘\r’

在計算機還沒有出現之前,有一種叫做電傳打字機(Teletype Model 33)的玩意,每秒鐘可以打10個字符。但是它有一個問題,就是打完一行換行的時候,要用去0.2秒,正好可以打兩個字符。要是在這0.2秒裏面,又有新的字符傳過來,那麼這個字符將丟失。

於是,研製人員想了個辦法解決這個問題,就是在每行後面加兩個表示結束的字符。一個叫做“回車”,告訴打字機把打印頭定位在左邊界;另一個叫做“換行”,告訴打字機把紙向下移一行。

(A)回車符就是回到一行的開頭,用符號r表示,十進制ASCII代碼是13,十六進制代碼爲0x0D,回車(return);

(B)換行符就是另起一行,用n符號表示,ASCII代碼是10,十六製爲0x0A, 換行(newline)。

(2)LF和CRLF區別

LF: Line Feed換行

feed v.餵養,供給;將(信息)輸入 line feed直譯是”將行輸入”,再意譯”換行”

CRLF: Carriage Return Line Feed 回車換行

Carriage n.馬車,火車車廂;運輸費用 在carriage return中,carriage譯爲“車”,return譯爲“回”

在過去的機械打字機上有個部件叫「字車」(Typewriter carriage),每打一個字符,字車前進一格,打完一行後,我們需要讓字車回到起始位置,而“Carriage Return”鍵最早就是這個作用,因此被直接翻譯爲「回車」。儘管後來回車鍵的作用已經不止” 倒回字車”那麼簡單,但這個譯名一直被保留下來。

3.分析問題

這句警告出現的原因:我們在Windows平臺下git add任意Windows平臺編輯過的代碼文本的換行默認都是CRLF,所以一般git add不會出錯。但是如果如下的(i)或者(ii)發生了,那我們再進行git add這個LF換行的文件時,會出現這個警告" LF will be replaced by CRLF in …"。

(i)我們的團隊成員是Linux/Mac平臺並參與了項目的git提交

(ii)我們Windows平臺的某些軟件會生成換行是LF的代碼文本(如李俊德git add的是Webstorm生成的HTML項目中隱藏文件夾.idea中的workspace.xml,這個xml文件換行是LF)

(1)不同操作系統下,處理行尾結束符的方法是不同的:

(A)Windows和Dos下:使用回車(CR)和換行(LF)兩個字符來結束一行,回車+換行(CR+LF),即“\r\n”;

(B)Unix和mac下:只使用換行(LF)一個字符來結束一行,即“\n”;

(最早Mac每行結尾是回車CR 即’\r’,後mac os x 也投奔了 unix)

(2)Git下處理“換行”(line ending)

core.autocrlf是git中負責處理line ending的變量,可以設置3個值:true,false,input。

(A)設置爲true【config --global core.autocrlf true】

當設置成true時,這意味着你在任何時候添加(add)文件到git倉庫時,git都會視爲它是一個文本文件(text file)。

它將把crlf變成LF。

(B)設置爲false【config --global core.autocrlf false】

當設置成false時,line endings將不做轉換操作。文本文件保持原來的樣子。

©設置爲input時,添加文件git倉庫時,git把crlf編程lf。當有人Check代碼時還是lf方式。因此在window操作系統下,不要使用這個設置。

4.此問題的負面影響

格式化與多餘的空白字符,特別是在跨平臺情況下,有時候是一個令人髮指的問題。由於編輯器的不同或者文件行尾的換行符在 Windows 下被替換了,一些細微的空格變化會不經意地混入提交,造成麻煩。雖然這是小問題,但會極大地擾亂跨平臺協作。

假如你正在Windows上寫程序;又或者你正在和其他人合作,他們在Windows上編程,而你卻在其他系統上,在這些情況下,你可能會遇到行尾結束符問題。此問題的全部負面影響如下:

(1)一個直接後果是,Unix/Mac系統下的一個“多行文本”文件在Windows裏打開的話,“多行文本”會變成“一行”。(原因:Unix/Mac換行只用了換行符‘\n’,而Windows的換行要求是回車換行符’\r\n’,因此Unix/Mac中的“多行文本”的換行不符合Windows的規則,所以Windows對這些不符合換行規則的“多行文本”全部按照“沒有換行”處理,所以導致“多行文本”會變成“一行”)

(2)而Windows裏的文件在Unix/Mac下打開的話,在每行的結尾可能會多出一個^M符號。

(3)Linux保存的文件在windows上用記事本看的話會出現黑點。

5.解決此問題的方案

(1)如果我們目前是Window平臺並出現該警告,啥也別做就行,雖然這個警告難看,但這個警告能保證我們項目團隊正常跨系統git操作代碼

因爲git的Windows 客戶端基本都會默認設置 core.autocrlf=true(我們可通過git config core.autocrlf命令查詢我們的Windows上該屬性是否默認true。如不是true,通過config --global core.autocrlf true命令設置該屬性爲true),而“core.autocrlf=true”有以下3個功能來避免我們出錯:

(A)在“把 modified修改過的文件git add到暫存區stage”時,Git自動把LF轉換成CRLF,並給出那條警告”LF will be replaced by CRLF”

(B)在“把modified修改過的文件由暫存區(stage) 提交(commit)到版本庫/倉庫(repository)”時,Git自動把CRLF轉換成LF

©在“用 檢出/git checkout切換到指定分支 或 git clone克隆遠程版本庫”來加載代碼時,Git自動把LF轉換成CRLF

提到的那句警告:“IF will be replaced by CRLF in ”

這句警告的下面其實還有一句很重要的話:The file will have its original line endings in your working directory.

(翻譯:“在工作區裏,這個文件會保留它原本的換行符”)

(2)如果我們是Linux 或 Mac平臺,我們不需要5(1)©的功能“在檢出或克隆遠程版本庫時,Git自動把LF轉換成CRLF”。然而當一個CRLF作爲行結束符的文件在我們的Linux 或 Mac平臺不小心被引入時,你肯定想讓 Git 修正。 所以,你可以通過config --global core.autocrlf input命令把 core.autocrlf 設置成 input 來告訴 Git 在提交(commit)時把CRLF轉換成LF,檢出(git checkout)時不轉換

(1)+(2):這樣在 Windows 上的檢出(checkout)文件中會保留CRLF,而在 Mac 和 Linux 上,以及版本庫中會保留LF,從而保證我們項目團隊正常跨系統git操作代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章