git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [Question] Git recovery with HEAD commit broken

From
Joey Hess <joey@kitenet.net>
Date
Dec 11, 2013, 16:14 UTC
Message-ID
<20131211161407.GA15939@kitenet.net>
In-Reply-To
<vpqzjo7whwj.fsf@anie.imag.fr>
Matthieu Moy wrote:
Show 5 quoted lines
> Not as far as I know. But "git fsck" has a --lost-found option that can
> help recovering unreachable (dangling) commits.
> 
> You may have a look at http://hackage.haskell.org/package/git-repair but
> I do not think it would solve your particular case.

Well, let's find out.. I corrupted .git/refs/heads/master to refer to a commit that does not exist. The history has a few prior commits.

joey@darkstar:/tmp/yy>git fsck Checking object directories: 100% (256/256), done. error: HEAD: invalid sha1 pointer 10814e97cc8bf5f6f8ce0c0d5302f778c09cac88 error: refs/heads/master does not point to a valid object! notice: No default references

joey@darkstar:/tmp/yy>~/src/git-repair/git-repair 
Running git fsck ...
Initialized empty Git repository in /home/joey/tmp/tmprepo.0/.git/
1 missing objects could not be recovered!
To force a recovery to a usable state, retry with the --force parameter.
- exit 1

If there had been a remote that had the missing 10814e97cc8bf5f6f8ce0c0d5302f778c09cac88 commit, it would have cloned it from there, and this would have succeeded. But with a fully missing commit, --force is needed to enable more destructive repairs.

joey@darkstar:/tmp/yy>~/src/git-repair/git-repair --force
Running git fsck ...
Initialized empty Git repository in /home/joey/tmp/tmprepo.0/.git/
fatal: bad object refs/heads/master
fatal: bad object refs/heads/master
fatal: bad object refs/heads/master
Deleted these local branches, which could not be recovered due to missing objects:
	refs/heads/master
You currently have refs/heads/master checked out. You may have staged changes in the index that can be committed to recover the lost state of this branch!
Successfully recovered repository!
Please carefully check that the changes mentioned above are ok..

Hmm, that could have gone better. While it successfully detected the broken HEAD, and removed that ref, which is enough to make git fsck pass[1], it failed to find the old ref in the reflog, despite containing code that walks up it to find a usable commit.

joey@darkstar:/tmp/yy>git reflog fatal: bad default revision 'HEAD'

And that's why.. git-reflog requires a valid HEAD to work. Bit of a catch-22. I could work around this by manually parsing the reflog. It would not be the first thing git-repair has to re-implement because the git command isn't robust enough[2].

I have made a TODO about this. OTOH, if a kind git developer would like to make git-reflog work when HEAD is missing, that seems like a generally useful improvement..

-- 
see shy jo

[1] It will make fsck pass 100% of the time -- its test suite randomly
    corrupts repositories and checks that it can force some repair good
    enough to make git fsck pass.
[2] A particularly annoying one is that git branch -d cannot be used
    to remove a branch that is directly pointing to a corrupted commit!
Previous: Matthieu MoyNext: Jonathan Nieder
Message 3 of 4 in “[Question] Git recovery with HEAD commit broken”
  1. Shilong WangDec 11, 2013
  2. Matthieu MoyDec 11, 2013
  3. Joey HessDec 11, 2013
  4. Jonathan NiederDec 11, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.