Note: I don't have any before-corruption clone of this repository. I believe my situation is different from others described here, because I'm missing a tree, not a blob.
What happened:
When I tried to clone a repository over LAN (via SSH), Git returned an error saying that the repository is corrupted:
remote: error: object file ./objects/2e/223ce259e9e33998d434acc778bc64b393d5d4 is empty
remote: fatal: loose object 2e223ce259e9e33998d434acc778bc64b393d5d4 (stored in ./objects/2e/223ce259e9e33998d434acc778bc64b393d5d4) is corrupt
error: git upload-pack: git-pack-objects died with error.
fatal: git upload-pack: aborting due to possible repository corruption on the remote side.
remote: aborting due to possible repository corruption on the remote side.
I've found somewhere that git fsck
can be used for diagnosing corruption, but it didn't tell me anything new:
git fsck --full
error: object file ./objects/2e/223ce259e9e33998d434acc778bc64b393d5d4 is empty
fatal: loose object 2e223ce259e9e33998d434acc778bc64b393d5d4 (stored in ./objects/2e/223ce259e9e33998d434acc778bc64b393d5d4) is corrupt
I've tried cloning the repository locally (using --no-hardlinks
) to see what happens, but I got exactly the same results.
Then I've stumbled upon this question, and the guy who answered just deleted the empty file (step 3), so i did this (i.e. i've deleted file 223ce259e9e33998d434acc778bc64b393d5d4
from subdirectory objects/2e/
).
git fsck
again, and i see:
Checking object directories: 100% (256/256), done.
broken link from tree 838e437f371c652fa4393d25473ce21cbf697d7a
to tree 2e223ce259e9e33998d434acc778bc64b393d5d4
dangling commit 54146bc0dc4eb3eede82a0405b749e05c11c5522
missing tree 2e223ce259e9e33998d434acc778bc64b393d5d4
dangling commit 864864feec207786b84158e526b2faec7799fd4e
dangling blob d3cfd7cc7718d5b76df70cf9865db01c25181bfb
So, there is now a problem with tree 838e437f37
. That's not what happened to the guy mentioned above, so I went googling and found some information from Linus.
So, I did git ls-tree 838e437f371c652fa4393d25473ce21cbf697d7a
and in the output there was a line reading:
040000 tree 2e223ce259e9e33998d434acc778bc64b393d5d4 moje
Now, "moje" is a directory (unlike the example which Linus explained, which was a file). I guess that's why next step suggested by Linus, git hash-object moje
returned fatal: Unable to hash moje
.
But anyway, there was just a small chance that it was what I needed, so I went looking further. I ran git log --raw --all --full-history -- moje/
and according to Linus' guide, there should be a commit which lists 2e223 as a SHA-2 hash of some content, but there's none. And the list ends with
fatal: unable to read source tree (2e223ce259e9e33998d434acc778bc64b393d5d4)
I tried looking at the last commit listed before that error, but I didn't find this hash. I've seen this, but it didn't help me, probably because there were some changes between the problematic version and current state of working tree.
There's one thing that may be important: inside moje/
there's a directory cli/
which is a Git repository itself (a submodule). I've looked for the problematic SHA-2 hash there, but haven't found it.
What should I do?
Use this command to get a list of the commits that contain your missing tree:
git rev-list --all | xargs -l -I '{}' sh -c 'if git ls-tree -rt {} > /dev/null 2>&1 ; then true; else git log --oneline -1 {}; git ls-tree -r -t {} | tail -1; fi'
Now you need to recreate the missing tree, by placing the exact same contents in there as you had in there back then and then adding that tree to the repo. The easiest way to do that is probably to just recreate the contents and then commit them to the repo (you can remove that commit afterwards).