之前没有遇到过这方面的问题,只到这次遇到了,才注意到这个问题。在Mac生成的代码文件,再在Windows上生成覆盖一次,文件内容没有变化,但是git提示文件发生了改变,原因便是换行符的问题。
Windows的机器默认使用的是\r\n
,即CRLF,而Mac机器默认使用的是\n
,即LF,所以git会提示文件发生了变化,而可视的文件内容并没有变化。
经过几次试验,对于处理这两个换行符,较为方便的策略是,全部使用LF的形式。Windows上默认的是CRLF,但是对于大多数IDE,同时支持LF和CRLF,所以使用LF也没有问题。
1. git的相关配置项
- core.autocrlf
这个配置有3个可选值,true/false/input,true是在提交代码时自动转换成LF,在检出代码时自动转换成CRLF,input是只在提交时转换成LF,false则是不进行转换。 - core.safecrlf
这个配置有3个可选值,true/false/warn,true表示不允许提交混合换行符,false表示允许,warn也表示允许,但是会发出提示 - .gitattrbutes
这是存在于项目根目录下的一个配置文件,优先级高于git config,在这里面可以配置git对于换行符的一些行为,并且可以使所有仓库协作者的行为保持一致,这一点很重要,因为git config是本地的配置,不同人的可能会有不同。
以上,就是git提供的可配置选项。
2. 配置
基于上面要达成的效果,首先auto需要配置成input,只要保证提交到远程的代码是LF,那么在检出的时候就没必要做转换了。
1 | git config core.autocrlf input |
safe设置成false,或者warn都可以,建议设置成warn,这样可以看到提示。
1 | git config core.safecrlf warn |
配置.gitattributes,没有的话需要先创建。
1 | touch .gitattributes |
其内容如下,
1 | * text=auto eol=lf |
星号表示对于任何文件,是否是text类型设置成auto,表示让git自己判断,git有一套判断是否是text类型文件的标准,一般交给git判断就好,如果是text的话,那么换行符使用LF,eol即为end of line。
一般来说,这样一行就可以了。此外,还可以添加一些额外的配置,明确指定文件的类型,比如以png结尾的是二进制文件,
1 | *.png binary |
以sh结尾的文件,告诉git不用当作文本处理
1 | *.sh -text |
注意,配置git config时,如果不加--global
参数,表示只对当前仓库有效,对于一些影响大的配置,建议都不要加global参数,避免无意间导致一些意料之外的问题。
3. 手动转换至LF
Mac上有一个命令工具,叫做dos2unix,用来将CRLF的文件转换成LF,用起来很方便,通过homebrew便可以安装,
1 | brew install dos2unix |
批量操作,通过find命令找到所有类型为文件的文件,然后再通过dos2unix命令将其转换成LF,如果已经是LF则不会发生改变。
1 | find . -type f -exec dos2unix {} \; |
清除git缓存,重新添加至git追踪,便可生效。
1 | git rm --cached -r . |
参考链接
- https://www.fullstackbb.com/post/handle-line-endings-in-git/
- https://rockhong.github.io/newline-in-git.html
- https://git-scm.com/docs/gitattributes
- http://crazy1984.com/2017/11/vcs/201711-git-line-endings/
- https://blog.csdn.net/uninterrupted/article/details/79000708