ccrama
ccrama

Reputation: 754

Recover from Git unable to read blob, file now has a different hash?

I was in the middle of a git rebase, and got an error about git being unable to read cc95d5463f90fd78c4382948418b6ae5ddfb0a2a

I investigated, and found that that blob was referenced in four commits. I unpacked one of the commits and grepped the blob, and the output pointed me to the file in my repo. I have replaced the output filename with brokenfile, and dc77f57d is a commit that referenced the blob:

$ git ls-tree -r dc77f57d | grep cc95d5463f90fd78c4382948418b6ae5ddfb0a2a
100644 blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a    brokenfile

git fsck also reports:

broken link from    tree 4e6de279c5d48acc16457bf35cea9702c892ddd1
              to    blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a
...
missing blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a

I was then going to re-create the blob for the file, but the file's hash no longer matches the blob:

$ git hash-object brokenfile
695d542ba36a58012c928e999b3b5f36bbb8013d

Is there a way to recover from this state? The blob doesn't exist at all in .git/objects/, which leads me to believe it was somehow deleted during the rebase.

Thank you.

Upvotes: 2

Views: 802

Answers (2)

ccrama
ccrama

Reputation: 754

I ended up solving the issue by removing .git and re-initializing the repo. Steps in case you run into the same issue:

mv .git .git.bak  #Make a copy in case something goes wrong
git init
git remote add origin MY_REPO_URL
git fetch && git reset origin/master --mixed

--mixed on git reset will make sure it keeps your local file changes.

That's it! If you break something in this state, just copy your backup to .git and start again.

Upvotes: 1

torek
torek

Reputation: 489388

Is there a way to recover from this state?

There are two; neither are pleasant or fun.

The better one is to find some copy of the repository that does have the missing blob. There may not be any such copy, but if there is, you can just get the file out and stick it into your repository, and now all is well again. If you have some backup copies of the repository, or clones of it, just enter each one and use git cat-file -t cc95d5463f90fd78c4382948418b6ae5ddfb0a2a in each. If this tells you that the object exists and has type blob, you have found it; if it says fatal: git cat-file: could not get object info, this repository does not have the object.

(Once found, there are several ways to copy the object back to the slightly-broken repository. The simplest would be:

git cat-file -p cc95d5463f90fd78c4382948418b6ae5ddfb0a2a > /tmp/the-file
cd <path to broken repository>
git hash-object -w -t blob /tmp/the-file

The other way is to discard the bad commits, and all their descendants. (Your own method—discard the entire repository and make a new one—is just the extreme end version of this method.)

Upvotes: 3

Related Questions