[toc]
一、遇到的問題
在Windows平臺上,會出現(xiàn)如下的warning:
$ git add app.wxss
warning: LF will be replaced by CRLF in app.wxss.
The file will have its original line endings in your working directory.
為什么會出現(xiàn)這個warning呢?
二、為什么會出現(xiàn)這個問題
通過查閱《ProGit》的相關(guān)內(nèi)容,可以得知:
If you’re programming on Windows and working with people who are not (or vice-versa), you’ll probably run into line-ending issues at some point. This is because Windows uses both a carriage-return character and a linefeed character for newlines in its files, whereas Mac and Linux systems use only the linefeed character. This is a subtle but incredibly annoying fact of cross-platform work; many editors on Windows silently replace existing LF-style line endings with CRLF, or insert both line-ending characters when the user hits the enter key.
簡單翻譯一下,Windows在換行的時候,同時使用了回車符(carriage-return character)和換行符(linefeed character);而Mac和Linux系統(tǒng)(很老的mac系統(tǒng)才是CR,可以參見wiki),此時,僅僅使用了換行符(linefeed character)。同時呢,Windows的許多編輯器還悄悄滴將LF修改成了CRLF格式的行結(jié)束符,或者在你敲回車的時候,CRLF格式的行結(jié)束符就產(chǎn)生了。當(dāng)然,這一切都發(fā)生在同時存在Windows和非Windows的跨平臺工作中,如果大家都是同一種操作系統(tǒng),那么,就天下太平了。
warning中所說的LF和CRLF分別是linefeed和carriage-return&linefeed。
那么現(xiàn)在,再仔細(xì)看warning的內(nèi)容,為什么在git add
的時候,“警告:app.wxss中的LF將來會被替換成CRLF”?
三、為什么LF->CRLF
Git can handle this by auto-converting CRLF line endings into LF when you add a file to the index, and vice versa when it checks out code onto your filesystem.
Git有一個針對性的功能:當(dāng)添加到暫存區(qū)時,自動將CRLF轉(zhuǎn)換成LF;反之,當(dāng)檢出時,自動將LF轉(zhuǎn)換成CRLF。
You can turn on this functionality with the core.autocrlf setting.
可以通過設(shè)置core.autocrlf
來開啟這個功能。
看到這里,就更加不懂了,添加到暫存區(qū)時,為什么警告LF將被轉(zhuǎn)換成CRLF?這不是和功能相反了嗎?
四、原因
這個問題與git-config
里面的相關(guān)設(shè)置有關(guān),主要涉及到三個參數(shù):
core.autocrlf
core.safecrlf
core.eol
這三個參數(shù)用來配置Git處理line-ending的方式。
五、接下來,來看如何配置
1. core.autocrlf
(1) true
If you’re on a Windows machine, set it to true?—?this converts LF endings into CRLF when you check out code:
$ git config --global core.autocrlf true
如果是在 Windows 系統(tǒng)上,把它設(shè)置成 true,這樣在檢出代碼時,換行(LF)會被轉(zhuǎn)換成回車和換行(CRLF)
(2) input
If you’re on a Linux or Mac system that uses LF line endings, then you don’t want Git to automatically convert them when you check out files; however, if a file with CRLF endings accidentally gets introduced, then you may want Git to fix it. You can tell Git to convert CRLF to LF on commit but not the other way around by setting core.autocrlf to input:
$ git config --global core.autocrlf input
如果使用以換行作為行結(jié)束符的 Linux 或 Mac,你不需要 Git 在檢出文件時進(jìn)行自動的轉(zhuǎn)換;然而當(dāng)一個以回車加換行作為行結(jié)束符的文件不小心被引入時,你肯定想讓 Git 修正。 你可以把 core.autocrlf 設(shè)置成 input 來告訴 Git 在提交時把回車和換行轉(zhuǎn)(CRLF)換成換行(LF),檢出時不轉(zhuǎn)換
(3) false
If you’re a Windows programmer doing a Windows-only project, then you can turn off this functionality, recording the carriage returns in the repository by setting the config value to false:
$ git config --global core.autocrlf false
如果你是 Windows 程序員,且正在開發(fā)僅運行在 Windows 上的項目,可以設(shè)置 false 取消此功能,把回車(CR)保留在版本庫中
以上,是core.autocrlf
的設(shè)置規(guī)則與建議。
2. core.safecrlf
通過查閱git-scm上的文檔上關(guān)于git-config
的文檔或者mirrors.edge.kernel.org
If true, makes Git check if converting
CRLF
is reversible when end-of-line conversion is active. Git will verify if a command modifies a file in the work tree either directly or indirectly.For example, committing a file followed by checking out the same file should yield the original file in the work tree. If this is not the case for the current setting ofcore.autocrlf
, Git will reject the file.
簡單翻譯一下:當(dāng)core.autocrlf
為true
或者input
時,算激活了eol
,此時如果core.safecrlf
為true
,Git檢查crlf
轉(zhuǎn)換是否正常,比如Windows平臺,core.autocrlf
設(shè)置為true
,如果工作區(qū)的文件中含有LF
,Git就會拒絕,因為true
的情況下,Git認(rèn)為工作區(qū)應(yīng)該都是CRLF
才對啊。
給你一個致命大禮,fatal:LF would be replaced by CRLF in app.wxss.
,阻止你繼續(xù)操作。
^?_?^ 使用dos2unix進(jìn)行手動轉(zhuǎn)換
這種情況不要慌,可以使用dos2unix工具中的unix2dos將LF
轉(zhuǎn)換成CRLF
,來滿足core.autocrlf
為true
的要求。當(dāng)然,解決的方法有很多,可以根據(jù)實際情況,使用不同的方法來解決。
以下命令可以將當(dāng)前文件夾內(nèi)的文件批量的轉(zhuǎn)換,也有其他方式,比如find . -type f -exec dos2unix {} +
,可以自行Google
find . -type f -print0 | xargs -0 dos2unix
dos2unix工具在Windows的MINGW64 Git Bash客戶端上自帶,在mac平臺可以Google how to install dos2unix on mac,同理linux(sudo apt-get install dos2unix
),哈哈哈。
The variable can be set to "warn", in which case Git will only warn about an irreversible conversion but continue the operation.
也可以設(shè)置core.safecrlf
為warn
,Git就只會警告一下,不會阻止你。
繼續(xù)看文檔的內(nèi)容。寫著寫著成了《帶你看文檔系列》了,所以很多問題,仔細(xì)看文檔就能解決,但是文檔太多,也很難看懂,只能花時間多看了。
CRLF conversion bears a slight chance of corrupting data. When it is enabled, Git will convert CRLF to LF during commit and LF to CRLF during checkout. A file that contains a mixture of LF and CRLF before the commit cannot be recreated by Git. For text files this is the right thing to do: it corrects line endings such that we have only LF line endings in the repository. But for binary files that are accidentally classified as text the conversion can corrupt data.
If you recognize such corruption early you can easily fix it by setting the conversion type explicitly in .gitattributes. Right after committing you still have the original file in your work tree and this file is not yet corrupted. You can explicitly tell Git that this file is binary and Git will handle the file appropriately.
這一段主要是說,同時有LF
和CRLF
的文件是被腐蝕的,這類文件是不被Git認(rèn)可的,而CRLF的轉(zhuǎn)換過程很可能會產(chǎn)生腐蝕的文件,比如二進(jìn)制的文件被當(dāng)作文本的話,就會被腐蝕。
所以提出了重要的文件.gitattributes
來明確轉(zhuǎn)換配置,而且越早設(shè)置越好。你可以明確地指出某些文件是二進(jìn)制的,比如*.jpg,Git知道了以后,會妥善處理。
Note, this safety check does not mean that a checkout will generate a file identical to the original file for a different setting of core.eol and core.autocrlf, but only for the current one. For example, a text file with LF would be accepted with core.eol=lf and could later be checked out with core.eol=crlf, in which case the resulting file would contain CRLF, although the original file contained LF. However, in both work trees the line endings would be consistent, that is either all LF or all CRLF, but never mixed. A file with mixed line endings would be reported by the core.safecrlf mechanism.
我的理解是,A和B協(xié)同開發(fā),A設(shè)置的是core.eol=lf core.autocrlf=true
,B設(shè)置的是core.eol=crlf core.autocrlf=true
,那么A checkout的時候,生成lf
結(jié)尾的文件,而B checkout的時候,生成crlf
結(jié)尾的文件。要么都是lf
,要么都是crlf
,安全檢查不可能允許混合出現(xiàn),如果發(fā)現(xiàn)了混合的行結(jié)束符,就會報警
3. core.eol
通過查閱git-scm上的文檔上關(guān)于git-config
的文檔或者mirrors.edge.kernel.org
Sets the line ending type to use in the working directory for files that have the
text
property set when core.autocrlf is false. Alternatives are lf, crlf and native, which uses the platform’s native line ending. The default value isnative
. See gitattributes[5] for more information on end-of-line conversion.
當(dāng)core.autocrlf
是false
時,設(shè)置行結(jié)束符的類型,可以是
lf
crlf
native
三種,其中native
是指平臺默認(rèn)的行結(jié)束符。默認(rèn)的類型是native
欲知詳情,請翻閱gitattributes[5]或者mirrors.edge.kernel.org。
六、總結(jié)一下吧
1. 不安全不保險的方式
雖然Google查詢LF will be replaced by CRLF
,幾個答案會建議設(shè)置
git config --global core.autocrlf false
git config --global core.safecrlf false
比如stackoverflow,知乎,github上的bolg中的某些答案(這幾個鏈接里也是有一些干貨的),
但是,通過上面我們看文檔的過程,我們發(fā)現(xiàn)這種方式,是不保險的。很容易產(chǎn)生混合,git diff
的時候,就會影響我們查看版本之間的修改。
2. 個人推薦的設(shè)置方式
(1)添加.gitattributes
首先要在項目里添加.gitattributes文件,可以參考Github help-Dealing with line endings和gitattributes[5],這是我自己的.gitattributes。
(2)safecrlf設(shè)置為true
git config --global core.safecrlf true
(3)autocrlf在不同平臺不同設(shè)置
- Windows
git config --global core.autocrlf true
- Mac Or Linux
git config --global core.autocrlf input
(4)eol默認(rèn)native,因為autocrlf不是false,也不起作用啊
補充
第一點 Git Setup Treat Line Endings In Text Files
Git默認(rèn)的core.autocrlf其實在安裝Git For Windows的時候,讓我們選擇了,只是安裝的時候并不會注意,就是下面這張圖:
由上向下依次是
true input false
。
第二點 TortoiseGit settings about AutoCrlf
另外,如果使用的是TortoiseGit,要注意其中的設(shè)置: