Remove git corrupt blob from repository

I have a situation with a corrupt object in a repository.

$ git push
...
fatal: loose object 95b6a826cadae849f4932a71d6735ab6ceb47cab (stored in .git/objects/95/b6a826cadae849f4932a71d6735ab6ceb47cab) is corrupt
...

And I know that this objet is a blob linked to by an old commit:

$ git fsck --full
Checking object directories: 100% (256/256), done.
broken link from  tree 27e8e7d5b94c1dad5410a8204089828a167a0eaf
            to    blob 95b6a826cadae849f4932a71d6735ab6ceb47cab 

I have done the classic steps to recover the blob from the FAQ but it seems there is no other copy of it anywhere that I can find (I am working alone and haven't push to the remote for a while so it's not there) so I can't recover it.

This blob is actually the first version of a file which has been modified a lot since then. I am fine losing the information about that version of the file. So I would like just to remove it from the commit that is pointing to it. How can I do that?


OK, I figured it out myself eventually.

Short version: I amended the commit pointing to the corrupt blob to remove it from the history.

Long version: I thought that since I knew what the file was, and just wanted to make it disappear from the commit, then I could just amend the old commit. I didn't really expect it to work, but eventually it did.

I have to point out that I removed the blob in .git/objects in trying previous things, and it is possibly important into why it worked.

First, i had to know what commit it was. For that I used the command

git log --raw --all --full-history -- subdir/my-file

I found the commit was named 966a46....

Then I did the steps to amend it. Since it was an old commit, I used

git rebase -- interactive 966a46^

My editor came in with one line for each commit, and I changed "pick" to "edit" in front of the commit I wanted to modify.

The command git status showed me that the file I wanted to erase was modified:

# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   subdir/my-file

I wanted to remove it from the commit, so I did rm subdir/my-file . git status then showed me:

#       deleted:    subdir/my-file

This looked promising. So I simply committed the amended commit and continued the rebase:

git commit --all --amend
git rebase --continue

But after having rebased a few commits it failed with this error:

error: could not apply 45c2315... did some fancy things
fatal: unable to read 95b6a826cadae849f4932a71d6735ab6ceb47cab

45c2315 was the first commit in which my file was modified after having been created. Since it didn't find the previous version of the file, it just failed.

git status showed me, among other things:

# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       deleted by us:      subdir/my-file

I'm actually not sure what it means, but this commit was supposed to be the first in which the file would appear, after the fix. So I didn't want it to be deleted, but on the contrary, added to the commit! So I did

git add subdir/my-file

And surely git status showed it as a "new file".

Then I did git rebase --continue and everything went good, and the rebase was a success.

git push went then smoothly instead of failing about the broken blob.

But there were still a problem, because git fsck was still failing:

$ git fsck --full
Checking object directories: 100% (256/256), done.
broken link from    tree 27e8e7d5b94c1dad5410a8204089828a167a0eaf
              to    blob 95b6a826cadae849f4932a71d6735ab6ceb47cab

And git gc failed too, when I asked him to prune everything. So I figured out the best course of action was, since I had successfully pushed before, to clone everything back in a new repository and work from there.

链接地址: http://www.djcxy.com/p/67946.html

上一篇: Android蓝牙打印

下一篇: 从存储库中删除git corrupt blob