threads / discuss / 25214

git-reflog bails if branch points to bad commit

Subject: git-reflog bails if branch points to bad commit

## tl;dr

4 messages between Sep 23, 2010 and Sep 23, 2010.

replies: 3people: 2as markdown or json

Kevin Ballard· Sep 23, 2010, 20:13 UTC · lore
Attempting to use `git reflog show foo` or `git log -g foo` will bail with "bad object: foo" if the tip commit of foo is invalid. This seems incredibly non-useful. Why should reflog care if foo points to a valid commit? This bug prevents reflog from being used in a time of great need, which someone just ran into on the #git IRC channel. Their power cut out and they ended up with a corrupt commit on the tip of their branch, and they simply could not view the reflog, which would have enabled them to roll the branch back to a previous commit. Does anybody know why reflog has this behavior?
-Kevin Ballard
Ævar Arnfjörð Bjarmason· Sep 23, 2010, 20:35 UTC · re: Kevin Ballard · lore

Re: git-reflog bails if branch points to bad commit

On Thu, Sep 23, 2010 at 20:13, Kevin Ballard <kevin@sb.org> wrote:
Show 10 quoted lines
> Attempting to use `git reflog show foo` or `git log -g foo` will
> bail with "bad object: foo" if the tip commit of foo is
> invalid. This seems incredibly non-useful. Why should reflog care if
> foo points to a valid commit? This bug prevents reflog from being
> used in a time of great need, which someone just ran into on the
> #git IRC channel. Their power cut out and they ended up with a
> corrupt commit on the tip of their branch, and they simply could not
> view the reflog, which would have enabled them to roll the branch
> back to a previous commit. Does anybody know why reflog has this
> behavior?

As you say the repository is probably corrupted, and recovering from that may be hard, not much you can do with corrupted data.

Can this person provide a tar-ed copy of the repository so we can look at it and be of help, instead of speculating?

Kevin Ballard· Sep 23, 2010, 21:57 UTC · re: Ævar Arnfjörð Bjarmason · lore

Re: git-reflog bails if branch points to bad commit

On Sep 23, 2010, at 1:35 PM, Ævar Arnfjörð Bjarmason wrote:
Show 18 quoted lines
> On Thu, Sep 23, 2010 at 20:13, Kevin Ballard <kevin@sb.org> wrote:
> 
>> Attempting to use `git reflog show foo` or `git log -g foo` will
>> bail with "bad object: foo" if the tip commit of foo is
>> invalid. This seems incredibly non-useful. Why should reflog care if
>> foo points to a valid commit? This bug prevents reflog from being
>> used in a time of great need, which someone just ran into on the
>> #git IRC channel. Their power cut out and they ended up with a
>> corrupt commit on the tip of their branch, and they simply could not
>> view the reflog, which would have enabled them to roll the branch
>> back to a previous commit. Does anybody know why reflog has this
>> behavior?
> 
> As you say the repository is probably corrupted, and recovering from
> that may be hard, not much you can do with corrupted data.
> 
> Can this person provide a tar-ed copy of the repository so we can look
> at it and be of help, instead of speculating?
The person's problem was eventually resolved by finding another clone of the repository and using it to identify the bad object. However, I was able to trivially reproduce the reflog problem by making a very simple history, then modifying the ref itself to point to a bad hash (I merely incremented the hash by 1). At this point, attempting to say `git reflog show foo` was complaining "fatal: Bad object foo" even though the reflog itself is perfectly valid, and in fact the only problem in the entire repository is the ref currently points to a hash that doesn't exist in the object database.
-Kevin Ballard
Kevin Ballard· Sep 23, 2010, 23:03 UTC · re: Kevin Ballard · lore

Re: git-reflog bails if branch points to bad commit

On Sep 23, 2010, at 2:57 PM, Kevin Ballard wrote:
> At this point, attempting to say `git reflog show foo` was complaining "fatal: Bad object foo" even though the reflog itself is perfectly valid, and in fact the only problem in the entire repository is the ref currently points to a hash that doesn't exist in the object database.
It appears the problem is `git reflog show` uses the current value of the branch as the first entry in the reflog, rather than actually showing the latest entry in the reflog. It still uses the message from the latest reflog entry, but the commit hash shown is the actual value of the branch. Is there any reason for this behavior? I admit it may be confusing if the reflog for a branch doesn't actually show the current branch pointer, but that should not be possible under normal behavior, and in a corrupt repo I believe showing the reflog is more important than showing the branch pointer. If necessary, we could even make it display a warning in this case.
Curiously, when the branch points to a commit not in the reflog, running `git rev-parse master@{0}` gives me something like

warning: Log .git/logs/refs/heads/master unexpectedly ended on Thu, 23 Sep 2010 13:09:56 -0700. d73cfd127a564756f7790d2c4ae00af0126ead29

Note that the hash it shows is actually the current value of the branch rather than the latest reflog entry. Arguably, this should also use the reflog unambiguously, as again, under normal operations that should be identical to the current branch, and with a corrupt repo the user may care more about the reflog. I can't think of any scenario where I would expect master@{0} to give me back the master branch if it differs from what the reflog says.
My proposal is twofold. First, modify `git reflog show` to only show the reflog and to not even attempt to show the current commit. It may also be worth extending it to not fail when it hits a bad object, but to simply log that and continue. And second, modify master@{0} to show the reflog entry in the event where it doesn't match the current value of the branch. Any comments/suggestions on this?
-Kevin Ballard

← back to recent threads