From: Johan Herland <johan@herland.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: Antoine Pelisse <apelisse@gmail.com>,
Michael Haggerty <mhagger@alum.mit.edu>,
Jeff King <peff@peff.net>, git <git@vger.kernel.org>
Subject: Re: Premerging topics
Date: Wed, 24 Apr 2013 08:22:18 +0200 [thread overview]
Message-ID: <CALKQrgd8jZQ__rnAT3wbfx-Y6mg-vrTdam53nS2ya2c=yMcS6Q@mail.gmail.com> (raw)
In-Reply-To: <7vzjwofpht.fsf@alter.siamese.dyndns.org>
On Wed, Apr 24, 2013 at 7:48 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Johan Herland <johan@herland.net> writes:
>
>>> But P is a commit(/merge with two parents), not a blob. Can we have trees
>>> pointing to commits instead of blobs ?
>>
>> Sort of. We do so when recording submodules in regular git trees.
>
> You are using notes to maintain reachability, aren't you? Because
> commit objects that appears in trees are not treated as reachable
> from the trees, that won't fly.
>
> I think you guys are making it unnecessarily complex by using notes.
> To record a prepared evil merge for merging branch that contains A
> with another branch that contains B (assuming that the interation
> between A and B is what makes the evil merge necessary, e.g. A
> renames a function foo() to bar(), while B adds new callsite that
> calls foo()), we can store a single commit that records the prepared
> evil merge under "refs/merge-fix/$A-$B" where A and B are their
> object names.
>
> Then when merging a branch Y that contains B into our history X that
> already contains A (or vice versa),
>
> ---o---o---A---o---X... ???
> \ .
> \ .
> \ .
> o---B----o---Y
>
> we can enumerate the commits that appear in "log --left-right X...Y"
> on the left/right side and notice there is refs/merge-fix/$A-$B.
>
> So the simplest implementation of "an efficient data store to record
> a commit for <A,B> pair" turns out to be just a ref namespace ;-)
>
> There may be other <C,D> pairs in X...Y history, and it probably is
> the sane thing to do to replay prepackaged evil merges from older to
> newer in the topological sense, but that loop would be trivial, once
> we understand how to replay a single such evil merge.
This raises the same question I recently asked Antoine: For a given
prepackaged merge <X,Y>, do we assume that it only resolves conflicts
between the changes introduced in commit X vs. changes introduced in
commit Y, or do we assume that it resolves conflicts between the
histories leading up to X and Y, respectively? In other words, does
<X,Y> _supercede_ earlier pre-merges between the histories leading up
to X and Y?
I think the latter makes more sense, since we can then reduce the
number of pre-merges to consider in the final merge. There might still
be more than one pre-merge to consider, though, e.g. in criss-cross
cases like this:
---o---o---o---o---o---o---o---o
\ / \ \
\ / \ \
\ / \ \
o---o---o P2 \
\ \ / \
\ \ / M
\ \ / /
o---o---+---o /
\ \ \ /
\ P1 \ /
\ / \ /
o---o---o---o---o
(there is no commit at the "+")
> The actual merge-fix data should be just a commit with a single
> parent. The easiest way to prepare it would be like this:
>
> ---o---o---A
> \ \
> \ M---F
> \ /
> o---B
>
> where M is the result of mechanical merge between A and B (there
> could be textual conflicts and you could choose to leave them in, or
> you could choose to have rerere resolve it. As long as you do the
> same when replaying this prepackaged evil merge, this choice does
> not matter, but using rerere will make your life easier), and F is
> the final result you would want, with semantics conflicts resolved.
> In other words, in the ideal world, you would have resolved a merge
> between A and B to record the tree of F.
>
> Point "F" with refs/merge-fix/$A-$B and you are done.
>
> When you replay this prepackaged evil merge, first you mechanically
> merge X and Y without worrying about M or F to produce N. If you
> allowed rerere to resolve textual conflicts between A and B when you
> recorded M, allow rerere to resolve this merge. Otherwise leave the
> textual conflict in.
>
> ---o---o---A---o---X
> \ \
> \ N
> \ /
> o---B---o---Y
>
> Then on top of N, you cherry-pick F, which will bring the semantic
> conflict resolution between M and F on top of N.
>
> ---o---o---A---o---X
> \ \
> \ N---F'
> \ /
> o---B---o---Y
>
> Once you know the tree shape of F', then you no longer need N. Just
> amend it away and make the tree recorded in F' the result of the
> merge between X and Y.
>
> ---o---o---A---o---X---.
> \ \
> \ F''
> \ /
> o---B---o---Y--.
This is obviously a much better way to solve it. It might already be
obvious, but I would suggest when making "refs/merge-fix/$A-$B" that you
canonicalize the name by always choosing A and B such that A precedes B
alphabetically. That way you won't have problems with both recording
"refs/merge-fix/$A-$B" and "refs/merge-fix/$B-$A".
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
next prev parent reply other threads:[~2013-04-24 6:22 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-10 20:35 Premerging topics (was: [RFD] annnotating a pair of commit objects?) Antoine Pelisse
2013-04-22 9:23 ` Antoine Pelisse
2013-04-23 6:34 ` Johan Herland
2013-04-23 14:51 ` Antoine Pelisse
2013-04-23 23:06 ` Johan Herland
2013-04-24 5:48 ` Premerging topics Junio C Hamano
2013-04-24 6:22 ` Johan Herland [this message]
2013-04-24 7:14 ` Junio C Hamano
2013-04-29 19:06 ` Antoine Pelisse
2013-04-29 22:19 ` Junio C Hamano
2013-04-29 13:04 ` Antoine Pelisse
2013-04-29 15:08 ` Junio C Hamano
2013-04-23 14:53 ` Junio C Hamano
2013-04-23 15:17 ` Antoine Pelisse
2013-04-23 15:29 ` Junio C Hamano
2013-04-23 15:36 ` Antoine Pelisse
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='CALKQrgd8jZQ__rnAT3wbfx-Y6mg-vrTdam53nS2ya2c=yMcS6Q@mail.gmail.com' \
--to=johan@herland.net \
--cc=apelisse@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=mhagger@alum.mit.edu \
--cc=peff@peff.net \
/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).