end_of_line

Git 有一个 core.autocrlf 功能,它有三个值:false(提交、拉取不进行 CRLF <-> LF 转换),true(进行转换),input(仅提交时转换)。在 Windows 上一般设置为 true,这样能确保提交的不会影响团队内 Linux/Mac 成员,同时其他 Windows 成员也会在拉取时自动转换回 CRLF。

这个功能看起来很好,但是它有两个问题:

  1. 它只对提交的内容进行转换。有可能有时你需要将没有提交的内容(例如 Windows 上构建的静态文件)上传到 Linux 服务器,此时服务器接收到的文件采用 CRLF 换行,这就会导致 Linux 的某些工具在处理这些文件时出现问题。
  2. 你无法确保团队不同成员 core.autocrlf 设置正确,而这即使设置正确,也可能出现某些文件依赖另一种换行符的情况。

对于问题 1,由于 LF 换行符在 Windows 上的影响比较小,所以我们就统一采用 LF 换行符,即确保创建的文件都采用 LF,同时 Windows 上有些文件可能依赖 CRLF,我们额外设置白名单就行。这里我们使用 .editorconfig 控制项目创建文件的换行符类型:

# 项目创建的所有文件采用 LF 换行
[*]
end_of_line = lf

# cmd/bat 文件采用 CRLF 换行
[*.{cmd,bat}]
end_of_line = crlf

对于问题 2,其实很简单,我们只需要某种方法强制覆盖每个团队成员机器上的 core.autocrlf 的拉取行为就好了,同时针对不同类型文件在拉取时做不同的转换就好了。这里我们可以使用 .gitattributes 文件来强制声明拉取的文件换行格式:

# 默认拉取的所有文本文件都采用 LF 换行
* text=auto eol=lf 

# 拉取的 cmd/bat 文件强制采用 CRLF 换行
*.cmd text eol=crlf
*.bat text eol=crlf