元数据
| id | git-crlf | 收录 | 2026-08-29 |
|---|---|---|---|
| 问题域 | 编码代理与终端 | 主题分组 | 编码与格式 |
| 适用工具 | git · 外部工具 | ||
症状
- 改动一行代码,`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)。
3. **只想管特定类型**:`.gitattributes` 写 `*.sh text eol=lf`、`*.bat text eol=crlf` 等,其余不动。
4. **避免再犯**:新仓库先在根目录提交 `.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)
来源与证据
素材来源:https://github.com/nhkiiim/TIL/issues/6
验证证据:Evidence details kept locally (2026-08-29)