【随笔】不同系统间以及git软件仓库的行尾坑(LF和CRLF)

不同操作系统间的文本行尾差异

首先要明确CR和LF的概念:

CR= Carriage Return= 回车= \r
LF= Line Feed= 换行= \n
Windows=CRLF=\n\r
Unix系=LF=\n——包括linux&mac

Windows操作系统与Unix系操作系统的默认行尾符是不一样的,这直接影响到所有能够以文本形式读写的文件。

比如在Windows下新建一个文本文件(各种语言的源代码、脚本、html、json、纯文本等本质上都是文本文件),会默认每一行的结束符为/n/r,如果把这个文件复制到Linux下用vim打开,则会显示每一行有一个未知字符^M,即Linux只能识别\n字符,而无法识别\r字符。如果这个文件是一个shell脚本,那么必然执行失败。

github的行尾转换(可能导致项目崩溃的bug)

github为了解决这个问题,添加了自动转换行尾符的功能,在提交到远程仓库时,会根据git的设置自动静默修改文件内容,然而这个功能又创造了另一个大坑。

非代码文本文件(如字体、矢量图等)

这类文件有着特定的内容规范,独立于系统,内部选择CRLF/LF完全由自己决定,用不着外部插手,一旦被外部修改则文件损坏。github的坑就在这里,如果没有设置好,那么就会篡改项目里的字体、矢量图等文件,导致文件崩坏。我不知道版本回退能否恢复,但版本回退只是亡羊补牢而已,并不能否认这个问题的严重性。已经有很多人中招,此坑却依然存在,我认为这就是一个bug,而且是很low的bug,这使得项目代码时刻暴露于崩溃的风险之中,作为一个项目托管网站却存在这样的问题,实在是太奇葩。

虽然有许多手动设置的解决方案,但我只喜欢自动操作。为了避开这个bug,我的解决方案是:利用在项目根目录的.gitattribute配置文件,把所有可能会被github篡改而不希望被篡改的文件类型设置为binary。

附:.gitattribute配置文件

*.type binary——被识别为二进制文件,不检测这种文件类型的编码、行尾,文件内容不会被背地里修改

*.type text——检测这种文件类型的编码、行尾,文件内容有可能被修改,后面可跟eol=lf永远转换为LF或eol=crlf永远转换为CRLF

举例:

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

# Declare files that will always have LF line endings on checkout.
*.sh text eol=lf

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

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

# font
*.ttf binary
*.eot binary
*.woff binary
*.otf binary
*.woff2 binary

# doc
*.xlsx binary
*.docx binary

# media
*.mp3 binary
*.mp4 binary

# data
*.db binary
*.dat binary

你可能感兴趣的:(软件技术)