问题现象

在 Windows 上编辑仓库中的文件并执行 git status 时,文件显示为已修改(M),但 git diff 输出完全为空。执行 git add 后再执行 git commit,报错 nothing to commit, working tree clean

根因分析

Git 的三种行尾模式

模式

作用

LF(Line Feed, \n

Linux/macOS 行尾标准,仓库中推荐

CRLF(Carriage Return + Line Feed, \r\n

Windows 行尾标准

CR(Carriage Return, \r

旧版 macOS(已基本淘汰)

触发条件

  1. 仓库中的文件以 LF 存储(这是 Git 的默认行为)

  2. Windows 上的 core.autocrlf 默认为 true

  3. Git 检出文件时自动 LF → CRLF,提交时自动 CRLF → LF

  4. 当文件被编辑保存后,磁盘上的 CRLF 版本与索引中的 LF 版本被 Git 判定为"不同"

  5. git status 显示已修改,但 git diff 对比的是工作区 vs 索引的内容,而行尾差异在 diff 层被忽略,所以显示为空

  6. git add 时 Git 执行 CRLF → LF 转换,与索引版本一致 → nothing to commit

为什么会反复出现

每次通过 Trae 编辑规则文件后,编辑器都会以 CRLF 格式保存文件。Git 在工作区看到 CRLF,索引中是 LF,于是又标记为已修改——形成循环。

解决方案

创建 .gitattributes 文件

在仓库根目录创建 .gitattributes,显式声明行尾策略,覆盖 core.autocrlf 的默认行为:

* text=auto eol=lf

配置项含义

部分

含义

*

匹配所有文件

text=auto

Git 自动检测文件是否为文本文件,是则进行行尾转换

eol=lf

强制所有文本文件使用 LF 行尾(即检出时也不转为 CRLF)

相对于默认行为的优势

行为

默认(有 .gitattributes 前)

.gitattributes

仓库存储

LF

LF(不变)

检出到工作区

core.autocrlf=true → CRLF

eol=lfLF(不变)

git status 误报

频繁出现

不再出现

跨平台协作

依赖每个人本机配置

统一由仓库声明控制

生效确认

执行以下命令一次性重写索引中的行尾记录:

git add --renormalize .

此后所有文件的检出、提交均使用 LF,不再产生误报。