Search code examples
gitcorruptiondata-recovery

How to recover Git objects damaged by hard disk failure?


I have had a hard disk failure which resulted in some files of a Git repository getting damaged. When running git fsck --full I get the following output:

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

I have backups of the repository, but the only backup that includes the pack file has it already damaged. So I think that I have to find out a way to retrieve the single objects from different backups and somehow instruct Git to produce a new pack with only correct objects.

Can you please give me hints how to fix my repository?


Solution

  • In some previous backups, your bad objects may have been packed in different files or may be loose objects yet. So your objects may be recovered.

    It seems there are a few bad objects in your database. So you could do it the manual way.

    Because of git hash-object, git mktree and git commit-tree do not write the objects because they are found in the pack, then start doing this:

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

    (Your packs are moved out from the repository, and unpacked again in it; only the good objects are now in the database)

    You can do:

    git cat-file -t 6c8cae4994b5ec7891ccb1527d30634997a978ee
    

    and check the type of the object.

    If the type is blob: retrieve the contents of the file from previous backups (with git show or git cat-file or git unpack-file; then you may git hash-object -w to rewrite the object in your current repository.

    If the type is tree: you could use git ls-tree to recover the tree from previous backups; then git mktree to write it again in your current repository.

    If the type is commit: the same with git show, git cat-file and git commit-tree.

    Of course, I would backup your original working copy before starting this process.

    Also, take a look at How to Recover Corrupted Blob Object.