git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Christian Couder <chriscool@tuxfamily.org>
Cc: git@vger.kernel.org,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>,
	Stephan Beyer <s-beyer@gmx.net>,
	Daniel Barkalow <barkalow@iabervon.org>,
	Jakub Narebski <jnareb@gmail.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Paolo Bonzini <bonzini@gnu.org>
Subject: Re: [PATCH v2 3/4] reset: add option "--merge-safe" to "git reset"
Date: Wed, 16 Sep 2009 11:37:09 -0700	[thread overview]
Message-ID: <7vfxamzqga.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: 20090916041443.3737.63217.chriscool@tuxfamily.org

Christian Couder <chriscool@tuxfamily.org> writes:

> From: Stephan Beyer <s-beyer@gmx.net>
>
> This option is nearly like "--merge" except that it is
> safer. The table below show the differences between these
> options.
>
> working index HEAD target         working index HEAD
>   B      B     A     A   --m-s      B      A     A
>                          --merge    A      A     A
>   B      B     A     C   --m-s       (disallowed)
>                          --merge    C      C     C
>
> In this table, A, B and C are some different states of
> a file. For example the first 2 lines of the table mean
> that if a file is in state B in the working tree and
> the index, and in a different state A in HEAD and in
> the target, then "git reset --merge-safe target" will
> put the file in state B in the working tree and in
> state A in the index and HEAD.

At first, I had to spend a few minutes guessing what you meant by "target"
in the table.  All the other words are well known and do not need to be
explained, but you can make it even easier to understand by updating the
sentence before the table, perhaps like:

    When running "git reset --option target" to reset the HEAD to another
    commit (as a special case "target" could be the same as HEAD), here
    is what happens to paths in various state.

As you mentioned in the proposed commit log message of the other entry,
you have a different behaviour for unmerged case.  Can you add that case
to the table as well?

The original use case of Linus's "reset --merge" was:

    $ edit ... ;# you may have some local changes to the work tree
    $ git merge/pull ...
    ... (1) it merges cleanly;
    ... (2) you see conflicts and do not commit, or
    ... (3) you resolve conflicts and commit, while leaving the earlier
    ...     modified paths alone.
    ... In any of the three cases, you inspect the result, and say
    ... "ah, crap!"
    ... You want to go back to the state before the merge, i.e.
    ... target = HEAD^ in (1) or (3) above and target = HEAD in (2).
    $ git reset --merge $target

Recall that "git merge/pull ..." step does not even touch anything if you
have a dirty index (i.e. "diff --cached" is non-empty), so any difference
between the index and HEAD to reset the failed merge away must come from
the merge itself

Immediately before you run "reset --merge" in the above sequence, you can
categorize the paths in various states this way:

  work   index  HEAD  how that path got into this state...
    A      A     A    not involved in this merge.
    B      A     A    not involved in this merge, originally modified.
    B      B     A    cleanly merged.
    B      B     B    cleanly merged (and committed if (1) or (3)).
    C      U     A    merge left conflicts

where U denotes unmerged path in the index, and C is a file in the work
tree with conflict markers.  The path had content A in HEAD before the
start of the merge that you are resetting away.

Note that the target is A in all cases in the above table.

We would want to go back to HEAD == index == target for all of these
cases, and discarding B in "cleanly merged" entries is absolutely the
right thing to do.  Clearly, --merge-safe is _not_ designed to work in
this scenario.

Don't get me wrong.  I am not saying --merge-safe is unsafe nor useless.

I am trying to show a way with an intended use-case (and the mechanical
notation you and Daniel wrote up, which is very nice to illustrate what
exactly happens) to explain how --merge works, and more importantly why
it works that way.

That is because I would like to see an intended use case of this new
feature in a bigger picture.  With the table, I can see what it does (or
at least what you wanted it to do), but it does not clearly explain what
this new mode of operation is good for, in what context it is designed
to be used, and what problem it intends to solve.  I think you find it
very clear, by reading my explanation above, what Linus's --merge is
intended to solve:

	After a (possibly conflicted) merge modified my index and my work
        tree, "reset --hard" to the commit before I started the merge will
        discard the local modifications I had in the work tree before the
        merge.  "reset --merge" was invented to let me go back to the
        state before the merge, without discarding such local changes I
        had before the merge.

I want to be able to explain to others what --merge-safe is for in a
similar way myself before I have it in my tree, and I can't (yet).

  reply	other threads:[~2009-09-16 18:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-16  4:14 [PATCH v2 0/4] "git reset --merge" related improvements Christian Couder
2009-09-16  4:14 ` [PATCH v2 1/4] reset: add a few tests for "git reset --merge" Christian Couder
2009-09-16  4:14 ` [PATCH v2 2/4] reset: use "unpack_trees()" directly instead of "git read-tree" Christian Couder
2009-09-16  4:14 ` [PATCH v2 3/4] reset: add option "--merge-safe" to "git reset" Christian Couder
2009-09-16 18:37   ` Junio C Hamano [this message]
2009-09-17  3:54     ` Christian Couder
2009-09-17  5:23       ` Junio C Hamano
2009-09-16  4:14 ` [PATCH v2 4/4] reset: add test cases for "--merge-safe" option Christian Couder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vfxamzqga.fsf@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=barkalow@iabervon.org \
    --cc=bonzini@gnu.org \
    --cc=chriscool@tuxfamily.org \
    --cc=git@vger.kernel.org \
    --cc=jnareb@gmail.com \
    --cc=s-beyer@gmx.net \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).