1

I have a git repository that has several worktree directories. Sometime in the past couple of months, something has gone wrong, possibly because my computer got hung a couple of times and I had to hard restart. : (

Anyway, whenever I now try to run git gc (or, more usually, gc is run in the background when I fetch), I get the following error output:

warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
Counting objects: 1255885, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (220739/220739), done.
fatal: unable to read 12e33ebd327a094eaaf844722760cd303fe5bcc5
error: failed to run repack

I've checked and no object with that SHA exists in my .git directory. (Yes, I know to look in .git/objects/12)

I've tried to find where that SHA might be being referenced a couple of ways. First I did a recursive grep on my .git directory for both the full SHA and (just in case) all but its first 2 digits. Found nothing except log entries (in various worktree directories), reporting the same "fatal" error as above.

After doing a bunch of reading (of both various SO answers and articles on the web, particularly this one, I also grep'd the output of git verify-pack -v for the problematic SHA and found nothing there either.

I assume, from the multiple warning lines, that somewhere I have a reflog or something that is referring to that ID, but I am unable to find such a reference anywhere.

Complication: I know that one of the standard 'remedies' is simply "Re-clone the repo from the origin and start over". I'd rather not do that for a couple of reasons: I really don't want to have to rebuild all my worktrees, and; I have a few commits and branches that I can't push )(because they don't belong in the remote repo) but that are useful to me, and I would not like to lose them.

So, if at all possible, I'd like to find a way to repair this problem. Also, it would be personally satisfying (and I'd learn a lot about Git in the process — I already have!) to be able to fix it.

Any ideas?

Wilson F
  • 1,050
  • 1
  • 18
  • 34
  • torek gave me some useful pointers on how I might go about repairing my repository, and I'm going to try them when I have an opportunity. However, I'm still curious about a couple of things, so if anyone wants to weigh in with comments, I would like to know, if possible, how to find the source of the `warning`s. I was also going to ask why I can't find anything that references the missing commit, but I think I may have figured that out. – Wilson F Jan 20 '18 at 00:16

1 Answers1

1

The immediate, most basic problem is this one:

fatal: unable to read 12e33ebd327a094eaaf844722760cd303fe5bcc5

If this problem is repairable, it will be by finding a copy of the object with that hash ID, perhaps in some other Git repository. For instance, if your repository is cloned from url and you have another clone made from url (or just make a new one now), perhaps the other clone (or the one you create now) has the missing object.

In that case, you're in much better shape as you can simply extract that object from the "good" repository and insert it into the damaged one by putting it into .git/objects/12/e33ebd327a094eaaf844722760cd303fe5bcc5. That may be a matter of copying the existing loose object, or of using git unpack-objects (or extracting the original data and building a new object, i.e., there is more than one way to do this).

It's fairly likely, however, that the missing object is one that was only in this particular repository. In that case you have a much more difficult recovery process. You can make a new clone, which will have commits that you had published (pushed), and then do what you can to extract whatever objects are accessible from your damaged repository and use those to add new good commits (on whatever branches you want to continue adding to, or re-create), minus anything that depends on the now-missing object.

Note that if your missing object is in a damaged pack, you may be able to recover some or most of that pack using the -r flag to git unpack-objects. See How to unpack all objects of a git repository? and the git unpack-objects documentation.

torek
  • 330,127
  • 43
  • 437
  • 552
  • Ah, I had missed the `unpack` command. I will look into giving that a try. (In my original post, I forgot to mention that I'm getting low on disk space, so I'm going to have to free some up before I try this.) Thanks! – Wilson F Jan 19 '18 at 23:20