Thread (2 messages) flat view 2 messages, 2 authors, 2016-06-15

Re: Add 'sane' mode to 'git reset'

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: 2016-06-15 22:45:43


On Wed, 3 Dec 2008, Junio C Hamano wrote:
I think a bit more explicit description with an example command sequence
in the documentation is in order.  Here is what I managed to reconstruct
from your description.

    Let's say you have a small change in the Makefile and some other local
    changes that you would want to keep uncommitted.  Then you receive a
    pull request that you would want to respond to.  So you do this:

	$ git pull $URL $branch

    knowing that your own local changes will be safe because pull will
    refuse to clobber them if the changes in the other person did overlaps
    with it.  Let's further say that the changes did not overlap, the
    merge succeeded and you still have your own local changes.

    But after inspecting the result, you realize that you do not want this
    change after all.  That means rewinding the HEAD back to the previous
    point (i.e. ORIG_HEAD), match the index to that commit, *and* rewind
    the work tree back to the state before the merge (i.e. mostly matching
    the index except for the local changes to Makefile and a handful other
    files).  "git reset" is the command to move the HEAD.  What mode
    should you use?

    Unfortunately, the only two modes that touch the index and/or the work
    tree are --mixed and --hard.

    You do not want to use --hard, because it will discard your local
    changes.  You do not want to use --mixed either, because it will keep
    not just your local changes but also the changes the merge brought
    into your work tree.  That's when you would want to use --merge mode.

	$ git reset --merge ORIG_HEAD
Exactly.
The recovery procedure I would use in such a case (and I rarely pull while
managing git.git even though I do so in my day job) would be:

	$ git checkout -b this-needs-more-work
        $ git checkout master
No, that won't work. The second 'git checkout' does nothing, since 
'master' still has all the broken code in it.

It would have worked had you started the new branch _before_ the pull, but 
if you had that, then you wouldn't have had anything to reset anyway, 
you'd just switch back to master and get rid of the new temp-branch.

But you could probably do something like this:

	git checkout -b temp-branch ORIG_HEAD
	git branch -M master

which depends on that checkout doing the right thing.

			Linus
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help