[TOC]
有时我们会遇到跨平台开发的情况,在windows上开发同时支持linux和windows部署的程序。
那么我们的程序中可能就会有平台相关的一些文件,比如shell脚本(bat、sh)。
如果没有正确处理好这些文件的换行符,将会导致脚本文件在对应的平台上不能正确执行。
对于使用Git管理源码的项目,git对text文件有自动转换换行符的机制,相关的配置有:
- git config core.autocrlf
- git config core.safecrlf
- git config core eol
- .gitattributes
windows和linux换行符的区别
- 在linux系统中,行尾使用一个换行符(LF=line feed)表示
- 在windows系统中,行尾使用回车(CR=carriage return)+换行(LF=line feed)2个字符表示
git config core.autocrlf
可选的配置值有:
- true 提交文件时自动转换为LF,检出文件时自动转换为CRLF。在windows平台上,这个是git的默认设置。
- input 提交的时候自动转换为LF,检出文件时不做转换。
- false 提交和检出的时候都不对换行符进行自动转换。提交时文件时什么样,服务器上就是什么样。
1
2
3
4
5
6
7core.autocrlf=true: core.autocrlf=input: core.autocrlf=false:
repo repo repo
^ V ^ V ^ V
/ \ / \ / \
crlf->lf lf->crlf crlf->lf \ / \
/ \ / \ / \
因为 core.autocrlf 在windows平台上默认是true,所以检出的时候sh文件将自动转换成CRLF换行符。
如果在windows平台上打包安装程序,那么安装后的程序sh文件将不能正常执行。
git config core.safecrlf
由于git有自动转换换行符的机制,如果设置了autocrlf,那么文件的换行符可能被统一处理。
例如: 对于混合了CRLF和LF的文件,都被统一成LF提交服务器了。
这种就是git处理转换后不可逆的情况:在同个机器上,提交后再检出,不能还原出一样的文件。
如果git错误的将binary文件判断为text文件,自动进行了CRLF转换,那么就会损坏文件数据。
通过开启 safecrlf 选项,可以防止出现上述错误:
- true 如果git根据配置的CRLF转换自动处理文件,将导致文件不可逆,那么git将拒绝提交文件。
- warn 如果git根据配置的CRLF转换自动处理文件,将导致文件不可逆,那么git将显示警告信息但继续处理文件。
- false 关闭检查。
开启该选项不会改变git的CRLF转换处理,但通过该选项,可以保证提交的text文件里不会出现混合LF、CRLF的情况。
git config core.eol
当autocrlf=false时,通过.gitattributes配置了text属性的文件,其换行符将使用本配置值。
可选的值有:cr,crlf,native(使用本地操作系统匹配的换行符)
.gitattributes
在项目的git根路径下,添加.gitattributes文件并纳入git管理,然后打开编辑内容:
1 | *.bat eol=crlf |
说明:
- bat 文件在检入检出时,使用CRLF换行符
- sh 文件在检入检出时,使用LF换行符
- ‘-text’ 的意思是,标记该类型的文件不是text。git对这类文件会跳“是否text文件”的检测,也不会自动转换换行符。
- ‘text=auto’ 的意思是,标记该类型的文件是text,同时使用core.eol配置的换行符(如果有配置的话)。
- 优先级: autocrlf > text=auto + core.eol
对于明确是二进制数据的文件,可以在本文件中显示的声明非text,防止git检测有误时错误的对文件进行处理而损坏数据。
总结
通过git config进行配置,只能在对所有的文件进行统一处理,不能分文件类型处理。
而且仅对各客户端有效,不能保证在不同开发人员那保持一致。
所以最好在项目根路径下添加.gitatttibutes文件,对关键的文件类型分别统一配置CRLF转换,也可避免不同客户端环境不同的影响。
参考
- https://git-scm.com/docs/git-config
- https://git-scm.com/docs/gitattributes
- https://stackoverflow.com/questions/1967370/git-replacing-lf-with-crlf
- https://stackoverflow.com/questions/5834014/lf-will-be-replaced-by-crlf-in-git-what-is-that-and-is-it-important
- https://stackoverflow.com/questions/21472971/what-is-the-purpose-of-text-auto-in-gitattributes-file
- https://help.github.com/articles/dealing-with-line-endings/#platform-all