{"thread":{"id":"35521","subject":"[Question] Git recovery with HEAD commit broken","startedAt":"2013-12-11T14:38:37Z","lastAt":"2013-12-11T19:12:07Z","messageCount":4,"participants":["Shilong Wang","Matthieu Moy","Joey Hess","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"231918","messageId":"CAP9B-Q=ARp00Bj5zJ0J=3qv9R16YGu5AZgLpqoO0y+cY1at1Zw@mail.gmail.com","threadId":"35521","inReplyTo":null,"subject":"[Question] Git recovery with HEAD commit broken","fromName":"Shilong Wang","fromEmail":"wangshilong1991@gmail.com","sentAt":"2013-12-11T14:38:37Z","receivedAt":"2013-12-11T14:38:37Z","isPatch":false,"sender":{"key":"wangshilong1991@gmail.com","avatar":null},"body":"I am not a developer for git, but i am a regular user with git, i came\nthe following problem:\n\nA power off cause my top commit broken, and then git\nbranch/log/reflog..etc won't work.\nI do a hack that i change the HEAD commit to the one that i can make\nsure is right, and then\ni do:\n\n# git reset --hard HEAD\n\nIn fact, i hope git fsck can fix up such problems(maybe can backup top\ncommit for example)...\nSomeone has faced such problems or have some suggestion for this?\n\nThanks,\nWang\n"},{"id":"231919","messageId":"vpqzjo7whwj.fsf@anie.imag.fr","threadId":"35521","inReplyTo":"CAP9B-Q=ARp00Bj5zJ0J=3qv9R16YGu5AZgLpqoO0y+cY1at1Zw@mail.gmail.com","subject":"Re: [Question] Git recovery with HEAD commit broken","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2013-12-11T15:01:48Z","receivedAt":"2013-12-11T15:01:48Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Shilong Wang <wangshilong1991@gmail.com> writes:\n\n> A power off cause my top commit broken, and then git\n> branch/log/reflog..etc won't work.\n\nWith a bit of luck, the reflog actually contain useful information. Look\nat .git/logs/HEAD (or refs/heads/* instead of HEAD for branches'\nreflog). It's a human-readable text format. You should be able to walk\nup the history looking for a good commit.\n\n> I do a hack that\n\nBefore anything else: do a backup of your full repository while it's\nstill time.\n\n> i change the HEAD commit to the one that i can make sure is right,\n\n(don't forget to run \"git fsck\" to make sure that not only the commit\nbut also its ancestry is right).\n\n> In fact, i hope git fsck can fix up such problems(maybe can backup top\n> commit for example)...\n\nNot as far as I know. But \"git fsck\" has a --lost-found option that can\nhelp recovering unreachable (dangling) commits.\n\nYou may have a look at http://hackage.haskell.org/package/git-repair but\nI do not think it would solve your particular case.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"231922","messageId":"20131211161407.GA15939@kitenet.net","threadId":"35521","inReplyTo":"vpqzjo7whwj.fsf@anie.imag.fr","subject":"Re: [Question] Git recovery with HEAD commit broken","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2013-12-11T16:14:07Z","receivedAt":"2013-12-11T16:14:07Z","isPatch":false,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"Matthieu Moy wrote:\n> Not as far as I know. But \"git fsck\" has a --lost-found option that can\n> help recovering unreachable (dangling) commits.\n> \n> You may have a look at http://hackage.haskell.org/package/git-repair but\n> I do not think it would solve your particular case.\n\nWell, let's find out.. I corrupted .git/refs/heads/master to refer to a\ncommit that does not exist. The history has a few prior commits.\n\njoey@darkstar:/tmp/yy>git fsck\nChecking object directories: 100% (256/256), done.\nerror: HEAD: invalid sha1 pointer\n10814e97cc8bf5f6f8ce0c0d5302f778c09cac88\nerror: refs/heads/master does not point to a valid object!\nnotice: No default references\n\njoey@darkstar:/tmp/yy>~/src/git-repair/git-repair \nRunning git fsck ...\nInitialized empty Git repository in /home/joey/tmp/tmprepo.0/.git/\n1 missing objects could not be recovered!\nTo force a recovery to a usable state, retry with the --force parameter.\n- exit 1\n\nIf there had been a remote that had the missing\n10814e97cc8bf5f6f8ce0c0d5302f778c09cac88 commit, it would have cloned\nit from there, and this would have succeeded. But with a fully missing\ncommit, --force is needed to enable more destructive repairs.\n\njoey@darkstar:/tmp/yy>~/src/git-repair/git-repair --force\nRunning git fsck ...\nInitialized empty Git repository in /home/joey/tmp/tmprepo.0/.git/\nfatal: bad object refs/heads/master\nfatal: bad object refs/heads/master\nfatal: bad object refs/heads/master\nDeleted these local branches, which could not be recovered due to missing objects:\n\trefs/heads/master\nYou 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!\nSuccessfully recovered repository!\nPlease carefully check that the changes mentioned above are ok..\n\nHmm, that could have gone better. While it successfully detected the broken\nHEAD, and removed that ref, which is enough to make git fsck pass[1],\nit failed to find the old ref in the reflog, despite containing code\nthat walks up it to find a usable commit.\n\njoey@darkstar:/tmp/yy>git reflog\nfatal: bad default revision 'HEAD'\n\nAnd that's why.. git-reflog requires a valid HEAD to work. Bit of a catch-22.\nI could work around this by manually parsing the reflog. It would not be\nthe first thing git-repair has to re-implement because the git command\nisn't robust enough[2]. \n\nI have made a TODO about this.\nOTOH, if a kind git developer would like to make git-reflog work when HEAD\nis missing, that seems like a generally useful improvement..\n\n-- \nsee shy jo\n\n[1] It will make fsck pass 100% of the time -- its test suite randomly\n    corrupts repositories and checks that it can force some repair good\n    enough to make git fsck pass.\n[2] A particularly annoying one is that git branch -d cannot be used\n    to remove a branch that is directly pointing to a corrupted commit!\n"},{"id":"231925","messageId":"20131211191207.GL2311@google.com","threadId":"35521","inReplyTo":"20131211161407.GA15939@kitenet.net","subject":"Re: [Question] Git recovery with HEAD commit broken","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2013-12-11T19:12:07Z","receivedAt":"2013-12-11T19:12:07Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Joey Hess wrote:\n\n> [2] A particularly annoying one is that git branch -d cannot be used\n>     to remove a branch that is directly pointing to a corrupted commit!\n\nIt's generally considered okay for everyday commands like \"git branch -d\"\nnot to cope well with corrupted repositories, but we try to keep\nplumbing like \"git update-ref -d\" working to give people a way out.\nIs update-ref -d broken in this situation, too?\n\nCurious,\nJonathan\n"}]}