* How to recover a lost commit...
@ 2010-11-11 16:29 Patrick Doyle
2010-11-11 16:49 ` Seth Robertson
2010-11-11 16:50 ` Jonathan Nieder
0 siblings, 2 replies; 8+ messages in thread
From: Patrick Doyle @ 2010-11-11 16:29 UTC (permalink / raw)
To: git
Help, I'm in a maze of twisty passages all alike...
Background: I just switched our project repository from SVN to git. I
realized once I completed that that I had some work in progress on my
local machine that I had not checked in. So I created a branch off of
master, copied the modified files into that branch, checked them in,
and switched back to master, where I did some other work.
Today I want to pick up where I left off with the work-in-progress (on
the "svn_to_git_wip" branch). What I _really_ wanted to do was to
grab the contents of that branch, dump them into my working directory
for the master branch, and continue as if nothing had happened. (This
is exactly the use case for which git-stash was created, and I
probably should have used that to begin with.)
So today I flailed around trying a couple of different approaches for
getting the work-in-progress (WIP) branch applied to the master
branch, without an associated commit, because I'm not ready to commit.
As I was flailing, at one point I switched to the WIP branch, and
tried a rebase, to get it up to date wrt master.
I've just noticed however, that my work in progress, no longer seems
to be there, and I'm at a loss to understand why it disappeared. I've
tried various checkouts to get it back (the commit containing it was
286f167). I know I can recover from this by grabbing the original
commit. I can also recover from this by grabbing the 1/2 dozen files
from the old SVN directory (which I've kept around just because I'm
paranoid like that).
But I'm curious... given the reflog show below... can any of you tell
what I did to myself to shoot myself in the foot? Aside from "use git
stash next time dummy", is there any way I could have avoided this?
--wpd
$ git reflog
ce11719... HEAD@{0}: checkout: moving from master to svn_to_git_wip
40070a1... HEAD@{1}: checkout: moving from svn_to_git_wip to master
ce11719... HEAD@{2}: ce11719: updating HEAD
286f167... HEAD@{3}: 286f167: updating HEAD
d8c9d02... HEAD@{4}: checkout: moving from master to svn_to_git_wip
40070a1... HEAD@{5}: checkout: moving from
286f167944ee019c07885b3f0fbe46efd2dc68b2 to master
286f167... HEAD@{6}: checkout: moving from master to 286f167
40070a1... HEAD@{7}: checkout: moving from svn_to_git_wip to master
d8c9d02... HEAD@{8}: checkout: moving from master to svn_to_git_wip
40070a1... HEAD@{9}: checkout: moving from svn_to_git_wip to master
d8c9d02... HEAD@{10}: HEAD^: updating HEAD
ce11719... HEAD@{11}: checkout: moving from master to svn_to_git_wip
40070a1... HEAD@{12}: commit: Rebaselined nccov reports based on errmon changes
cb98d3f... HEAD@{13}: checkout: moving from svn_to_git_wip to master
ce11719... HEAD@{14}: rebase: updating HEAD
3638aa3... HEAD@{15}: checkout: moving from svn_to_git_wip to
3638aa3f6e8496b5415ab59bec2a7af07b8ed169
3638aa3... HEAD@{16}: checkout: moving from master to svn_to_git_wip
cb98d3f... HEAD@{17}: checkout: moving from svn_to_git_wip to master
3638aa3... HEAD@{18}: checkout: moving from master to svn_to_git_wip
cb98d3f... HEAD@{19}: checkout: moving from svn_to_git_wip to master
3638aa3... HEAD@{20}: checkout: moving from svn_to_git_wip to svn_to_git_wip
3638aa3... HEAD@{21}: checkout: moving from svn_to_git_wip to svn_to_git_wip
3638aa3... HEAD@{22}: HEAD^: updating HEAD
d8c9d02... HEAD@{23}: checkout: moving from svn_to_git_wip to svn_to_git_wip
d8c9d02... HEAD@{24}: HEAD^: updating HEAD
ce11719... HEAD@{25}: checkout: moving from master to svn_to_git_wip
cb98d3f... HEAD@{26}: checkout: moving from svn_to_git_wip to master
ce11719... HEAD@{27}: HEAD^: updating HEAD
286f167... HEAD@{28}: checkout: moving from master to svn_to_git_wip
cb98d3f... HEAD@{29}: commit: errmon now manages cmp{low,hgh}fal status bits.
ce11719... HEAD@{30}: checkout: moving from svn_to_git_wip to master
286f167... HEAD@{31}: commit: Saving WIP at the time I switched from SVN to GIT
ce11719... HEAD@{32}: checkout: moving from master to svn_to_git_wip
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to recover a lost commit...
2010-11-11 16:29 How to recover a lost commit Patrick Doyle
@ 2010-11-11 16:49 ` Seth Robertson
2010-11-11 17:34 ` Patrick Doyle
2010-11-11 16:50 ` Jonathan Nieder
1 sibling, 1 reply; 8+ messages in thread
From: Seth Robertson @ 2010-11-11 16:49 UTC (permalink / raw)
To: Patrick Doyle; +Cc: git
In message <AANLkTinfYTMKicr3V=T=scVpOte_XrmaDgVA_oMj2fYU@mail.gmail.com>, Patr
ick Doyle writes:
I've just noticed however, that my work in progress, no longer seems
to be there, and I'm at a loss to understand why it disappeared. I've
tried various checkouts to get it back (the commit containing it was
286f167).
But I'm curious... given the reflog show below... can any of you tell
what I did to myself to shoot myself in the foot? Aside from "use git
stash next time dummy", is there any way I could have avoided this?
No problem. We deal with stuff like this on #git in IRC all of the time.
$ git reflog
ce11719... HEAD@{0}: checkout: moving from master to svn_to_git_wip
40070a1... HEAD@{1}: checkout: moving from svn_to_git_wip to master
ce11719... HEAD@{2}: ce11719: updating HEAD
286f167... HEAD@{3}: 286f167: updating HEAD
d8c9d02... HEAD@{4}: checkout: moving from master to svn_to_git_wip
HEAD@{3} shows that your commit of interest was the head of
svn_to_git_wip. HEAD@{2} shows that this was changed to whatever
ce11719 points to (apparently the commit before the commit of interest).
"Updating HEAD" is often a sign of running `git reset`
What you probably want to do is:
git checkout svn_to_git_wip
git reset --hard 2867167 (or HEAD@{3} <- caution, number may have changed)
git checkout master
git merge svn_to_git_wip
You could do a three-argument rebase instead of a merge, but merge is
much simpler.
-Seth Robertson
----------------------------------------------------------------------
286f167... HEAD@{6}: checkout: moving from master to 286f167
Checking out the SHA directly--disconnected head. Nothing wrong with
that per-se, but probably not where you want to go.
ce11719... HEAD@{14}: rebase: updating HEAD
3638aa3... HEAD@{15}: checkout: moving from svn_to_git_wip to
3638aa3f6e8496b5415ab59bec2a7af07b8ed169
rebasing a disconnected head is definitely not where you want to go.
You should not in general make modifications if you are not on a branch
cb98d3f... HEAD@{26}: checkout: moving from svn_to_git_wip to master
ce11719... HEAD@{27}: HEAD^: updating HEAD
286f167... HEAD@{31}: commit: Saving WIP at the time I switched from SVN to GIT
ce11719... HEAD@{32}: checkout: moving from master to svn_to_git_wip
HEAD@{27} was your original problem. You made the commit on @{32}
then for some reason did (probably) a `git reset HEAD^` That was the
source of all of your problems. You should only use `git reset` if
you have not pushed and if you are very sure you want to get rid of a
commit or changes. It is a powerful command and with great power
comes great responsibility.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to recover a lost commit...
2010-11-11 16:29 How to recover a lost commit Patrick Doyle
2010-11-11 16:49 ` Seth Robertson
@ 2010-11-11 16:50 ` Jonathan Nieder
2010-11-11 17:39 ` Patrick Doyle
1 sibling, 1 reply; 8+ messages in thread
From: Jonathan Nieder @ 2010-11-11 16:50 UTC (permalink / raw)
To: Patrick Doyle; +Cc: git
Patrick Doyle wrote:
> But I'm curious... given the reflog show below... can any of you tell
> what I did to myself to shoot myself in the foot? Aside from "use git
> stash next time dummy", is there any way I could have avoided this?
I don't know. :) But if you still have the svn_to_git_wip branch,
you might want to try
$ git log -g svn_to_git_wip
which just shows the history of that branch.
> Today I want to pick up where I left off with the work-in-progress (on
> the "svn_to_git_wip" branch). What I _really_ wanted to do was to
> grab the contents of that branch, dump them into my working directory
> for the master branch, and continue as if nothing had happened. (This
> is exactly the use case for which git-stash was created, and I
> probably should have used that to begin with.)
Couldn't
$ git cherry-pick --no-commit svn_to_git_wip
$ git reset
or something like
$ git merge --no-commit svn_to_git_wip
$ git reset
have worked?
Hope that helps,
Jonathan
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to recover a lost commit...
2010-11-11 16:49 ` Seth Robertson
@ 2010-11-11 17:34 ` Patrick Doyle
2010-11-11 17:58 ` Jonathan Nieder
2010-11-11 17:58 ` Junio C Hamano
0 siblings, 2 replies; 8+ messages in thread
From: Patrick Doyle @ 2010-11-11 17:34 UTC (permalink / raw)
To: Seth Robertson; +Cc: git
On Thu, Nov 11, 2010 at 11:49 AM, Seth Robertson <in-gitvger@baka.org> wrote:
> -Seth Robertson
>
> HEAD@{27} was your original problem. You made the commit on @{32}
> then for some reason did (probably) a `git reset HEAD^` That was the
> source of all of your problems. You should only use `git reset` if
> you have not pushed and if you are very sure you want to get rid of a
> commit or changes. It is a powerful command and with great power
> comes great responsibility.
>
Hello Seth,
Thank you for your reply and cogent explanation. Yes, in fact, I did
do a "git reset HEAD^". Somewhere along the way, I decided that was a
way to make my working copy look like it did prior to a commit.
I thought that git reset only affected HEAD. I didn't realize that it
also affected the branch pointer.
Your "great power, great responsibility" comment will make me treat
"git reset" with a lot more fear and respect.
It is confusing though, because I frequently see advice (such as that
offered by Jonathan Nieder (and very much appreciated, by the way) to
do things like:
$ git merge --no-commit
$ git reset
Why is that "git reset" benign, when the "git reset HEAD^" wasn't benign before?
--wpd
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to recover a lost commit...
2010-11-11 16:50 ` Jonathan Nieder
@ 2010-11-11 17:39 ` Patrick Doyle
0 siblings, 0 replies; 8+ messages in thread
From: Patrick Doyle @ 2010-11-11 17:39 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: git
On Thu, Nov 11, 2010 at 11:50 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Couldn't
>
> $ git merge --no-commit svn_to_git_wip
> $ git reset
>
> have worked?
Hi Jonathan,
Thanks. That's where I started (although I also added the --no-ff
flag to the git-merge command) , but then I decided to get fancy and
switched to the svn_to_git_wip branch and rebase it on master first.
In hindsight, I was trying to be to clever for my own good. But I
figured I could always undo any mistakes. I was just surprised to
find that my work-in-progress had disappeared despite the fact that I
hadn't done a commit. (It's possible/likely that I did an implicit
commit when I was playing with rebase.)
Anyway, next time I'll use git-stash, and in the future, I'll be much
more paranoid about using git-reset.
--wpd
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to recover a lost commit...
2010-11-11 17:34 ` Patrick Doyle
@ 2010-11-11 17:58 ` Jonathan Nieder
2010-11-11 18:19 ` Patrick Doyle
2010-11-11 17:58 ` Junio C Hamano
1 sibling, 1 reply; 8+ messages in thread
From: Jonathan Nieder @ 2010-11-11 17:58 UTC (permalink / raw)
To: Patrick Doyle; +Cc: Seth Robertson, git
Patrick Doyle wrote:
> Thank you for your reply and cogent explanation. Yes, in fact, I did
> do a "git reset HEAD^". Somewhere along the way, I decided that was a
> way to make my working copy look like it did prior to a commit.
>
> I thought that git reset only affected HEAD. I didn't realize that it
> also affected the branch pointer.
Right. In general, git operations that update HEAD also tend to take
the current branch along with them. So:
# update the current branch to include a new commit
git commit
# update the current branch to include a change from another branch
git cherry-pick --ff $rev
# update the current branch to incorporate the history of another branch
git merge $rev
# reset the current branch head to match _that_ commit
git reset --keep $rev
# only reset the current branch head; index and worktree will be untouched
git reset --soft $rev
If you want to use such an operation without updating a certain
branch, then switch to a different branch.
# switch branches: we are following 'topic' now
git checkout topic
# detach from all branches: we are building unanchored history now
git checkout HEAD^0
See the section DETACHED HEAD from the "git checkout" manual for details.
> Your "great power, great responsibility" comment will make me treat
> "git reset" with a lot more fear and respect.
Once you're used to it, it is not so scary. If you pass paths to
"git reset", it will not change HEAD; instead, it changes the content
registered in the index:
git reset some-crazy-old-commit -- foo.c bar.c baz.c
git diff --cached
If you do not pass paths, it will update HEAD to point to the specified
commit.
# the last commit was bad; discard it
git reset --keep HEAD^
# I'm totally lost. Let's just start over, based on the version
# that worked from yesterday.
git reset --hard @{yesterday}
# specialized operation: the tracked content of all files should
# be used as a single commit on top of some other revision
git reset --soft $new_parent
git commit
# less strange way to do about the same thing
git reset $new_parent
git diff; # looks good?
git add -u
git commit
If you do not pass paths and do not pass a revision arg, this means
you wanted to update HEAD to point to the commit it is already at.
In other words, with --soft or --keep this is basically a noop, with
--hard it discards any changes in working-tree files you haven't
committed, with no operation mode arg it makes the index match the
HEAD commit.
> $ git merge --no-commit
> $ git reset
>
> Why is that "git reset" benign, when the "git reset HEAD^" wasn't benign before?
There should be a revision argument after "git merge --no-commit".
This "git reset" is equivalent to "git reset HEAD": it resets the
index to match the current commit, so the changes applied by the
merge appear as local changes.
Regards,
Jonathan
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to recover a lost commit...
2010-11-11 17:34 ` Patrick Doyle
2010-11-11 17:58 ` Jonathan Nieder
@ 2010-11-11 17:58 ` Junio C Hamano
1 sibling, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2010-11-11 17:58 UTC (permalink / raw)
To: Patrick Doyle; +Cc: Seth Robertson, git
Patrick Doyle <wpdster@gmail.com> writes:
> $ git merge --no-commit
> $ git reset
>
> Why is that "git reset" benign, when the "git reset HEAD^" wasn't benign before?
The former is resetting the index to HEAD (your latest commit), while the
latter is resetting the index to HEAD^ (the one before that, discarding
your latest commit), no?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to recover a lost commit...
2010-11-11 17:58 ` Jonathan Nieder
@ 2010-11-11 18:19 ` Patrick Doyle
0 siblings, 0 replies; 8+ messages in thread
From: Patrick Doyle @ 2010-11-11 18:19 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Seth Robertson, git
On Thu, Nov 11, 2010 at 12:58 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Right. In general, git operations that update HEAD also tend to take
> the current branch along with them.
Ahhhh.... that's the missing piece, errr, one of the missing pieces,
to my puzzled brain.
So
$ git reset HEAD
updates HEAD (and whatever branch we are currently on) to point to
HEAD. Except for mucking with the index, that seems pretty benign.
$ git reset HEAD^
updates HEAD (and whatever branch we are currently on) to point to
HEAD^, thus backing everything up by 1 commit. As you pointed out,
this is dangerous/not a good idea/ if I've already pushed my
repository someplace.
In my particular case, after doing the "git reset HEAD^" on my
svn_to_git_wip branch, I later tried to switch back to master ("git
checkout master"). Git warned me about files that were not up to date
and refused to merge (but I thought I was checking out, not merging).
Since I knew what I was doing (we all know how sadly lacking in truth
that statement is now, don't we), I "git reset --hard" those files
(thus discarding my changes) and proceeded to check out master.
Light dawns on marble head.
Thanks again.
--wpd
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-11-11 18:19 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-11 16:29 How to recover a lost commit Patrick Doyle
2010-11-11 16:49 ` Seth Robertson
2010-11-11 17:34 ` Patrick Doyle
2010-11-11 17:58 ` Jonathan Nieder
2010-11-11 18:19 ` Patrick Doyle
2010-11-11 17:58 ` Junio C Hamano
2010-11-11 16:50 ` Jonathan Nieder
2010-11-11 17:39 ` Patrick Doyle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).