"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Omar Polo <op@omarpolo.com>
Subject:
Re: got patch; got patch -R
To:
Stefan Sperling <stsp@stsp.name>
Cc:
Christian Weisgerber <naddy@mips.inka.de>, gameoftrees@openbsd.org
Date:
Thu, 21 Jul 2022 19:59:27 +0200

Download raw body.

Thread
Stefan Sperling <stsp@stsp.name> wrote:
> Playing around with merge(1), which is a thin wrapper around the
> RCS merge machinery, I realize now that my explanation of how a
> reverse-merge needs to be done wrong. I said the left/right versions
> need to be swapped, but it actually works as follows:
> 
> In a regular merge, the "base" is the oldest version of the file,
> and left and right are two derived, i.e. newer, versions.
> 
> Try this:
> 
> jot 10 > numbers
> jot 10 | sed s/5/five/g > numbers-left
> jot 10 | sed -e s/5/five/g -e s/6/six/g > numbers-left
> merge -p numbers-left numbers numbers-right 
> 
> The above displays the forward-merge conflict. I arbitrarily chose -left
> as the version on "our" branch of history; this content is displayed in
> the first conflict section.
> 
> To do a reverse-merge, we must pick a base which represents the "newest"
> version of the file, and use the oldest and other derived file as left
> and right inputs.
> 
> According to the merge(1) man page, the first file argument represents
> the merge target file, i.e. this should be the version of the file the
> user wants to arrive at. And when backing out the change, the file we
> want is the old "original" file, as it used to exist before the change
> was applied:

i haven't think before about the idea of "version of the file the user
wants to arrive at", in my head left and right shouldn't matter, they're
just two indipendent edit of the ancestor (or at least that's what i got
from a superficial read of the "diff3 analysis" paper), but maybe this
could explain why OpenRCS merge does the diffs in a different order?

just thinking aloud, i'm not sure.

> merge -p numbers numbers-left numbers-right 
> 
> In this command, the second argument determines which context appears
> as the merge base in the conflict marker, and the third argument
> appears in the lower conflict section.
> 
> So what got patch needs to do is the equivalent of this:
> 
> regular patch: merge -p numbers-left numbers numbers-right 
> [[[
> 1
> 2
> 3
> 4
> <<<<<<< numbers-left
> five
> 6
> =======
> five
> six
> >>>>>>> numbers-right
> 7
> 8
> 9
> 10
> ]]]
> 
> reverse patch: merge -p numbers numbers-left numbers-right 
> [[[
> 1
> 2
> 3
> 4
> <<<<<<< numbers
> 5
> 6
> =======
> five
> six
> >>>>>>> numbers-right
> 7
> 8
> 9
> 10
> ]]]
> 
> And this seems to be exactly what your proposed diff is doing, correct?

yep.  i figured out that if i want to merge back the reverse of the
patch i should use the patched blob as ancestor and the old blob as one
of the derivation of it, with the other one being of course the current
revision.  that's why -- even if maybe a bit counter-intuitively -- i'm
not reversing the patch :)

(tbf initially i just used the old blob twice and saw all the changes,
not only the ones in the patch, disappear in the result, and also tried
with the left-right swapped but didn't produced the right results, so
only one option was left...)