如何恢复由于硬盘故障损坏的Git对象?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (62)

我遇到了硬盘故障,导致Git存储库的一些文件被损坏。运行时git fsck --full我得到以下输出:

error: .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack SHA1 checksum mismatch
error: index CRC mismatch for object 6c8cae4994b5ec7891ccb1527d30634997a978ee from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack at offset 97824129
error: inflate: data stream error (invalid code lengths set)
error: cannot unpack 6c8cae4994b5ec7891ccb1527d30634997a978ee from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack at offset 97824129
error: inflate: data stream error (invalid stored block lengths)
error: failed to read object 0dcf6723cc69cc7f91d4a7432d0f1a1f05e77eaa at offset 276988017 from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack
fatal: object 0dcf6723cc69cc7f91d4a7432d0f1a1f05e77eaa is corrupted

我有存储库的备份,但是唯一包含包文件的备份已经损坏了。因此,我认为我必须找到一种方法从不同的备份中检索单个对象,并以某种方式指示Git生成一个只有正确对象的新包。

能给我一些提示吗?如何修复我的存储库?

提问于
用户回答回答于

在以前的一些备份中,坏对象可能已打包在不同的文件中,或者可能是松散的对象。这样你的物品就可以被回收了。

数据库中似乎有一些坏的对象。这样你就可以用手动的方式了。

因为git hash-objectgit mktreegit commit-tree不要因为在包中找到对象而编写对象,然后开始这样做:

mv .git/objects/pack/* <somewhere>
for i in <somewhere>/*.pack; do
  git unpack-objects -r < $i
done
rm <somewhere>/*

(包将从存储库中移出,并在其中重新解压缩;现在数据库中只有好的对象)

你可以:

git cat-file -t 6c8cae4994b5ec7891ccb1527d30634997a978ee

并检查对象的类型。

如果类型为BLOB:从以前的备份中检索文件的内容(与git showgit cat-filegit unpack-file然后你可以git hash-object -w若要在当前存储库中重写对象,请执行以下操作。

如果类型是树:可以使用git ls-tree若要从以前的备份中恢复树,请执行以下操作:git mktree在当前存储库中再次编写它。

如果类型为COMMIT:git showgit cat-filegit commit-tree

当然,在开始这个过程之前,我会备份原来的工作副本。

用户回答回答于

# Unpack last non-corrupted pack
$ mv .git/objects/pack .git/objects/pack.old
$ git unpack-objects -r < .git/objects/pack.old/pack-012066c998b2d171913aeb5bf0719fd4655fa7d0.pack
$ git log
fatal: bad object HEAD

$ cat .git/HEAD 
ref: refs/heads/master

$ ls .git/refs/heads/

$ cat .git/packed-refs 
# pack-refs with: peeled 
aa268a069add6d71e162c4e2455c1b690079c8c1 refs/heads/master

$ git fsck --full 
error: HEAD: invalid sha1 pointer aa268a069add6d71e162c4e2455c1b690079c8c1
error: refs/heads/master does not point to a valid object!
missing blob 75405ef0e6f66e48c1ff836786ff110efa33a919
missing blob 27c4611ffbc3c32712a395910a96052a3de67c9b
dangling tree 30473f109d87f4bcde612a2b9a204c3e322cb0dc

# Copy HEAD object from backup of repository
$ cp repobackup/.git/objects/aa/268a069add6d71e162c4e2455c1b690079c8c1 .git/objects/aa
# Now copy all missing objects from backup of repository and run "git fsck --full" afterwards
# Repeat until git fsck --full only reports dangling objects

# Now garbage collect repo
$ git gc
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'refs/heads/master' references pruned commits
Counting objects: 3992, done.
Delta compression using 2 threads.
fatal: object bf1c4953c0ea4a045bf0975a916b53d247e7ca94 inconsistent object length (6093 vs 415232)
error: failed to run repack

# Check reflogs...
$ git reflog

# ...then clean
$ git reflog expire --expire=0 --all

# Now garbage collect again
$ git gc       
Counting objects: 3992, done.
Delta compression using 2 threads.
Compressing objects: 100% (3970/3970), done.
Writing objects: 100% (3992/3992), done.
Total 3992 (delta 2060), reused 0 (delta 0)
Removing duplicate objects: 100% (256/256), done.
# Done!

扫码关注云+社区