如果你在一个Windows开发团队中–更甚者在一个跨平台的开发团队中,那么必须要面对的问题之一就是行结束符(line endings)。您的行结束符设置可能会影响开发效率并引发一系列问题。
处理行结束符的关键是确保您的. gitattributes
配置文件已正常提交到代码仓库。对大多数人来说,在仓库的根目录创建一个名为 .gitattributes
的文件,并添加下述配置是十分简单的。
* text=auto
设置了如上配置后,当将文件添加到仓库中时,Windows用户可以将它们从Windows样式的行结束符(\r\n)转换为Unix样式的行结束符(\n)。
如果你对这些内容已经感到无聊了,那么你可以马上停止阅读。对于大多数开发人员来说–在大多数代码仓库中–这些知识就已经足够了。
最初,Git for Windows引入了一种不同的行结束符表示方法:core.autocrlf。这是一种类似于属性机制的表示方法,其思想是,Windows用户如果设置了Git配置选项core.autocrlf=true
,当他们向仓库添加文件时,他们的行结束符将被转换为Unix样式的行结束符。
这两个选项之间的区别很微小,但很关键: .gitattributes
是在代码仓库中设置的,所以它可以与其他人共享。但是core.autocrlf是在本地Git配置中设置的。这意味着每个人都必须记住设置它,并且设置成相同的参数值。
首先,配置该选项最好的时机是当你在Windows安装Git时:
您需要点击第一个选项,但是如果您是第一次运行安装程序,您很可能并不知道这一点,这是可以谅解的。
core.autocrlf的问题是,如果有些人将它设置为true,而有些人没有,那么在您的代码仓库中会出现混合的行结束符。这并不好——因为他的设置并不只是告诉Git你希望它如何处理进入你的代码仓库的文件。它还告诉Git您已经做了什么,以及已经加入仓库的文件行结束符是什么样子。
这就是为什么行结束符配置最常见的问题之一就是是看到“phantom changes”:执行git status
命令告诉您已经更改了一个文件,但是运行git diff
看不到任何修改。为什么会这样呢?就是因为行结束符。
假设某个文件以Windows风格的行结束符加入到您的代码仓库中。由于某种原因,有人在添加文件时没有设置core.autocrlf=true
。另一方面,你作为一个熟练的Windows git用户,设置了这个选项。
当您运行git status
时,git将查看该文件以判断您是否对其进行了任何更改。当它将你磁盘上的内容与代码仓库中的内容进行比较时,它会将你本地仓库中磁盘上的行结束符从Windows风格转换为Unix风格。由于代码仓库中现有的文件都使用Windows风格的行结束符,而您希望它们是Unix风格的(按照你本地的配置),git将判断该文件是不同的。(从字节维度对比,确实不一样。)
通过使用.gitattributes
,您可以确保这些设置存在于仓库级别,而不是让每个用户来进行正确配置。这意味着就不用担心个人用户可能会配置错误。
当然,设置它的最佳时间是在您创建代码仓库之时,在您添加任何文件之前。事后进行设置意味着您可能仍然有一些文件使用了错误的配置项。
随着时间的推移,这些文件会随着您的编辑而更新。您可以尝试重新规范化文件,更新行结束符,但是这样做会导致在重新规范文件之前就已经创建的分支在合并时会出现令人讨厌的冲突。
一般来说,git非常擅长检测一个文件是否是二进制文件。如果它判断一个文件是二进制文件,那么它将拒绝转换行结束符。但是我们仍然推荐显式配置git不转换二进制文件的行结束符。
如果您不想某些文件进行行结束符的转化,您可以删除这些文件的文本属性。例如,如果您的仓库中中有png,那么对应的.gitattributes
配置文件可能如下所示:
* text=auto
*.png -text
当然, .gitattributes 的应用还有很多方面。在某些特定的开发场景中会特别有用。我们将在下一篇博文中深入探讨其中的一些——比如使用Unity。
原文链接:
https://www.edwardthomson.com/blog/git_for_windows_line_endings.html