Thread (16 messages) flat view 16 messages, 4 authors, 2018-02-28

Re: [RFC] Rebasing merges: a jorney to the ultimate solution (Road Clear)

From: Jacob Keller <hidden>
Date: 2018-02-28 00:29:28

On Tue, Feb 27, 2018 at 8:21 AM, Johannes Schindelin
[off-list ref] wrote:
Hi Jake,

On Mon, 26 Feb 2018, Jacob Keller wrote:
quoted
On Mon, Feb 26, 2018 at 4:07 PM, Johannes Schindelin
[off-list ref] wrote:
quoted
On Tue, 20 Feb 2018, Igor Djordjevic wrote:
quoted
I`m really interested in this topic, which seems to (try to) address the
only "bad feeling" I had with rebasing merges - being afraid of silently
losing amendments by actually trying to "replay" the merge (where
additional and possibly important context is missing), instead of really
"rebasing" it (somehow).
If those amendments are what you are worried about, why not address them
specifically?

In other words, rather than performing the equivalent of

        git show <merge>^! | git apply

(which would of course completely ignore if the rewritten <merge>^2
dropped a patch, amended a patch, or even added a new patch), what you
really want is to figure out what changes the user made when merging, and
what merge strategy was used to begin with.

To see what I mean, look at the output of `git show 0fd90daba8`: it shows
how conflicts were resolved. By necessity, this is more complicated than a
simple diff: it is *not* as simple as taking a diff between two revisions
and applying that diff to a third revision. There were (at least) three
revisions involved in the original merge commit, and recreating that merge
commit faithfully means to represent the essence of the merge commit
faithfully enough to be able to replay it on a new set of at least three
revisions.  That can be simplified to two-way diffs only in very, very
special circumstances, and in all other cases this simplification will
simply fall on its nose.

If the proposed solution was to extend `git apply` to process combined
diffs, I would agree that we're on to something. That is not the proposed
solution, though.

In short: while I am sympathetic to the desire to keep things simple,
the idea to somehow side-step replaying the original merge seems to be
*prone* to be flawed. Any system that cannot accommodate
dropped/changed/added commits on either side of a merge is likely to be
too limited to be useful.

The reason Sergey's solution works is because he cherry picks the
merge using each parent first, and then merges the result of those. So
each branch of the merge gets one, and then you merge the result of
those cherry-picks. This preservers amendments and changes properly,
and should result in a good solution.
I saw your patch trying to add a minimal example, and I really want to run
away screaming.

Do you have any way to describe the idea in a simple, 3-5 lines long
paragraph?

So far, I just know that it is some sort of confusing criss-cross
cherry-picking and merging and stuff, but nothing in those steps shouts
out to me what the *idea* is.
Sergey's posted explained it more in detail, at
https://public-inbox.org/git/87y3jtqdyg.fsf@javad.com/

I was mostly just attempting to re-create it in a test case to show
that it could work.
If it would be something like "recreate the old merge, with merge
conflicts and all, then generate the diff to the actual tree of the merge
commit, then apply that to the newly-generated merge", I would understand.
It's more or less:

Rebase each parent, then cherry-pick -m<N> the original merge to that
parent, then you merge the result of each cherry-pick, then use the
resulting final merged tree to create the merge pointing at the real
parents instead of the cherry-pick merges.
I would still suspect that -s ours would be a hard nut for that method,
but I would understand that idea.
The goal of the process isn't to know or understand the "-s ours"
strategy, but simply re-create the contents of the original merge
faithfully, while still preserving the changes done when rebasing the
side branches. Thus it should re-create the contents generated by "-s
ours" the first time, but it doesn't need to do or know anything
special about how the content was created.
Thanks,
Dscho
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help