Fixing a broken Git repository

After having several hard kernel crashes, some of my files ended up empty on my disk. I then got errors like:

error: object file .git/objects/81/b43db0dadcafe18eef75c60c57cc496d523d83 is empty
error: object file .git/objects/fb/9b5b3daa56c7833be66f0eaac2b5a906474627 is empty

I can recommend this Wiki page on kernel.org which tells how recovery basically should be done. This post shows some of those steps a bit more “hands-on”. I started with moving this corrupt (empty) object away, and then got this message when doing some git operations:

fatal: unable to read 81b43db0dadcafe18eef75c60c57cc496d523d83

However I had the issue that I did not know what type of object I was missing at all:

A git fsck –full showed that those commits I miss used to be blobs:

...
missing blob 81b43db0dadcafe18eef75c60c57cc496d523d83
...
missing blob fb9b5b3daa56c7833be66f0eaac2b5a906474627
...

But I did not get the “broken link from” information showed on the kernel.org how-to. So I still have to find out to which tree those blobs belong… A little shell script which I found on Github proved to be useful for this:

#!/bin/sh
obj_name="$1"
shift
git log "$@" --pretty=format:'%T %h %s' \
| while read tree commit subject ; do
 if git ls-tree -r $tree | grep -q "$obj_name" ; then
 echo $commit "$subject"
 fi
done

A run returned the commits which contain this blob:

./find-blob.sh 81b43db0dadcafe18eef75c60c57cc496d523d83
3184029 ASoC: fsl_sai_ac97: implement AC97 protocol using structs
1445893 ASoC: vf610: use common AC97 reset/warm reset

Oh well yes, this was what I was last working on… The command git ls-tree shows the tree of those commits, and here we have finally the file name associated with that commit:

$ git ls-tree -r 3184029 | grep 81b43db0dadcafe18eef75c60c57cc496d523d83
100644 blob 81b43db0dadcafe18eef75c60c57cc496d523d83 arch/arm/boot/dts/vf610-colibri.dtsi

Hm, lets see if the file in the working tree has that hash too:

$ git hash-object arch/arm/boot/dts/vf610-colibri.dtsi
81b43db0dadcafe18eef75c60c57cc496d523d83

Excellent! So I just have to write the object to the database. The -w parameter does this:

$ git hash-object -w arch/arm/boot/dts/vf610-colibri.dtsi
81b43db0dadcafe18eef75c60c57cc496d523d83

But for the second object I was not that lucky. The hash of my file doesn’t match the missing blobs hash. And my brain could not reconstruct the exact original file, which would be required to actually replace the missing file. Since only two commits were affected (the last two), and I had the changes of the last state in my working directory, I decided to get rid of those two commits and just commit the last state. To do this, I simply deleted the broken object, and ran git fsck –full. This displayed the tree objects referencing the missing objects, which I then removed from the .git/objects directory too. I repeated that about 7 times, until the commit objects appeared, which I deleted as well. Finally, I had a consistent git repository again and could commit the working state again *phu* 🙂

  1. Hi! Even if this was posted many years ago, it was helpfull beyond measure. In my scenario, I didn’t have a remote repository to re-clone or fix my corrupted git objects (as many people sugest as solution for this problem).

    Thank you very much!

Leave a Comment