Skip to content

Git 强制仓库使用 LF 换行符避免 ^M

  • 状态:已验证
  • 来源:对话整理
  • 更新时间:2026-03-16

关键结论

  • 统一换行符的推荐做法是使用 .gitattributes 控制仓库规则,而不是依赖开发者个人 Git 配置。
  • 跨平台协作时通常应统一为 LF,避免 Linux/macOS 中出现 ^M
  • .gitattributes 推荐配置为 * text=auto eol=lf
  • 在引入 .gitattributes 后,应执行 git add --renormalize . 统一现有文件。
  • 开发者本地 Git 配置只应作为辅助,优先级低于仓库规则。

详细分析

  • 文本文件常见的换行符有两种:
    • Linux / macOS:LF\n
    • Windows:CRLF\r\n
  • Windows 编辑产生的 CRLF 文件在 Linux 下常会显示为 ^M,容易导致:
    • diff 混乱
    • shell 脚本执行失败
    • 编译错误
    • patch 应用失败
  • Git 处理换行符时通常涉及三层:
    1. 工作区文件
    2. Git index
    3. 仓库存储
  • .gitattributes 可以控制 Git 在 checkout 和 commit 阶段如何处理换行符,因此它是工程级、仓库级的统一方案。
  • 推荐配置:
txt
* text=auto eol=lf
  • 该配置的含义是:
    • text=auto:让 Git 自动识别文本文件
    • eol=lf:强制文本文件以 LF 形式写入工作区和仓库标准化流程
  • 在这个规则下:
    • Windows 提交 CRLF 文本时,Git 会在入库时标准化为 LF
    • Linux/macOS 提交 LF 时保持不变
    • checkout 时也会按规则落地为 LF
  • 因此比起依赖每个人的 core.autocrlf,用仓库内的 .gitattributes 更稳定、可审计,也更适合团队协作。
  • 除了 .gitattributes,还可以配合 .editorconfig 和 CI 检查,形成“编辑器约束 + Git 规则 + 自动检查”的完整闭环。

可执行步骤

  1. 在仓库根目录创建 .gitattributes
txt
* text=auto eol=lf
  1. 如果希望编辑器层面也统一换行符,可增加 .editorconfig
ini
root = true

[*]
end_of_line = lf
insert_final_newline = true
  1. 在引入规则后,重新规范当前仓库中的文本文件:
bash
git add --renormalize .
  1. 提交统一后的结果:
bash
git commit -m "Normalize line endings"
  1. 检查仓库当前换行符状态:
bash
git ls-files --eol
  1. 在 Linux 下快速检测工作区是否仍有 CRLF
bash
grep -r $'\r' .
  1. 如果历史上已经混入大量 CRLF 文件,也可以先批量转换,再提交:
bash
dos2unix $(git ls-files)
git add .
git commit -m "convert CRLF to LF"

命令 / 配置 / 代码

txt
# .gitattributes
* text=auto eol=lf
ini
# .editorconfig
root = true

[*]
end_of_line = lf
insert_final_newline = true
bash
# 统一现有文件换行符
git add --renormalize .

# 查看文件换行符
git ls-files --eol

# 检测 CRLF 文件
grep -r $'\r' .

# 辅助检查:识别 CRLF 文本文件
find . -type f -print0 | xargs -0 file | grep CRLF

# Linux/macOS 建议配置
git config --global core.autocrlf input

# Windows 建议配置
git config --global core.autocrlf false

风险与注意事项

  • 修改 .gitattributes 后建议立刻执行 git add --renormalize .,否则旧文件可能仍保留历史上的换行符状态。
  • 旧提交中的 CRLF 不会因为新增 .gitattributes 自动被历史回溯修复。
  • patch 文件本身也可能带有 CRLF,跨平台传递时仍要注意。
  • dos2unix $(git ls-files) 属于批量修改操作,执行前应确认仓库中不存在本就要求保留特殊换行符的文件。
  • .editorconfig 和本地 core.autocrlf 只能作为辅助,最终应以仓库内 .gitattributes 作为统一规则。