1. 程式人生 > >Git處理換行符問題

Git處理換行符問題

在你通過github或者其他遠端託管伺服器來和其他人進行協同開發程式碼的時候,確保換行符被正確處理是一項很重要的事。首先,你需要知道不同的作業系統對換行符的定義會有所不同,Unix或類Unix作業系統的換行符叫做LF,而windows系統的叫做CRLF,二者具有很大的區別:

Unix系統裡,每行結尾只有“<換行>”,即”n”;Windows系統裡面,每行結尾是“<換行><回車>”

Note:引自回車(CR)與換行(LF), ‘r’和’n’的區別.

這就是造成問題的根源——即如果你使用的是windows系統,而你的小夥伴用的是Mac的話,當你們使用git協同開發軟體時,就會出現換行符不統一的問題。

git其實可以自己處理換行符不統一的問題,但是可能會產生意想不到的結果。因此,有必要進行相關的配置,我們通常有兩種方案:

  • 全域性配置換行符
  • 針對某個倉庫的區域性配置

換行符的全域性配置

一般如果你不想麻煩的話,可以採用比較簡單的方法,如下所示:

$ git config --global core.autocrlf true

其實,在你安裝windows版本的git或者torgoiseGit時,你可能已經進行過這樣的配置,也許你當時並未知道那個選項是什麼意思。下面這張圖是不是有些眼熟呢?

config-newline

不過,也許很多人安裝git的時候,是一直next…next吧!其實上面寫得很清楚:

  • Checkout Windows-style, commit Unix-style line endings

當檢出文字檔案時,Git會將LF轉換為CRLF。當提交文字檔案時,CRLF將會被轉換為LF。對於跨平臺的專案,這是對Windows系統的推薦設定。(“core.autocrlf” is set to “true”)

  • Checkout as-is, commit Unix-style line endings

當檢出文字檔案時,Git不會做任何轉換。當提交文字檔案時,CRLF將會被轉換為LF。對於跨平臺的專案,這是對Unix系統的推薦設定。(“core.autocrlf” is set to “input”)

  • Checkout as-is, commit as-is

不論是檢出還是提交文字檔案時,Git都不會做任何轉換。對於跨平臺的專案,不推薦採用該選項。

顯然,第一個選項就是我們所介紹的第一種方法。

順便吐槽一下,我在網上看到很多介紹如何安裝Git的部落格,很少有詳細說明每一個安裝步驟的,有些甚至直接說

一直next下去就安裝完成了。

一方面原因就是他們也不知道,其實這樣可能會對新手產生誤導,而且未免有些不負責任。

單一倉庫的換行符區域性配置

當然,有更好的方法解決換行符不統一的問題——使用.gitattributes檔案統一換行符。這種方法是針對某個倉庫進行換行符的統一配置,即時你已經進行了全域性配置。

另外,這個檔案有點兒類似於.gitignore,不僅名字很類似,使用方式,編寫語法也很像。這個檔案必須位於倉庫的根目錄,可以像其他檔案一樣進行修改、提交。下面介紹如何編寫這個檔案:

檔案內容看起來像一張表格,總共分為兩列:左邊一列是git要匹配的檔名;右邊是git需要採用的換行符格式。下面我們來看一個栗子:

# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto

# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.h text

# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

如果你熟悉.gitignore的話,你會覺得上面這個檔案的左邊一列很熟悉,這裡我們就不再贅述了,不熟悉的話,請自行查閱相關資料。唯一的不同就是.gitattributes檔案多了右邊一列,如text, text eol=crlf, binary,剛剛我們也說過這一列是用來設定左邊對應檔案使用的換行符格式的,左右兩列用空格隔開。下面我們來詳細介紹下右邊一列的語法:

  • text=auto
    讓git自行處理左邊匹配的檔案使用何種換行符格式,這是預設選項。

  • text eol=crlf
    對左邊匹配的檔案統一使用CRLF換行符格式,如果有檔案中出現LF將會轉換成CRLF。

  • text eol=lf
    對左邊匹配的檔案統一使用LF換行符格式,如果有檔案中出現CRLF將會轉換成LF。

  • binary
    告訴git這不是文字檔案,不應該對其中的換行符進行改變。另外,binary和符號-text -diff是等價的。

如果建立倉庫之前沒有進行換行符配置怎麼辦

也許你在看完我的部落格之後,才意識到自己並未進行相關的設定抑或是你想修改換行符配置,於是你興致勃勃地按照我的部落格進行了配置,結果你發現出了一堆莫名其妙的警告或者錯誤。

怪我嘍?

guaiwolou

不要著急吐槽,兵來將擋,水來土掩,沒有解決不了的問題!

  • 首先儲存Git中目前的所有檔案,這樣可以確保你的工作不會丟失。
# 在倉庫的根目錄下執行命令
$ git add . -u
$ git commit -m "Saving files before refreshing line endings"
  • 然後刪除暫存區中的所有檔案,
$ git rm --cached -r .
  • 重寫暫存區以重新應用新的換行符
$ git reset --hard
  • 找回所有修改過的檔案並加入暫存區,同時,你也可以檢視些檔案沒有被修改。
$ git add .
# 出現"warning: CRLF will be replaced by LF in file."的警告是很正常的現象
  • 提交你對倉庫的修改
$ git commit -m "Normalize all the line endings"

參考資料