校验和错乱但文件实际未损坏,大概率是.git/index缓存损坏;应先用git ls-files -s与git hash-object比对sha-1确认,再执行git add -u --refresh强制刷新索引校验和,而非直接删index或重置。

校验和错乱但文件实际没坏,大概率是 git 本地索引缓存损坏
Git 的 .git/index 文件记录了工作区文件状态与暂存区快照的映射,一旦它损坏(比如突然断电、磁盘写入异常、强行 kill git 进程),git status 就可能报告“修改”或“删除”,而 git diff 却看不到内容变化——本质是缓存里的校验和(SHA-1)和磁盘文件不一致,不是文件真坏了。
别急着 git reset --hard 或删整个 .git,先验证是不是缓存问题:
- 运行
git ls-files -s查看暂存区记录的 SHA-1; - 用
git hash-object <file></file>计算当前文件真实 SHA-1; - 两者不一致,就坐实是
index错乱。
强制重建 .git/index 而不丢暂存状态
直接删 .git/index 再 git read-tree HEAD 会清空暂存区,更稳妥的做法是让 Git 自动重生成并保留已 git add 的文件状态:
- 执行
git add -u:只重新扫描已跟踪文件,更新 index 中的校验和,不改动未跟踪文件; - 如果提示冲突或报错,加
--refresh强制刷新:git add -u --refresh; - 验证:再跑一遍
git ls-files -s和git hash-object,应完全一致。
注意:git add -u 不影响未 git add 的修改,也不会把新文件自动加入暂存区,安全边界清晰。
遇到 fatal: Unable to read tree HEAD 怎么办
这说明 HEAD 指向的 commit 对象本身损坏,或 .git/objects 里缺关键 blob/tree,比 index 损坏更严重。此时 git add -u 会失败:
- 先检查对象完整性:
git fsck --full; - 若输出类似
missing blob <sha></sha>,说明对象丢失,需从远程仓库恢复:git fetch origin --force(前提是远程有完整历史); - 若
fsck报broken link且本地无备份,只能靠.git/refs/和ORIG_HEAD等线索手动重建分支指向,风险高,建议优先从同事 clone 一份干净副本。
core.autocrlf 和换行符也会触发假校验和错乱
Windows 下开启 core.autocrlf=true 时,Git 会在检出时把 LF 转 CRLF,提交时再转回 LF。若某次转换中途失败(如编辑器锁住文件),index 里存的是 LF 版本的校验和,而工作区是 CRLF 版本,就会误报“修改”。
- 检查设置:
git config core.autocrlf; - 临时绕过:设为
false,再git add -u --refresh; - 长期方案:统一团队用
core.autocrlf=input(Linux/macOS 风格)或true(Windows),并在项目根目录放.gitattributes显式声明文本文件规则,比如:* text=auto eol=lf
换行符问题常被当成“缓存损坏”,但它本质是内容被静默转换,和 index 文件损坏的修复路径完全不同。











