git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "Björn Steinbrink" <B.Steinbrink@gmx.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>, git@vger.kernel.org
Subject: Re: Merge seems to get confused by (reverted) cherry-picks
Date: Wed, 03 Sep 2008 00:50:43 -0700	[thread overview]
Message-ID: <7vprnld5ws.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <20080903072011.GA14252@atjola.homenet> (Björn Steinbrink's message of "Wed, 3 Sep 2008 09:20:11 +0200")

Björn Steinbrink <B.Steinbrink@gmx.de> writes:

> "git merge" produces a (IMHO) wrong result, when a commit from the
> branch that is to be merged in was cherry-picked into the current branch
> and later reverted on the original branch. Basically ignoring the
> revert.

There are a few issues around 3-way merge.

One thing is, what happened in between the common ancestor and the final
results on histories before you initiate the merges does not matter.  When
doing a 3-way merge, you look only at three endpoints: your final state,
their final state and the common ancestor between the two.

Your history looks like this:

            123a456
               3-----------?
              /           /
             /           /
            0-----1-----2
         123456       123456

During the development between 0..2, your undecision might have caused the
contents of the file fluctuate back and forth many number of times, but in
the end result, you (the one who went 0..1..2) decided that for your
development, you do not have to change the contents of that path.  The
path might have been a xyzzy.h file, and you once added an extern decl of
a function because you thought a function in xyzzy.c might be needed by
another file frotz.c, but it turned out that the function can stay private
and you removed that extern decl from xyzzy.h and ended up in the same
state.

But the other person who built the history 0..3 decided that having the
change is better than not having it.  Perhaps his code does use the
function from some other place and needs an extern.

You are merging the two histories, which means by definition you trust
your decision and the other guys decision with equal weight.  And here is
another thing.

When you compare the path in question at 0 and 2, you see they are
identical.  And you are interpreting that "I say they MUST STAY THE SAME,
while they say they want to change it some way, that is a conflict".

But in 3-way merge context, you do not interpret the fact that something
is identical between 0..2 as "they MUST STAY THE SAME".  Instead, you read
it as "My history does not care what happens to that path -- if the other
guy wants to change it, I'll happily take it."

    Note.  I am not claiming that the above interpretation will always
    match what you would expect.  I am just explaining how the underlying
    concept of 3-way merge works in general.  If you think about it in a
    realistic context, such as the "extern in xyzzy.h you did not need to
    add but the other guy needed to have", you'll realize that more often
    than not, "I do not care and let the other guy decide" interpretation
    results in a more useful result.

That essentially boils down to three rules:

 (0) If both of you did not change anything, the final result won't have
     any change (obvious);

 (1) If you decided you do not have a need to change a path, but the other
     one saw a need, you take the change;

 (2) If you and the other one both wanted to change a path but in a
     different way, you need to merge at the contents level.

And you are seeing rule (1) in action.

  parent reply	other threads:[~2008-09-03  7:51 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-03  7:20 Merge seems to get confused by (reverted) cherry-picks Björn Steinbrink
2008-09-03  7:25 ` Björn Steinbrink
2008-09-03  7:50 ` Junio C Hamano [this message]
2008-09-03  8:37   ` Björn Steinbrink
2008-09-03 15:26     ` Linus Torvalds
2008-09-03  9:19   ` Ittay Dror
2008-09-03 11:04     ` Andreas Ericsson
2008-09-03 11:16     ` Johan Herland
2008-09-03 17:10       ` Mike Hommey

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

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

  git send-email \
    --in-reply-to=7vprnld5ws.fsf@gitster.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=B.Steinbrink@gmx.de \
    --cc=git@vger.kernel.org \
    --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.
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).