Just the other day one of my Git repositories developed problems and did things like this:
bombe@scandium:~/git/repo> git describe next error: Could not read 706f6f1ff3dadccab7b037736d5ebf4eeadf7ccd fatal: No tags can describe 'b39a41ddb264bbc673d731b81897583796657eca'.
git fsck
reported (among other things removed for brevity):
broken link from commit 73ba74461ca2dd1da89f322aa87035f710fe4865 to commit 706f6f1ff3dadccab7b037736d5ebf4eeadf7ccd
Fortunately, even though this commit was quite recent it was already pushed to a remote repository so the correct data had to be there. But how do I get it back?
I tried naïvely to simply remove the branch and refetch it from the remote repository but that didn’t change anything. Of course it didn’t, the broken objects would still be in Git’s object store, they are referenced from the reflog as well, and I didn’t try to fiddle around with the settings for git gc
to get it to remove objects more recent than two weeks.
Browsing the list of all available commands I stumbled upon pack-objects
and unpack-objects
which according to their respective man pages would do what I need. I cloned the remote repository next to the broken repository and started my rescue operation, after creating a copy of my broken repository:
bombe@scandium:~/git/repo> (cd ../repo2; echo 706f6f1ff3dadccab7b037736d5ebf4eeadf7ccd | git pack-objects --stdout) | git unpack-objects Enumerating objects: 1, done. Counting objects: 100% (1/1), done. Total 1 (delta 0), reused 1 (delta 0), pack-reused 0 Unpacking objects: 100% (1/1), 882 bytes | 441.00 KiB/s, done.
Well, that looked nice. Did it work? What does git fsck
say?
broken link from commit 706f6f1ff3dadccab7b037736d5ebf4eeadf7ccd to commit 0f2af3a9ceede2efed3f5a477aba1cbd7fe7f5c0
Well, that’s a success! The formerly missing/broken commit was fixed but now pointed in turn to another missing or broken commit. In my case I had to repeat above procedure a small number of times but finally git fsck
was not reporting broken links anymore and every other command once again performed like I expected it to.