1.换行符在不同的操作系统上的表示
首先要理解的一点是,对于不同的操作系统,对于换行符的表示是不一样的。也就是说当我们在编辑一个文件,在键盘上按下回车键的时候,对于不同的操作系统保存到文件中的换行符是不一样的。见下表:
CR:表示回车\r
LF:表示换行\n
CRLF:表示回车换行\r\n
敲下回车键,不同的操作系统保存到文件中的值:
Windows:使用的是CRLF ==> 即\r\n,文件中保存的是\r\n
Linux/Unix: 使用的是LF ==> 即\n,文件中保存的是\n
Mac OS: 使用的是CR ==> 即\r,文件中保存的是\r
Mac OS X系统:使用的是LF ==> 即\n,文件中保存的是\n(Mac OS X已经改成和Unix/Linx一样使用LF)
问题: 既然不同的操作系统,对于换行符使用不同的表示形式,如果一个团队在开发一个共同的项目,如果你使用的是windows系统,而你的小伙伴用的是Mac的话,当你们使用git协同开发软件时,就会出现换行符不统一的问题。
虽然对于不同的操作系统,默认的换行符的表示方法不一样,但是编辑器是可以设置在敲下回车键的时候保存的换行符是什么的,比如常用的vscode就可以进行设置。直接点击编辑器右下角的LF或者CRLF,出现如下图所示的设置,直接选择即可。在设置完成之后,在敲回车键,保存在文件中的换行符就是你设置的(CRLF或者是LF,设置什么就是什么)。
2.Git会自动对换行符进行转换
Git为了解决上面提出的问题,会自动对换行符进行转换。转换的方案有3种:
- 在提交时将CRLF转换为LF,在拉取(检出checkout)时将UNIX换行符(LF)替换成CRLF。(Windows系统推荐使用,我们在windows上安装git的时候,如果一路next,默认是使用这个方案)
- 在提交时将CRLF转换为LF,在拉取(检出checkout)时不进行转换。(Linux/Unix和Mac OS和Mac OS X推荐使用,在Unix或者类Unix操作系统上安装git,默认使用这种方案)
- 不进行转换(这种方案对于跨平台项目不推荐使用)。
可以发现,如果不使用第3种方案,那么在Git仓库(包括本地仓库和GitHub远程仓库)中保存的文件的换行符都是LF表示的。
3.自己指定换行符转换方案
我们自己在开发过程中,是可以修改/设置Git的换行符转换方案的。修改/设置的方法有2种。
3.1 通过Git的全局配置进行修改
设置autoclf属性,在控制台直接运行如下的一条命令就可以设置了:
// 提交时转换为LF,检出时转换为CRLF
git config --global core.autocrlf true
// 提交时转换为LF,检出时不转换
git config --global core.autocrlf input
// 提交检出均不转换
git config --global core.autocrlf false
上述命令运行之后,会修改.gitconfig文件。
一般在项目中,为了避免项目中同时出现CRLF和LF,还可以开启safecrlf检查。当然,如果你的项目自己定义了语法检查规则,例如使用eslint去约束换行符必须是LF,那么当你的文件中出现CRLF的时候,eslint会给你错误提示信息,告诉你不能包含CRLF,这时候,不开启safecrlf也是可以的 (一般建议开启)。
开启方法如下第一条命令:
// 拒绝提交包含混合换行符的文件 (一般设置为true)
git config --global core.safecrlf true
// 允许提交包含混合换行符的文件
git config --global core.safecrlf false
// 提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn
上述命令运行之后,也会修改.gitconfig文件。
3.2 通过.gitattributes进行修改
参考:https://git-scm.com/docs/gitattributes
注意.gitattributes是针对一个单一的仓库的,也就是说每一个代码仓库都可以包含一个.gitattributes文件。这种方式设置之后,不需要一个项目组里面的同事分别再去修改自己电脑的git的全局配置。
对于通过.gitattributes设置换行符的转换方案,可以使用如下的命令:
1. text=auto:采用git认为最好的方式来处理文件,未在.gitattributes中
设置的项默认按照这种方式处理;(If Git decides that the content
is text, its line endings are converted to LF on checkin.
When the file has been committed with CRLF, no conversion
is done.)git发现是文本文件,那么在checkin的时候,会将文件结尾符转
换为LF。果文件已经被已CRLF的形式提交(就是说已经在Gti仓库中的文件,如
果结束符是CRLF,不会有任何的转换),不会有任何转换。
2. -text 表示让git在checkin以及checkout的时候,对end-of-line不
做任何转换。
3. text 表示在checkin的时候会被转换为LF(在repository中的文件结束
符是LF),如果需要控制在checkout的时候的换行符,需要结合eol进行设置
(也就是 控制working tree中的文件的结尾符,需要通过eol设置)。
text=auto和text的区别在于,text=auto由git来确定是不是文本文件,
从而进行转换;而text表示,你确定这个path就是文本文件,会直接对这个
path进行转换,而不是有git来decides是否转换。
4. 如果没有指定text,git会使用全局配置中的core.autocrlf来进行eol
的转换。core.autocrlf需要自己在自己的电脑上进行配置。
5. eol=crlf:对左边匹配的文件统一使用CRLF换行符格式,如果有文件中出现LF将会转换成CRLF;也就是说,在checkin和checkout的时候,文件中都是CRLF,
LF会被转换为CRLF。
7. eol=lf:对左边匹配的文件统一使用LF换行符格式,如果有文件中出现CRLF将会转换成LF;也就是说,在checkin和checkout的时候,文件中都是LF,
CRLF会被转换为LF。
8. binary: 告诉git该文件为二进制,防止git修改该文件。git不会对对其中的换行符进行改变。
注意:.gitattributes文件必须要提交之后才能生效。
参考博客: