From: Igor Djordjevic <igor.d.djordjevic@gmail.com>
To: Johannes Schindelin <Johannes.Schindelin@gmx.de>,
Sergey Organov <sorganov@gmail.com>
Cc: git@vger.kernel.org, Johannes Sixt <j6t@kdbg.org>,
Junio C Hamano <gitster@pobox.com>,
Jacob Keller <jacob.keller@gmail.com>,
Phillip Wood <phillip.wood@dunelm.org.uk>
Subject: Re: [RFC v2] Rebasing merges: a jorney to the ultimate solution (Road Clear)
Date: Thu, 8 Mar 2018 20:58:59 +0100 [thread overview]
Message-ID: <a0cc88d2-bfed-ce7b-1b3f-3c447d2b32da@gmail.com> (raw)
In-Reply-To: <nycvar.QRO.7.76.6.1803071450511.20700@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz>
Hi Johannes,
On 07/03/2018 15:08, Johannes Schindelin wrote:
>
> > > Didn't we settle on Phillip's "perform successive three-way merges
> > > between the original merge commit and the new tips with the old tips
> > > as base" strategy?
> >
> > It seems you did, dunno exactly why.
>
> That is not true. You make it sound like I was the only one who liked
> this, and not Phillip and Buga, too.
For myself, I do actually favor Sergey`s approach in general, but
_implemented_ through what Phillip described (or a mixture of both, to
be precise). But, let me explain... :)
> > The main problem with this decision is that we still don't see how and
> > when to stop for user amendment using this method. OTOH, the original
> > has this issue carefully discussed.
>
> Why would we want to stop, unless there are merge conflicts?
Because we can reliably know that something "unusual" happened - and
by that I don`t necessarily mean "wrong", but just might be worth
user inspection.
For example, situation like this (M is made on A3 with `-s ours`,
obsoleting Bx commits):
(1) ---X8--X9 (master)
|\
| A1---A2---A3
| \
| M (topic)
| /
\-B1---B2---B3
... where we want to rebase M onto X9 is what I would call "usual
stuff", but this situation (M is still made on A3 with `-s ours`,
obsoleting Bx commits, but note cherry-picked B2'):
(2) ---X8--B2'--X9 (master)
|\
| A1---A2---A3
| \
| M (topic)
| /
\-B1---B2---B3
... where we still want to rebase M onto X9 is what we might consider
"unusual", because we noticed that something that shouldn`t be part
of the rebased merge commit (due to previous `-s ours`) actually got
in there (due to later cherry-pick), and just wanting the user to
check and confirm.
This is the major reason why I would prefer Sergey`s approach in
general... and might be I also have a good explanation on *why* it
works, but let`s get there ;)
(p.s. This is only one, but certainly not the only case)
> > "rebase sides of the merge commit and then three-way merge them back
> > using original merge commit as base"
>
> And that is also wrong, as I had proved already! Only Buga's addition made
> it robust against dropping/modifying commits, and that addition also makes
> it more complicated.
No, this is actually right, that sentence nicely describing _how_ it
works. That addition of mine was just including the correct merge
base (being the original merge commit that we are "rebasing"), and
that`s what Sergey is talking about.
> And it still has no satisfactory simple explanation why it works.
Getting there... :)
> > > - it is *very easy* to reason about, once it is pointed out that
> > > rebases and merges result in the same trees.
> >
> > The original is as easy to reason about, if not easier, especially as
> > recursive merge strategy is not being used there in new ways.
>
> So do it. I still have to hear a single-sentence, clear and obvious
> explanation why it works.
>
> And please do not describe why your original version works, because it
> does not work. Describe why the one amended with Buga's hack works.
>
> > I honestly don't see any advantages of Phillip's method over the
> > original, except personal preferences. At the same time, I have no
> > objection of using it either, provided consistency check problem is
> > solved there as well.
>
> Okay, let me reiterate then, because I do not want this point to be
> missed:
>
> Phillip's method is essentially merging the new tips into the original
> merge, pretending that the new tips were not rebased but merged into
> upstream.
>
> So it exploits the duality of the rebase and merge operation, which both
> result in identical trees (potentially after resolving merge conflicts).
>
> I cannot think of any such interpretation for your proposal augmented by
> Buga's fix-ups. And I haven't heard any such interpretation from your
> side, either.
Ok here it goes (I might be still wrong, but please bare with me).
What Sergey originally described also uses the "duality of the rebase
and merge operation", too ;) Just in a bit different way (and might
be a more straightforward one?).
Here`s a starting point, two commits A and B, merged into M:
(3) ---A
\
M
/
---B
According the "patch theory"[1] (which might not be too popular
around here, but should serve the purpose for what I`m trying to
explain), each merge commit can be "transformed" to two non-merge
commits, one on top of each of the merge parents, where new commit
brings its original merge parent commit tree to the state of the
merge commit tree:
(4) ---A---U1
---B---U2
Now, we have two new commits, U1 and U2, each having the same tree as
previous merge commit M, but representing changes in regards to
specific parents - and this is essentially what Sergey`s original
approach was using (whether he knew it, or not).
When it comes to rebasing, it`s pretty simple, too. As this:
(5) ---X1---o---o---o---o---o---X2 (master)
|\
| A1---A2---A3
| \
| M
| /
\-B1---B2---B3
... actually equals this:
(6) ---X1---o---o---o---o---o---X2 (master)
|\
| A1---A2---A3---U1
|
|
|
\-B1---B2---B3---U2
... where trees of M, U1 and U2 are same, and we can use the regular
rebase semantics and rebase it to this:
(7) ---X1---o---o---o---o---o---X2 (master)
|\
| A1'--A2'--A3'--U1'
|
|
|
\-B1'--B2'--B3'--U2'
... which is essentially this again:
(8) ---X1---o---o---o---o---o---X2 (master)
|\
| A1'--A2'--A3'
| \
| M'
| /
\-B1'--B2'--B3'
... where it is still true that trees of U1', U2' and M' are still
the same. So we managed to rebase a merge commit without ever doing a
merge :) (note that, practically, we _can_ finally even merge U1' and
U2' to produce M', it shouldn`t really matter as all the trees are
the same, so merge will be a no-op)
But, as we saw (what you`ve explained), this doesn`t really work in
case one of the sides of the merge gets "disbalanced" (so to say),
like dropping a commit (which could also happen non-interactively,
where a commit has been cherry-picked to a different branch, but
previously obsoleted by `-s ours` merge).
As observed, dropped commit could still wrongly get into final merge
commit tree (or cherry-picked commit wrongly not get there), due to
the nature of those rebased U1 and U2 temporary commits to hold all
the differences in regards to their specific merge commit parent.
A natural improvement to original idea which Sergey eventually came
up with after my findings (which you now ended up calling a hack, even,
but I would respectfully disagree), is to use original merge commit M
as a merge base for final merge of U1' and U2' - and here is why it
works, too, and why I wouldn`t consider it a hack, but a proper (and
a solid) solution.
Merge commit M is what we are rebasing, so we should have a way to
somehow learn from it, alongside U1 and U2 temporary commits - and
that is what using original merge commit M as a base does for us. It
helps us spot any "disbalances" that happened in comparison to original
merge parent trees, which is exactly what we`re interested in.
In ideal case (as per "patch theory"[1]), final merge of rebased U1'
and U2' with original merge commit M as a base would be rather simple,
too (not to say pointless again), as both U1' and U2' would have same
changes in comparison to M, namely all the changes from commit we are
rebasing from (X1 above) to commit we are rebasing to (X2 above).
But in a more complex case like this:
(9) ---X1---B2'---o---o---o---o---X2 (master)
|\
| A12--A2'---B3'
| \
| M'
| /
\-B1'--B3'---B4
..., being what we are ultimately interested in, it helps us notice
all kind of changes on our rebased merge parent branches, and act
accordingly (as shown by my previously posted test script[2]).
All this said (and hoping anyone is still reading this), to shed some
light on what I meant by "favoring Sergey`s approach in general, but
_implemented_ through what Phillip described".
I think we should use temporary commits U1 and U2, being a sound
approach backed up by the "patch theory"[1], as it helps us notice
any "disbalances" of the rebased merge commit parents trees (so we
can stop for user inspection), finally merging them with original
merge commit as a base, in order to spot additional changes on trees
of the merge commit parents we are rebasing.
But, the merging steps themselves, backed up by a need to stop for
conflict resolution as soon as one happens, should be performed
_iteratively_, like Phillip showed us... I would think :)
And, for example, that would do wonders when we introduce completely
new branch during an interactive rebase, too, for example:
(10) ---X1---B2'---o---o---o---o---X2 (master)
|\ /|\
| A1---A2---A3---U1 || A12--A2'---B3'---U1'
| \ || \
| M || M'
| / || /|
\-B1---B2---B3---U2 |\---B3'---B4-/-|---U2'
| |
\-----B1'-------/
In this situation, we would merge all temporary Ux commits using
original merge M as a merge base, and then merge _that_ resulting
tree with B1' (being a newly introduced merge commit parent), using
whatever merge base is most appropriate between the two (in this
case, X2).
So, for diagram (10) above, I guess something like this:
git merge-recursive U1' -- M U2'
tree="$(git write-tree)"
# in case of original merge being octopus, we would continue like:
# git merge-recursive $tree -- M U3'
# tree="$(git write-tree)"
# git merge-recursive $tree -- M U4'
# ... and so on, then finally:
git merge-recursive $tree -- "$(git merge-base U1' U2' B1')" B1'
# in more general case, it would be:
# git merge-recursive $tree -- "$(git merge-base <all-parents-of-new-merge-commit>)" B1'
tree="$(git write-tree)"
git tag M' "$(git log --pretty=%B -1 M | git commit-tree $tree -p B3' -p B4 -p B1')"
... where we would stop for conflict resolution after each failing
merge-recursive attempt (which is also true for producing rebased U1'
and U2' in the first place).
There, I would still need to make a test script doing this, but I
hope the concept is clear, and I`m not missing something crucial here.
Comments welcome :)
Regards, Buga
[1] https://en.wikibooks.org/wiki/Understanding_Darcs/Patch_theory
[2] https://public-inbox.org/git/f1a960dc-cc5c-e7b0-10b6-39e5516655b3@gmail.com/
next prev parent reply other threads:[~2018-03-08 19:59 UTC|newest]
Thread overview: 173+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-16 13:08 [RFC] Rebasing merges: a jorney to the ultimate solution (Road Clear) Sergey Organov
2018-02-18 4:16 ` Jacob Keller
2018-02-19 5:28 ` Sergey Organov
2018-02-19 23:44 ` Igor Djordjevic
2018-02-20 12:42 ` Sergey Organov
2018-02-27 0:07 ` Johannes Schindelin
2018-02-27 5:01 ` Sergey Organov
2018-02-27 5:30 ` Jacob Keller
2018-02-27 16:21 ` Johannes Schindelin
2018-02-27 18:55 ` Igor Djordjevic
2018-02-27 19:59 ` Igor Djordjevic
2018-02-27 23:27 ` Johannes Schindelin
2018-02-28 2:12 ` Igor Djordjevic
2018-02-28 4:35 ` Igor Djordjevic
2018-02-28 6:14 ` Sergey Organov
2018-02-28 20:53 ` Igor Djordjevic
2018-02-28 5:44 ` Sergey Organov
2018-02-28 19:42 ` Igor Djordjevic
2018-02-27 23:40 ` Igor Djordjevic
2018-02-28 0:10 ` Junio C Hamano
2018-02-28 2:35 ` Igor Djordjevic
2018-02-28 5:27 ` Sergey Organov
2018-02-28 0:36 ` Jacob Keller
2018-02-28 1:33 ` Igor Djordjevic
2018-02-28 1:43 ` Igor Djordjevic
2018-02-28 5:21 ` Sergey Organov
2018-02-28 19:09 ` Igor Djordjevic
2018-03-01 5:27 ` Sergey Organov
2018-02-28 5:19 ` Sergey Organov
2018-02-28 20:25 ` Igor Djordjevic
2018-02-28 22:17 ` Igor Djordjevic
2018-03-01 5:19 ` Sergey Organov
2018-03-01 5:39 ` Sergey Organov
2018-03-02 1:16 ` Igor Djordjevic
2018-03-02 5:40 ` Sergey Organov
2018-03-02 17:45 ` Igor Djordjevic
2018-03-02 11:17 ` [RFC] Rebasing merges: a jorney to the ultimate solution(RoadClear) Phillip Wood
2018-03-02 12:36 ` Phillip Wood
2018-03-02 16:02 ` Jacob Keller
2018-03-02 23:33 ` Igor Djordjevic
2018-03-06 10:36 ` Phillip Wood
2018-03-06 18:12 ` Johannes Schindelin
2018-03-06 19:43 ` Igor Djordjevic
2018-03-07 7:26 ` Johannes Schindelin
2018-03-08 11:20 ` Phillip Wood
2018-03-08 12:16 ` Phillip Wood
2018-03-08 16:05 ` Igor Djordjevic
2018-03-11 12:00 ` Johannes Schindelin
2018-03-11 16:33 ` Igor Djordjevic
2018-03-12 10:37 ` Johannes Schindelin
2018-03-12 12:56 ` Sergey Organov
2018-03-13 0:01 ` Igor Djordjevic
2018-03-26 12:03 ` Johannes Schindelin
2018-03-27 5:08 ` Sergey Organov
2018-03-27 13:35 ` Johannes Schindelin
2018-04-02 6:07 ` Sergey Organov
2018-03-12 23:54 ` Igor Djordjevic
2018-03-13 6:25 ` Sergey Organov
2018-03-08 15:56 ` Igor Djordjevic
2018-03-11 12:08 ` Johannes Schindelin
2018-03-11 17:34 ` Igor Djordjevic
2018-03-12 10:46 ` Johannes Schindelin
2018-03-13 0:16 ` Igor Djordjevic
2018-03-26 13:07 ` Johannes Schindelin
2018-03-27 5:51 ` Sergey Organov
2018-03-27 13:49 ` Johannes Schindelin
2018-03-28 5:57 ` Sergey Organov
2018-03-30 13:41 ` Johannes Schindelin
2018-03-30 16:36 ` Sergey Organov
2018-03-28 5:57 ` Sergey Organov
[not found] ` <CA+P7+xoDQ2mzhxeZPFhaY+TaSoKkQm=5AtoduHH06-VggOJ2jg@mail.gmail.com>
2018-03-28 11:29 ` Sergey Organov
[not found] ` <CA+P7+xo19mHrWz9Fy-ifgCcVJM2xwzcLj7F2NvFe2LwGbaJiDQ@mail.gmail.com>
2018-03-29 5:53 ` Sergey Organov
2018-03-30 10:38 ` Johannes Schindelin
2018-03-30 12:36 ` Sergey Organov
2018-03-30 13:33 ` Johannes Schindelin
2018-03-30 15:13 ` Sergey Organov
2018-03-28 12:10 ` Sergey Organov
2018-03-08 16:07 ` Jacob Keller
2018-03-11 12:11 ` Johannes Schindelin
2018-03-11 17:46 ` Igor Djordjevic
2018-03-08 15:16 ` Igor Djordjevic
2018-03-08 16:21 ` Igor Djordjevic
2018-03-11 12:22 ` Johannes Schindelin
2018-03-14 14:24 ` Sergey Organov
2018-03-14 23:11 ` Igor Djordjevic
2018-03-15 6:00 ` Sergey Organov
2018-03-15 21:51 ` Igor Djordjevic
2018-03-17 2:08 ` Igor Djordjevic
2018-03-19 5:44 ` Sergey Organov
2018-03-19 21:35 ` Igor Djordjevic
2018-03-20 14:43 ` Sergey Organov
2018-03-26 13:47 ` Johannes Schindelin
2018-03-06 23:24 ` Junio C Hamano
2018-03-07 7:09 ` Johannes Schindelin
2018-03-07 18:20 ` Junio C Hamano
2018-03-08 7:03 ` Johannes Schindelin
2018-03-08 8:11 ` Junio C Hamano
2018-03-09 17:09 ` Johannes Schindelin
2018-03-02 16:00 ` Jacob Keller
2018-03-02 18:14 ` Igor Djordjevic
2018-03-03 17:29 ` Igor Djordjevic
2018-03-05 5:35 ` Sergey Organov
2018-03-02 11:31 ` [RFC] Rebasing merges: a jorney to the ultimate solution (Road Clear) Phillip Wood
2018-03-03 0:29 ` Igor Djordjevic
2018-03-05 5:00 ` Sergey Organov
2018-03-06 10:52 ` Phillip Wood
2018-03-06 16:56 ` Junio C Hamano
2018-03-08 7:05 ` Johannes Schindelin
2018-03-08 8:18 ` Junio C Hamano
2018-03-11 11:56 ` Johannes Schindelin
2018-03-13 18:24 ` Junio C Hamano
2018-03-26 13:17 ` Johannes Schindelin
2018-03-05 17:29 ` Johannes Schindelin
2018-03-06 23:21 ` Igor Djordjevic
2018-03-07 7:04 ` Johannes Schindelin
2018-03-06 10:45 ` Phillip Wood
2018-03-06 11:45 ` Sergey Organov
2018-03-08 16:30 ` Igor Djordjevic
2018-03-06 18:12 ` Johannes Schindelin
2018-03-07 5:08 ` Sergey Organov
2018-03-07 6:58 ` Johannes Schindelin
2018-03-07 14:34 ` Sergey Organov
2018-03-08 6:45 ` Johannes Schindelin
2018-03-12 12:31 ` Sergey Organov
2018-03-26 11:37 ` Johannes Schindelin
2018-03-27 5:11 ` Sergey Organov
2018-03-27 12:55 ` Johannes Schindelin
2018-03-28 4:32 ` Sergey Organov
2018-03-08 11:08 ` Phillip Wood
2018-03-05 17:52 ` Johannes Schindelin
2018-03-13 16:10 ` Sergey Organov
2018-03-14 1:12 ` Igor Djordjevic
2018-03-14 7:21 ` Sergey Organov
2018-03-15 0:09 ` Igor Djordjevic
2018-03-15 7:52 ` Sergey Organov
2018-03-15 23:08 ` Igor Djordjevic
2018-03-16 7:31 ` Sergey Organov
2018-03-17 3:04 ` Igor Djordjevic
2018-03-19 6:01 ` Sergey Organov
2018-03-26 14:11 ` Johannes Schindelin
2018-02-28 0:29 ` Jacob Keller
2018-02-27 11:57 ` Sergey Organov
2018-02-27 18:14 ` Junio C Hamano
2018-02-28 0:30 ` Jacob Keller
2018-02-28 5:54 ` Sergey Organov
2018-02-28 4:53 ` Sergey Organov
2018-03-06 13:26 ` [RFC v2] " Sergey Organov
2018-03-07 6:46 ` Johannes Schindelin
2018-03-07 13:27 ` Sergey Organov
2018-03-07 14:08 ` Johannes Schindelin
2018-03-07 15:16 ` Sergey Organov
2018-03-08 7:01 ` Johannes Schindelin
2018-03-12 12:42 ` Sergey Organov
2018-03-26 11:50 ` Johannes Schindelin
2018-03-08 19:58 ` Igor Djordjevic [this message]
2018-03-08 20:27 ` Igor Djordjevic
2018-03-08 22:05 ` Igor Djordjevic
2018-03-08 23:31 ` Igor Djordjevic
2018-03-11 15:47 ` Johannes Schindelin
2018-03-11 20:53 ` Igor Djordjevic
2018-03-12 10:20 ` Johannes Schindelin
2018-03-12 13:49 ` Sergey Organov
2018-03-26 12:44 ` Johannes Schindelin
2018-03-27 5:32 ` Sergey Organov
2018-03-13 0:29 ` Igor Djordjevic
2018-03-26 13:58 ` Johannes Schindelin
2018-03-12 13:07 ` Sergey Organov
2018-03-11 15:40 ` Johannes Schindelin
2018-03-11 22:04 ` Igor Djordjevic
2018-03-12 12:05 ` Sergey Organov
2018-03-26 11:33 ` Johannes Schindelin
2018-03-27 5:34 ` Sergey Organov
2018-03-12 22:41 ` Igor Djordjevic
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=a0cc88d2-bfed-ce7b-1b3f-3c447d2b32da@gmail.com \
--to=igor.d.djordjevic@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=j6t@kdbg.org \
--cc=jacob.keller@gmail.com \
--cc=phillip.wood@dunelm.org.uk \
--cc=sorganov@gmail.com \
/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).