{"thread":{"id":"25713","subject":"How to recover a lost commit...","startedAt":"2010-11-11T16:29:10Z","lastAt":"2010-11-11T18:19:09Z","messageCount":8,"participants":["Patrick Doyle","Seth Robertson","Jonathan Nieder","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"155703","messageId":"AANLkTinfYTMKicr3V=T=scVpOte_XrmaDgVA_oMj2fYU@mail.gmail.com","threadId":"25713","inReplyTo":null,"subject":"How to recover a lost commit...","fromName":"Patrick Doyle","fromEmail":"wpdster@gmail.com","sentAt":"2010-11-11T16:29:10Z","receivedAt":"2010-11-11T16:29:10Z","isPatch":false,"sender":{"key":"wpdster@gmail.com","avatar":null},"body":"Help, I'm in a maze of twisty passages all alike...\n\nBackground: I just switched our project repository from SVN to git.  I\nrealized once I completed that that I had some work in progress on my\nlocal machine that I had not checked in.  So I created a branch off of\nmaster, copied the modified files into that branch, checked them in,\nand switched back to master, where I did some other work.\n\nToday I want to pick up where I left off with the work-in-progress (on\nthe \"svn_to_git_wip\" branch).  What I _really_ wanted to do was to\ngrab the contents of that branch, dump them into my working directory\nfor the master branch, and continue as if nothing had happened.  (This\nis exactly the use case for which git-stash was created, and I\nprobably should have used that to begin with.)\n\nSo today I flailed around trying a couple of different approaches for\ngetting the work-in-progress (WIP) branch applied to the master\nbranch, without an associated commit, because I'm not ready to commit.\n As I was flailing, at one point I switched to the WIP branch, and\ntried a rebase, to get it up to date wrt master.\n\nI've just noticed however, that my work in progress, no longer seems\nto be there, and I'm at a loss to understand why it disappeared.  I've\ntried various checkouts to get it back (the commit containing it was\n286f167).  I know I can recover from this by grabbing the original\ncommit.  I can also recover from this by grabbing the 1/2 dozen files\nfrom the old SVN directory (which I've kept around just because I'm\nparanoid like that).\n\nBut I'm curious... given the reflog show below... can any of you tell\nwhat I did to myself to shoot myself in the foot?  Aside from \"use git\nstash next time dummy\", is there any way I could have avoided this?\n\n--wpd\n\n$ git reflog\nce11719... HEAD@{0}: checkout: moving from master to svn_to_git_wip\n40070a1... HEAD@{1}: checkout: moving from svn_to_git_wip to master\nce11719... HEAD@{2}: ce11719: updating HEAD\n286f167... HEAD@{3}: 286f167: updating HEAD\nd8c9d02... HEAD@{4}: checkout: moving from master to svn_to_git_wip\n40070a1... HEAD@{5}: checkout: moving from\n286f167944ee019c07885b3f0fbe46efd2dc68b2 to master\n286f167... HEAD@{6}: checkout: moving from master to 286f167\n40070a1... HEAD@{7}: checkout: moving from svn_to_git_wip to master\nd8c9d02... HEAD@{8}: checkout: moving from master to svn_to_git_wip\n40070a1... HEAD@{9}: checkout: moving from svn_to_git_wip to master\nd8c9d02... HEAD@{10}: HEAD^: updating HEAD\nce11719... HEAD@{11}: checkout: moving from master to svn_to_git_wip\n40070a1... HEAD@{12}: commit: Rebaselined nccov reports based on errmon changes\ncb98d3f... HEAD@{13}: checkout: moving from svn_to_git_wip to master\nce11719... HEAD@{14}: rebase: updating HEAD\n3638aa3... HEAD@{15}: checkout: moving from svn_to_git_wip to\n3638aa3f6e8496b5415ab59bec2a7af07b8ed169\n3638aa3... HEAD@{16}: checkout: moving from master to svn_to_git_wip\ncb98d3f... HEAD@{17}: checkout: moving from svn_to_git_wip to master\n3638aa3... HEAD@{18}: checkout: moving from master to svn_to_git_wip\ncb98d3f... HEAD@{19}: checkout: moving from svn_to_git_wip to master\n3638aa3... HEAD@{20}: checkout: moving from svn_to_git_wip to svn_to_git_wip\n3638aa3... HEAD@{21}: checkout: moving from svn_to_git_wip to svn_to_git_wip\n3638aa3... HEAD@{22}: HEAD^: updating HEAD\nd8c9d02... HEAD@{23}: checkout: moving from svn_to_git_wip to svn_to_git_wip\nd8c9d02... HEAD@{24}: HEAD^: updating HEAD\nce11719... HEAD@{25}: checkout: moving from master to svn_to_git_wip\ncb98d3f... HEAD@{26}: checkout: moving from svn_to_git_wip to master\nce11719... HEAD@{27}: HEAD^: updating HEAD\n286f167... HEAD@{28}: checkout: moving from master to svn_to_git_wip\ncb98d3f... HEAD@{29}: commit: errmon now manages cmp{low,hgh}fal status bits.\nce11719... HEAD@{30}: checkout: moving from svn_to_git_wip to master\n286f167... HEAD@{31}: commit: Saving WIP at the time I switched from SVN to GIT\nce11719... HEAD@{32}: checkout: moving from master to svn_to_git_wip\n"},{"id":"155706","messageId":"201011111649.oABGnjca019731@no.baka.org","threadId":"25713","inReplyTo":"AANLkTinfYTMKicr3V=T=scVpOte_XrmaDgVA_oMj2fYU@mail.gmail.com","subject":"Re: How to recover a lost commit...","fromName":"Seth Robertson","fromEmail":"in-gitvger@baka.org","sentAt":"2010-11-11T16:49:45Z","receivedAt":"2010-11-11T16:49:45Z","isPatch":false,"sender":{"key":"in-gitvger@baka.org","avatar":null},"body":"\nIn message <AANLkTinfYTMKicr3V=T=scVpOte_XrmaDgVA_oMj2fYU@mail.gmail.com>, Patr\nick Doyle writes:\n\n    I've just noticed however, that my work in progress, no longer seems\n    to be there, and I'm at a loss to understand why it disappeared.  I've\n    tried various checkouts to get it back (the commit containing it was\n    286f167).\n\n    But I'm curious... given the reflog show below... can any of you tell\n    what I did to myself to shoot myself in the foot?  Aside from \"use git\n    stash next time dummy\", is there any way I could have avoided this?\n\nNo problem.  We deal with stuff like this on #git in IRC all of the time.\n\n    $ git reflog\n    ce11719... HEAD@{0}: checkout: moving from master to svn_to_git_wip\n    40070a1... HEAD@{1}: checkout: moving from svn_to_git_wip to master\n    ce11719... HEAD@{2}: ce11719: updating HEAD\n    286f167... HEAD@{3}: 286f167: updating HEAD\n    d8c9d02... HEAD@{4}: checkout: moving from master to svn_to_git_wip\n\nHEAD@{3} shows that your commit of interest was the head of\nsvn_to_git_wip.  HEAD@{2} shows that this was changed to whatever\nce11719 points to (apparently the commit before the commit of interest).\n\n\"Updating HEAD\" is often a sign of running `git reset`\n\nWhat you probably want to do is:\n\ngit checkout svn_to_git_wip\ngit reset --hard 2867167 (or HEAD@{3} <- caution, number may have changed)\ngit checkout master\ngit merge svn_to_git_wip\n\nYou could do a three-argument rebase instead of a merge, but merge is\nmuch simpler.\n\n\t\t\t\t\t-Seth Robertson\n\n\n----------------------------------------------------------------------\n286f167... HEAD@{6}: checkout: moving from master to 286f167\n\nChecking out the SHA directly--disconnected head.  Nothing wrong with\nthat per-se, but probably not where you want to go.\n\nce11719... HEAD@{14}: rebase: updating HEAD\n3638aa3... HEAD@{15}: checkout: moving from svn_to_git_wip to\n3638aa3f6e8496b5415ab59bec2a7af07b8ed169\n\nrebasing a disconnected head is definitely not where you want to go.\nYou should not in general make modifications if you are not on a branch\n\ncb98d3f... HEAD@{26}: checkout: moving from svn_to_git_wip to master\nce11719... HEAD@{27}: HEAD^: updating HEAD\n286f167... HEAD@{31}: commit: Saving WIP at the time I switched from SVN to GIT\nce11719... HEAD@{32}: checkout: moving from master to svn_to_git_wip\n\nHEAD@{27} was your original problem.  You made the commit on @{32}\nthen for some reason did (probably) a `git reset HEAD^` That was the\nsource of all of your problems.  You should only use `git reset` if\nyou have not pushed and if you are very sure you want to get rid of a\ncommit or changes.  It is a powerful command and with great power\ncomes great responsibility.\n"},{"id":"155707","messageId":"20101111165023.GB16972@burratino","threadId":"25713","inReplyTo":"AANLkTinfYTMKicr3V=T=scVpOte_XrmaDgVA_oMj2fYU@mail.gmail.com","subject":"Re: How to recover a lost commit...","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-11T16:50:23Z","receivedAt":"2010-11-11T16:50:23Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Patrick Doyle wrote:\n\n> But I'm curious... given the reflog show below... can any of you tell\n> what I did to myself to shoot myself in the foot?  Aside from \"use git\n> stash next time dummy\", is there any way I could have avoided this?\n\nI don't know. :)  But if you still have the svn_to_git_wip branch,\nyou might want to try\n\n\t$ git log -g svn_to_git_wip\n\nwhich just shows the history of that branch.\n\n> Today I want to pick up where I left off with the work-in-progress (on\n> the \"svn_to_git_wip\" branch).  What I _really_ wanted to do was to\n> grab the contents of that branch, dump them into my working directory\n> for the master branch, and continue as if nothing had happened.  (This\n> is exactly the use case for which git-stash was created, and I\n> probably should have used that to begin with.)\n\nCouldn't\n\n\t$ git cherry-pick --no-commit svn_to_git_wip\n\t$ git reset\n\nor something like\n\n\t$ git merge --no-commit svn_to_git_wip\n\t$ git reset\n\nhave worked?\n\nHope that helps,\nJonathan\n"},{"id":"155711","messageId":"AANLkTikqBXjAf44O0QERH39rK+7nNA8uD2CwtPKJTTyV@mail.gmail.com","threadId":"25713","inReplyTo":"201011111649.oABGnjca019731@no.baka.org","subject":"Re: How to recover a lost commit...","fromName":"Patrick Doyle","fromEmail":"wpdster@gmail.com","sentAt":"2010-11-11T17:34:13Z","receivedAt":"2010-11-11T17:34:13Z","isPatch":false,"sender":{"key":"wpdster@gmail.com","avatar":null},"body":"On Thu, Nov 11, 2010 at 11:49 AM, Seth Robertson <in-gitvger@baka.org> wrote:\n>                                        -Seth Robertson\n>\n> HEAD@{27} was your original problem.  You made the commit on @{32}\n> then for some reason did (probably) a `git reset HEAD^` That was the\n> source of all of your problems.  You should only use `git reset` if\n> you have not pushed and if you are very sure you want to get rid of a\n> commit or changes.  It is a powerful command and with great power\n> comes great responsibility.\n>\n\nHello Seth,\nThank you for your reply and cogent explanation.  Yes, in fact, I did\ndo a \"git reset HEAD^\".  Somewhere along the way, I decided that was a\nway to make my working copy look like it did prior to a commit.\n\nI thought that git reset only affected HEAD.  I didn't realize that it\nalso affected the branch pointer.\n\nYour \"great power, great responsibility\" comment will make me treat\n\"git reset\" with a lot more fear and respect.\n\nIt is confusing though, because I frequently see advice (such as that\noffered by Jonathan Nieder (and very much appreciated, by the way) to\ndo things like:\n\n$ git merge --no-commit\n$ git reset\n\nWhy is that \"git reset\" benign, when the \"git reset HEAD^\" wasn't benign before?\n\n--wpd\n"},{"id":"155713","messageId":"AANLkTi=9bu1nwjFgxbXGN+4scMAgrCgmb95H8E3Nfj1x@mail.gmail.com","threadId":"25713","inReplyTo":"20101111165023.GB16972@burratino","subject":"Re: How to recover a lost commit...","fromName":"Patrick Doyle","fromEmail":"wpdster@gmail.com","sentAt":"2010-11-11T17:39:20Z","receivedAt":"2010-11-11T17:39:20Z","isPatch":false,"sender":{"key":"wpdster@gmail.com","avatar":null},"body":"On Thu, Nov 11, 2010 at 11:50 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Couldn't\n>\n>        $ git merge --no-commit svn_to_git_wip\n>        $ git reset\n>\n> have worked?\n\nHi Jonathan,\nThanks.  That's where I started (although I also added the --no-ff\nflag to the git-merge command) , but then I decided to get fancy and\nswitched to the svn_to_git_wip branch and rebase it on master first.\nIn hindsight, I was trying to be to clever for my own good.  But I\nfigured I could always undo any mistakes.  I was just surprised to\nfind that my work-in-progress had disappeared despite the fact that I\nhadn't done a commit.  (It's possible/likely that I did an implicit\ncommit when I was playing with rebase.)\n\nAnyway, next time I'll use git-stash, and in the future, I'll be much\nmore paranoid about using git-reset.\n\n--wpd\n"},{"id":"155717","messageId":"20101111175836.GD16972@burratino","threadId":"25713","inReplyTo":"AANLkTikqBXjAf44O0QERH39rK+7nNA8uD2CwtPKJTTyV@mail.gmail.com","subject":"Re: How to recover a lost commit...","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-11T17:58:36Z","receivedAt":"2010-11-11T17:58:36Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Patrick Doyle wrote:\n\n> Thank you for your reply and cogent explanation.  Yes, in fact, I did\n> do a \"git reset HEAD^\".  Somewhere along the way, I decided that was a\n> way to make my working copy look like it did prior to a commit.\n> \n> I thought that git reset only affected HEAD.  I didn't realize that it\n> also affected the branch pointer.\n\nRight.  In general, git operations that update HEAD also tend to take\nthe current branch along with them.  So:\n\n\t# update the current branch to include a new commit\n\tgit commit\n\n\t# update the current branch to include a change from another branch\n\tgit cherry-pick --ff $rev\n\n\t# update the current branch to incorporate the history of another branch\n\tgit merge $rev\n\n\t# reset the current branch head to match _that_ commit\n\tgit reset --keep $rev\n\n\t# only reset the current branch head; index and worktree will be untouched\n\tgit reset --soft $rev\n\nIf you want to use such an operation without updating a certain\nbranch, then switch to a different branch.\n\n\t# switch branches: we are following 'topic' now\n\tgit checkout topic\n\n\t# detach from all branches: we are building unanchored history now\n\tgit checkout HEAD^0\n\nSee the section DETACHED HEAD from the \"git checkout\" manual for details.\n\n> Your \"great power, great responsibility\" comment will make me treat\n> \"git reset\" with a lot more fear and respect.\n\nOnce you're used to it, it is not so scary.  If you pass paths to\n\"git reset\", it will not change HEAD; instead, it changes the content\nregistered in the index:\n\n\tgit reset some-crazy-old-commit -- foo.c bar.c baz.c\n\tgit diff --cached\n\nIf you do not pass paths, it will update HEAD to point to the specified\ncommit.\n\n\t# the last commit was bad; discard it\n\tgit reset --keep HEAD^\n\n\t# I'm totally lost.  Let's just start over, based on the version\n\t# that worked from yesterday.\n\tgit reset --hard @{yesterday}\n\n\t# specialized operation: the tracked content of all files should\n\t# be used as a single commit on top of some other revision\n\tgit reset --soft $new_parent\n\tgit commit\n\n\t# less strange way to do about the same thing\n\tgit reset $new_parent\n\tgit diff;\t# looks good?\n\tgit add -u\n\tgit commit\n\nIf you do not pass paths and do not pass a revision arg, this means\nyou wanted to update HEAD to point to the commit it is already at.\nIn other words, with --soft or --keep this is basically a noop, with\n--hard it discards any changes in working-tree files you haven't\ncommitted, with no operation mode arg it makes the index match the\nHEAD commit.\n\n> $ git merge --no-commit\n> $ git reset\n> \n> Why is that \"git reset\" benign, when the \"git reset HEAD^\" wasn't benign before?\n\nThere should be a revision argument after \"git merge --no-commit\".\n\nThis \"git reset\" is equivalent to \"git reset HEAD\": it resets the\nindex to match the current commit, so the changes applied by the\nmerge appear as local changes.\n\nRegards,\nJonathan\n"},{"id":"155716","messageId":"7vfwv7hhda.fsf@alter.siamese.dyndns.org","threadId":"25713","inReplyTo":"AANLkTikqBXjAf44O0QERH39rK+7nNA8uD2CwtPKJTTyV@mail.gmail.com","subject":"Re: How to recover a lost commit...","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-11-11T17:58:41Z","receivedAt":"2010-11-11T17:58:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Doyle <wpdster@gmail.com> writes:\n\n> $ git merge --no-commit\n> $ git reset\n>\n> Why is that \"git reset\" benign, when the \"git reset HEAD^\" wasn't benign before?\n\nThe former is resetting the index to HEAD (your latest commit), while the\nlatter is resetting the index to HEAD^ (the one before that, discarding\nyour latest commit), no?\n"},{"id":"155724","messageId":"AANLkTik_zW1ih=wF-dWTjsFhToNy1fOxy0XJXT1i1RTo@mail.gmail.com","threadId":"25713","inReplyTo":"20101111175836.GD16972@burratino","subject":"Re: How to recover a lost commit...","fromName":"Patrick Doyle","fromEmail":"wpdster@gmail.com","sentAt":"2010-11-11T18:19:09Z","receivedAt":"2010-11-11T18:19:09Z","isPatch":false,"sender":{"key":"wpdster@gmail.com","avatar":null},"body":"On Thu, Nov 11, 2010 at 12:58 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Right.  In general, git operations that update HEAD also tend to take\n> the current branch along with them.\nAhhhh.... that's the missing piece, errr, one of the missing pieces,\nto my puzzled brain.\n\nSo\n\n$ git reset HEAD\n\nupdates HEAD (and whatever branch we are currently on) to point to\nHEAD.  Except for mucking with the index, that seems pretty benign.\n\n$ git reset HEAD^\n\nupdates HEAD (and whatever branch we are currently on) to point to\nHEAD^, thus backing everything up by 1 commit.  As you pointed out,\nthis is dangerous/not a good idea/ if I've already pushed my\nrepository someplace.\n\nIn my particular case, after doing the \"git reset HEAD^\" on my\nsvn_to_git_wip branch, I later tried to switch back to master (\"git\ncheckout master\").  Git warned me about files that were not up to date\nand refused to merge (but I thought I was checking out, not merging).\nSince I knew what I was doing (we all know how sadly lacking in truth\nthat statement is now, don't we), I \"git reset --hard\" those files\n(thus discarding my changes) and proceeded to check out master.\n\nLight dawns on marble head.\n\nThanks again.\n\n--wpd\n"}]}