Git 换行符 LF 和 CRLF 的自动转换

FreeGuideOnline 最新 2026-07-06

Git 换行符 LF 和 CRLF 的自动转换

为什么需要关心换行符

不同操作系统使用不同的字符表示文本行的结束:

  • LF (\n):Linux、macOS 以及现代 macOS 的默认换行符。
  • CRLF (\r\n):Windows 的默认换行符。

当开发团队跨平台协作,或者项目同时包含 Windows 和 Unix 类系统的文件时,不一致的换行符会导致:

  • 版本差异里出现大量无意义的“整行修改”。
  • 脚本、配置文件在错误的环境下执行失败。
  • 代码审查(Code Review)难以聚焦实际逻辑变更。

Git 提供了一套自动转换机制,可以在提交时将 CRLF 转为 LF,在检出时将 LF 转为 CRLF,从而保证仓库内部统一使用 LF,而工作区适配本地操作系统。

核心配置:core.autocrlf

通过设置 core.autocrlf,Git 会在文件的提交和检出过程中自动处理换行符。该配置有三个值:

配置值 提交时(工作区 → 仓库) 检出时(仓库 → 工作区) 适用场景
true CRLF 转换为 LF LF 转换为 CRLF Windows 开发者的推荐设置
input CRLF 转换为 LF 不做转换,保留 LF Linux/macOS 开发者,或跨平台项目希望工作区保持 LF 的场景
false 不做任何转换 不做任何转换 项目完全由特定操作系统开发,或对换行符有严格保留要求的场景(如二进制文件)

设置方式(全局或针对单个仓库):

# 全局设置(推荐 Windows 用户)
git config --global core.autocrlf true

# 全局设置(推荐 Linux/macOS 用户)
git config --global core.autocrlf input

# 仅当前仓库关闭自动转换
git config core.autocrlf false

三种模式的行为细节

  • true:Git 会认为所有文本文件在检出时应使用 CRLF,提交时统一转为 LF。这个设置对 Windows 用户最友好,避免因编辑器的自动换行符而引入冲突。
  • input:无论工作区文件是 LF 还是 CRLF,提交时一律转为 LF;检出时不做转换。如果开发者使用支持 LF 的编辑器(如 VS Code、Sublime、Vim),且希望仓库内外都保持 LF,这是合适的选择。
  • false:Git 完全不干预换行符,文件原样提交、原样检出。如果团队所有成员都在同一操作系统上工作,且已统一编辑器换行符设置,可以使用此选项。但通常不推荐,因为它放弃了 Git 提供的跨平台保护。

更精细的控制:.gitattributes

core.autocrlf 是全局或仓库级别的“一刀切”设置,无法区分文件类型。.gitattributes 文件则允许你为不同文件或文件类型单独指定换行符转换规则,并且该配置会随仓库传播,确保所有协作者行为一致。

常用属性

  • text=auto:让 Git 自动检测文件是否为文本。对检测为文本的文件执行换行符规范化(提交时转 LF,检出时按 core.eol 或操作系统转换)。对二进制文件不转换。
  • text:强制标记为文本文件,提交时统一为 LF
  • text eol=lf:提交和检出都强制使用 LF。工作区文件也将是 LF
  • text eol=crlf:提交时转 LF,检出时强制使用 CRLF
  • -text:取消所有换行符转换,文件被视为二进制,原样提交和检出。
  • binary-text -diff 的别名,标记为二进制文件,既不进行换行符转换,也不生成文本差异。

实战示例

在仓库根目录创建 .gitattributes 文件:

# 所有文件默认自动检测,文本文件规范化
* text=auto

# 明确指定源代码文件使用 LF,即使在 Windows 上检出也保持 LF
*.js    text eol=lf
*.ts    text eol=lf
*.py    text eol=lf
*.sh    text eol=lf

# Windows 特有的批处理文件必须使用 CRLF
*.bat   text eol=crlf
*.cmd   text eol=crlf

# 图片、字体等二进制文件不转换
*.png   binary
*.jpg   binary
*.woff2 binary

设置完成后,需要将 .gitattributes 文件提交到仓库。该文件对所有克隆仓库的开发者立即生效,优先级高于 core.autocrlf

如果只想对部分文件重新归一化换行符,可以使用:

# 将所有匹配 *.txt 的文件重新用 LF 标准化
git add --renormalize .

查看当前工作区换行符状态

有时需要确认文件实际使用的换行符,或者排查未预期的转换。常用方法:

  • file 命令检测(Linux/macOS):file your-file.txt 会显示 with CRLF line terminatorswith LF line terminators
  • cat -A 查看行尾字符cat -A your-file,行尾显示 $ 表示 LF,^M$ 表示 CRLF。
  • 用 Git 查看差异时注意 ^M:执行 git diff,如果看到行尾有 ^M 字符,说明文件包含 CRLF,但 Git 预期是 LF。
  • 检查 Git 生效的配置git config core.autocrlf 以及 git check-attr text your-file 可以查看 .gitattributes 对特定文件的效果。

常见问题与排查

问题:提交后 Git 状态仍显示文件已修改(即使未编辑)

这通常是因为工作区文件换行符与仓库索引中记录的不一致,且 Git 转换规则导致持续变化。 解决方案

  1. 确保 .gitattributescore.autocrlf 配置正确。
  2. 运行 git rm --cached -r . (谨慎操作,会清空暂存区),然后 git add --all。这会强制重新添加所有文件,让 Git 应用当前转换规则进行归一化。
  3. 提交归一化结果。

问题:在 Windows 检出后脚本无法在 WSL 或 Docker 中运行

很可能脚本被转换为了 CRLF,而 Linux 解释器要求 LF解决方案:在 .gitattributes 中强制该类脚本使用 eol=lf,例如:

*.sh text eol=lf

问题:.gitattributes 中添加了 * text=auto,但某些文件没被识别为文本

Git 使用类似 file 命令的启发式方法判断二进制内容。如果文件开头包含大量非 ASCII 字节,可能被误判。可以通过显式指定 text 来覆盖:

/my-data.csv text

问题:不小心把二进制文件提交成了文本并损坏了内容

二进制文件(如图片)如果被当作文本进行换行符转换,会破坏内容。务必在 .gitattributes 中为它们设置 binary-text

最佳实践:从混乱到一致

  1. 在项目初期就加入 .gitattributes 文件,并提交到仓库。这是团队协作中处理换行符最可靠的方式。
  2. 推荐配置组合
    • 所有仓库包含 .gitattributes* text=auto
    • Windows 开发者:git config --global core.autocrlf true
    • Linux/macOS 开发者:git config --global core.autocrlf input
  3. 编辑器统一配置:建议成员将编辑器默认换行符设置为 LF(VS Code、JetBrains 系列等均支持),并开启“保存时自动去除行尾空白”。从源头减少混乱。
  4. 避免在仓库中存在混合换行符:一旦出现,立即通过归一化提交解决,不要让不一致蔓延。
  5. CI 检查:可以在持续集成中运行 git diff --check,它会检测空白字符错误,包括 CRLF,提前阻断问题。

总结

  • Git 通过 core.autocrlf.gitattributes 解决跨平台换行符混乱。
  • core.autocrlf 提供三种模式:true (Windows 友好)、input (Unix 友好)、false (不转换)。
  • .gitattributes 提供文件级别的精细控制,是团队协作的最佳选择。
  • 正确配置后,开发者在各自系统上都能舒适地工作,仓库内部始终保持干净的 LF 历史。规范化换行符是构建可持续、多平台项目的基础步骤。