[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Implicit keep-alive after reintegrate merge

From: Stefan Sperling <stsp_at_elego.de>
Date: Mon, 30 Jan 2012 14:23:46 +0100

On Tue, Jan 24, 2012 at 01:12:39AM +0100, Branko Čibej wrote:
> By the way, I read Stefan's description of why --reintegrate is
> necessary, and after slogging through the unfortunate terminology (2-URL
> merge doesn't mean a thing in CM theory :) and one little bit caught my
> attention:
>
> > A sync merge can fill in the all parameters as well, except PATH2.
> > However, it needs to do so in a different way. With a sync merge
> > PATH1 and PATH2 are the same
>
> I keep reading this in the context of the rest of the reasoning, any my
> reaction is still: "WTF? Bogus!" This looks like someone /started off/
> with the assumption that a sync merge can take shortcuts where a
> reintegrate merge cannot; but, so sorry, that's just plain nonsense.

Oh, it's not nonsense. And there are no special shortcuts reintegrate
can take. You just misunderstood what I was writing about.

I didn't write about CM theory. I wrote about usage of Subversion.

When using svn, the term "2-URL" merge refers to a specific way of
invoking 'svn merge'. It is the most general type of invocation.
All other forms are syntactic sugar which can be represented by
equivalent 2-URL merge invocations.

Consider: svn merge ^/trunk
with mergeinfo on the current dir being: /trunk:2-6
The following 2-URL merge is the equivalent:
 svn merge ^/trunk_at_6 ^/trunk_at_HEAD .
That's all there is to it.

The same applies to "reintegrate", BTW. It is a Subversion-specific
concept that might not be represented in CM theory because it is, as you
point out, just a special case of the general merge (you didn't describe
what "merge" means in your theory so I'm just going to make assumptions).

> The cases are exactly symmetrical, all edge cases apply to both directions
> of the merge, a sync merge can encounter all the complications of a
> reintegrate merge. I'll be bold enough to assume that the keep-alive
> song-and-dance is a direct result of these invalid assumptions.
>
> Well, at least this answers the question of whether it's the model or
> the implementation that's wrong ... the answer is, that the
> implementation is misinterpreting the model. :)

Huh? I don't follow. Which model do you think is being misinterpreted?
Does the model you have in mind cleanly map to what Subversion can
represent?

> Just to make sure it's understood: When you create a branch, the origin
> of the branch is an interesting bit of information. However, for
> merging, it is entirely irrelevant if branch A was created from B or the
> other way around. To illustrate:
>
> (1)
> +- b_at_r2 ---- b_at_r3 ----
> (branch) / | (merge)
> / v
> --- a_at_r1 -------------+- a_at_r4 ----
>
> (2)
> --- a_at_r1 ----------- a_at_r3 ----
> \ | (merge)
> (branch) \ v
> +- b_at_r2 ------+- b_at_r4 ----
>
>
> Cases (1) and (2) are exactly equivalent as far as the merge algorithm
> is concerned, but Subversion calls the first a reintegrate merge and the
> second a sync merge, and treats them differently, as if branch (a) were
> somehow special. It's not.

If you always use the 2-URL merge syntax all the abstractions go away
and you'll have symmetry.

 (1) svn co a_at_r4 wc; svn merge b_at_r2 b_at_r3 a
 (2) svn co b_at_r4 wc; svn merge a_at_r1 a_at_r3 b

See? Perfectly symmetrical.

Your example is too simple, though.
You only have one change being merged either way, and no cycles.

Generally, we want to avoid spurious conflicts from diff3 which happen
when changes are applied twice because diff3 is not idempotent.
I.e. we break the nice symmetry to work around a limitation of diff3.

In the following case we can avoid spurious conflicts by picking
our parameters carefully:

     (3)
                +-b_at_r2--+ b_at_r3--b@r4-b_at_r5 ----
      (branch) / ^ | (merge 2)
              / | (merge 1) v
        --- a_at_r1 ------a_at_r2-----------+- a_at_r6 ----

Merge 1 brings a_at_r2 into b_at_r2.
Merge 2 brings b_at_r4 into a_at_r5.

 (3.1) svn co b_at_r2 wc; svn merge a_at_r1 a_at_r2 b

There are two ways of performing merge 2.
The first is symmetrical and re-applies a_at_r2 to a_at_r6, via b_at_r3,
with possible spurious conflicts from diff3:

 (3.2 a) svn co a_at_r5 wc; svn merge b_at_r2 b_at_r5 a

The second does not re-apply a_at_r2, so there are no possible conflicts
from diff3 because of a_at_r2/b_at_r3. Only b_at_r4 can conflict.

 (3.2 b) svn co a_at_r5 wc; svn merge b_at_r3 b_at_r5 a

The result is the same, however.

What we use during --reintegrate is (3.2 b).
You can argue that this approach is broken and we should be using (3.2 a)
for symmetry, and let users deal with spurious conflicts.

But (3.2 b) is always correct and more convenient if diff3 fails to
produce a conflict-free diff when b_at_r3 is applied to a_at_r5.
So why not use it?

Alternatively, do you know of a diff3 replacement that is idempotent?
Received on 2012-01-30 14:24:29 CET

This is an archived mail posted to the Subversion Dev mailing list.