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@6 ^/trunk@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@r2 ---- b@r3 ---- > (branch) / | (merge) > / v > --- a@r1 -------------+- a@r4 ---- > > (2) > --- a@r1 ----------- a@r3 ---- > \ | (merge) > (branch) \ v > +- b@r2 ------+- b@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@r4 wc; svn merge b@r2 b@r3 a (2) svn co b@r4 wc; svn merge a@r1 a@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@r2--+ b@r3--b@r4-b@r5 ---- (branch) / ^ | (merge 2) / | (merge 1) v --- a@r1 ------a@r2-----------+- a@r6 ---- Merge 1 brings a@r2 into b@r2. Merge 2 brings b@r4 into a@r5. (3.1) svn co b@r2 wc; svn merge a@r1 a@r2 b There are two ways of performing merge 2. The first is symmetrical and re-applies a@r2 to a@r6, via b@r3, with possible spurious conflicts from diff3: (3.2 a) svn co a@r5 wc; svn merge b@r2 b@r5 a The second does not re-apply a@r2, so there are no possible conflicts from diff3 because of a@r2/b@r3. Only b@r4 can conflict. (3.2 b) svn co a@r5 wc; svn merge b@r3 b@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@r3 is applied to a@r5. So why not use it? Alternatively, do you know of a diff3 replacement that is idempotent?