技术 · 实用指南
Git 报 fatal: bad object?删除前先证明引用、对象与仓库边界
先保全本地工作,再解析精确引用、测试对象、区分浅历史或部分克隆,最后只修证据确认损坏的层。

`fatal: bad object` 不是单一故障。Git 可能解析到缺失对象、遇到无效引用、跨过浅克隆或部分克隆边界、打开错误仓库,也可能真的发现对象损坏。
修改前先保全工作树和仓库元数据,再证明精确引用、对象 ID、对象类型和可达性边界。安全修复只改变证据确认的最小层,并保留可验证的恢复路径。
修复前先给工作做快照
在 checkout、reset、gc、prune、repack 或删除引用前,复制工作树与仓库元数据。记录 status、仓库根目录、Git 目录、远端、工作树和全部引用;删去凭据,但保留引用名与对象 ID。
大型仓库至少保留未提交文件、HEAD、松散与打包引用、reflog、shallow 文件、alternates 和部分克隆配置。可测试全新克隆,但在核对本地提交前不要替换损坏副本。
解析精确名称并测试精确对象
把错误中 bad object 后的内容当作证据。若是引用,用 show-ref、for-each-ref 与 rev-parse 验证;解析出对象 ID 后,用 cat-file -e 与 cat-file -t 测试存在性和类型。
还要证明失败进程使用的仓库与工作树。编辑器、钩子、服务和 CI 可能带着不同目录或 GIT_DIR 运行;若当前 shell 能打开对象,应复现原环境。
解读 fsck,不把每一行都当数据丢失
在保留副本上运行 git fsck --full。缺失对象、无效引用指针、哈希不匹配或损坏对象需要处理;dangling 只表示对象存在但未被普通引用触达,可能是恢复线索。
把第一条有效错误映射回精确引用或父边。若只有一个可丢弃的本地引用指向缺失对象,可考虑定向 update-ref -d;绝不能扩展为批量删除。
区分有意的历史边界与缺失数据
检查 .git/shallow、CI 深度、部分克隆过滤器、promisor 远端、alternates 与子模块。浅根是有意边界;actions/checkout 默认只取一个提交,旧祖先缺席不代表当前提交损坏。
确认远端与预期历史后,才深化或获取精确引用。fetch-depth: 0 请求完整分支和标签历史,但更小的定向获取可能已足够;获取失败仍需保留坏引用与对象恢复两条分支。
选择最小修复并证明收口
陈旧符号引用或远端引用应指向已验证分支,或只删除已证明可丢弃的那一个引用;浅克隆应深化;真正缺失的可达对象应从可靠克隆、备份或对象库恢复。
重试原命令,再检查精确引用、对象与 fsck 解释。确认未提交和仅本地工作仍在;保留损坏副本,直到全新克隆或备份独立证明恢复路径。
