编码代理与终端 · 收录于 2026-08-29 · 适用 1 工具 ✓ 实测验证

git 换行符混乱——diff 全部文件显示修改 / warning: LF will be replaced by CRLF / CRLF will be replaced by LF

已验证 2026-08-29git 换行符混乱——仓库根加 .gitattributes(* text=auto eol=lf)后 git add --renormalize . 一劳永逸。

快速修复

# 一键:仓库根目录加 .gitattributes 并重规范化(一劳永逸)
printf '* text=auto eol=lf\n' > .gitattributes && git add .gitattributes && git add --renormalize . && git commit -m "normalize line endings"

之后 git ls-files --eol 应显示 i/lf w/lf。

你会遇到什么

改动一行代码,git diff 却把整个文件标成修改(每行都是红+/绿-);git add 时冒 warning: LF will be replaced by CRLF(或反向 CRLF will be replaced by LF);同一仓库在 Windows 和 Linux/WSL 两边 checkout 出来"看起来一样"但 diff 永远不干净;

脚本在 Windows 上 clone 下来后报 \r 相关执行错误。

换行符策略没统一。

本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。

为什么会这样

Windows 文本默认 CRLF(\r\n),Linux/macOS 默认 LF(\n)。git 的 core.autocrlf 控制转换,而入库格式取决于首次提交时各人的配置:

配置行为适用
autocrlf=false不做转换,CRLF 直接入库Windows 旧默认——跨平台仓库的坑源
autocrlf=true提交转 LF、检出转 CRLFWindows 推荐
autocrlf=input提交转 LF、检出不转Linux 推荐

多人各配各的,仓库里 CRLF/LF 混合入库,就是"谁提交谁踩坑"的源头。warning: LF will be replaced by CRLF 本身无害,但出现 = 行尾策略没统一。

行尾转换发生在「写出/读入」两个方向:core.autocrlf 控制的是提交时把工作区 CRLF 转成 LF 入库、检出时按配置转回——它只改文本流的字节,不识别文件类型,所以二进制文件在 autocrlf=true 下也可能被误转(.gitattributes 的 -text 就是用来豁免的)。

仓库里最终存什么,取决于每个提交者自己的配置:autocrlf=false 的人把 CRLF 原样提交,autocrlf=true 的人提交时转 LF——同一仓库两种字节并存,git 的 diff 就会显示整行改动。

确定性推论:LF will be replaced by CRLF 警告 = 检出时发生了转换,说明配置已生效但策略未统一;跨平台仓库应该在 .gitattributes 里用 * text=auto + 显式声明(*.sh text eol=lf 等)把策略写进仓库,而不是依赖每个人的本地配置——配置是每台机器自己的,属性是跟着仓库走的。

一步步来

1. 症状无害时(只是 warning、diff 没乱) — 必做

确认全队统一 core.autocrlf(Windows 用 true,Linux/mac 用 input),warning 会消失。

2. diff 全红/已混入库(推荐,一劳永逸) — 必做

仓库根目录加 .gitattributes:

* text=auto eol=lf

然后重规范化(把历史里已入库的 CRLF 全部转成 LF):

git add .gitattributes
git add --renormalize .
git commit -m "normalize line endings"

3. 只想管特定类型 — 必做

.gitattributes 写 *.sh text eol=lf、*.bat text eol=crlf 等,其余不动。

4. 避免再犯 — 必做

新仓库先在根目录提交 .gitattributes(* text=auto)再写内容;不要用 autocrlf=false 做跨平台仓库的默认(那会把 CRLF 存进仓库)。

怎么确认修好了

入库格式统一(实测输出形态):

git ls-files --eol → 全部 i/lf w/lf,无 warning
git diff → 只显示真实改动(加 1 行只报 1 insertion,实测)

其它环境的表现

环境说明
Windowsautocrlf=true(提交转 LF、检出转 CRLF)
Linux/macautocrlf=input
已混入库.gitattributes + git add --renormalize .(实测修复)
特定文件*.sh text eol=lf、*.bat text eol=crlf
新仓库先提交 .gitattributes 再写内容

症状

  • 改动一行代码,git diff 却把整个文件标成修改(每行都是红+/绿-);
  • git add 时冒 warning: in the working copy of 'xxx', LF will be replaced by CRLF the next time Git touches it(或反向 CRLF will be replaced by LF);
  • 同一仓库在 Windows 和 Linux/WSL 两边 checkout 出来内容「看起来一样」但 diff 永远不干净;
  • 脚本(.sh/.py)在 Windows 上 clone 下来后报 \r 相关执行错误(CRLF 进入脚本)。

特征:纯文本文件;报错带「换行符」字样;Windows/Linux 双环境协作的仓库最常见。

原因

Windows 文本默认 CRLF(\r\n),Linux/macOS 默认 LF(\n)。git 的 core.autocrlf 控制转换,而入库格式取决于首次提交时各人的配置:

  • autocrlf=false(Windows 旧版 git 默认、很多老教程推荐):提交时不做任何转换,CRLF 直接被存进仓库——后续任何 LF 工作区一比对就全行不同,diff 全红;
  • autocrlf=true(Windows 推荐):提交转 LF、检出转 CRLF;
  • autocrlf=input(Linux 推荐):提交转 LF、检出不转。

多人各配各的(Windows 默认 false + Linux 默认 input 或 false),仓库里 CRLF/LF 混合入库,就是「谁提交谁踩坑」的源头。warning: LF will be replaced by CRLF 只是提示 git 会在下次操作时转换,本身无害,但它出现 = 行尾策略没统一。

解法

  1. 症状无害时(只是 warning、diff 没乱):确认全队统一 core.autocrlf(Windows 用 true,Linux/mac 用 input),warning 会消失。
  2. diff 全红/已混入库(推荐,一劳永逸):

仓库根目录加 .gitattributes:

   * text=auto eol=lf

然后重规范化(把历史里已入库的 CRLF 全部转成 LF):

   git add .gitattributes
   git add --renormalize .
   git commit -m "normalize line endings"

之后 git ls-files --eol 应显示 i/lf w/lf(入库/工作区都是 LF)。

  1. 只想管特定类型:.gitattributes 写 *.sh text eol=lf、*.bat text eol=crlf 等,其余不动。
  2. 避免再犯:新仓库先在根目录提交 .gitattributes(* text=auto)再写内容;不要用 autocrlf=false 做跨平台仓库的默认(那会把 CRLF 存进仓库)。
验证证据
  • 本地实测(2026-08-29,WSL Ubuntu,git 2.53.0):
  • 复现 1(diff 全红):autocrlf=false 提交 CRLF 文件(git ls-files --eol 显示 i/crlf w/crlf)→ 工作区改成 LF 后 git diff 把 2 行显示成 3 删 2 加(全行变化);
  • 复现 2(warning 正向):autocrlf=true 时 add LF 文件 → warning: in the working copy of 'lf.txt', LF will be replaced by CRLF the next time Git touches it;
  • 复现 3(warning 反向):autocrlf=input 时 add CRLF 文件 → warning: ... CRLF will be replaced by LF ...;
  • 修复:根目录 .gitattributes(* text=auto eol=lf)+ git add --renormalize . → 入库格式全部 i/lf w/lf,无 warning;
  • 修复后 diff 只显示真实改动(加 1 行只报 1 insertion)。
  • 实测复现日志(2026-08-29)

适用工具 (1)

本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。

git · 外部工具

来源与证据

收录 验证 ✓ 实测验证适用 1 工具
方案含本地实测或来源可复核的解法;未实测项已在文中如实标注。

素材来源:https://github.com/nhkiiim/TIL/issues/6

← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡