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

Re: Merge bug causes changesets to be applied although this should not be the case

From: Christoph Schulz <develop_at_kristov.de>
Date: Thu, 11 Apr 2013 17:29:32 +0200

Hello!

Paul Burba schrieb am Thu, 11 Apr 2013 10:45:34 -0400:

>> What do you mean exactly? The file could me marked as resolved via "svn
>> resolve" if that's what the user wants, couldn't it?
>
> I was asking what contents of the resolved file would be; not the
> mechanics of resolution. Lets assume for a moment that a conflict was
> raised. If we resolve the conflict as a no-op, then the later merge
> of r3 will still (correctly) be applied and cause a divergence between
> trunk and the branch. This is what I mean when I said raising a
> conflict might not help very much in your example.

OK. But a conflict would be raised. Currently, no conflict is raised
at all in this situation. In our case, the script aborts the merge if
there are any conflicts and does not try to resolve anything
automatically. (It tries to detect which changeset the merge operation
is in conflict with, however, but this is another story.)

What the file should contain after the conflict in the situation
described is not important in my opinion. You could always include
lines as

<<<<<<<<<<< ...
>>>>>>>>>>> ...
===========

(or however the markers are exactly written, I don't remember) in the
file where the conflict occurs. I think, however, that it is very
important to raise a conflict and to not allow the merge to happen
(see below why).

>> I was under the opinion that if I merge two or more changesets (or, more
>> generelly speaking, apply two or more patches), the following rule applies:
>> Either _all_ changes apply in some order(s) (and _any_ order produces the
>> _same_ result), or _every_ change results in a conflict. So patches are
>> either dependent on each other (in some order) or they are independent of
>> each other (in this case, they may be applied in any order). This behaviour
>> is safe, as it means that cherry-picking cannot "break" a branch in such a
>> way that you cannot merge other (missing) changesets at a later point.
>
> I've tried several times to parse the preceding paragraph, but I just
> can't make sense of what you are saying.

I'll try again :-)

Let's assume we have some file a.txt and two changes to a.txt, p1 and
p2 (which I will call "patches" in the following). Now there should be
only two possibilities:

1) p2 depends on p1, i.e. p2 can only be applied to a.txt if p1 is
applied to a.txt before

2) p2 does not depend on p1, i.e. p1 and p2 are independent of each
other, i.e. we can apply p1 to a.txt first, then p2 _or_ we can apply
p2 to a.txt first, then p1; in both cases the results must be
_identical_

With regard to 2), think e.g. of ACID transactions -- transactions are
serializable if any execution order of their elementary actions
produces the same result.

So if two patches are serializable (or independent or however you call
it), applying them in any order should produce the same result, and if
they are not, it must not be possible to apply a "depender" before its
"dependee".

My test case breaks this assumption -- I can apply either
(files1.patch, files2.patch) or (files2.patch, files1.patch) and
receive different results. So the patches are obviously not
independent of each other, and a conflict should have been raised.
However, this does not happen.

So when looking through Subversion's eyes, p1 and p2 are neither
independent of each other (as different orders produce different
results) nor are they dependent on each other (as both patches can be
applied in any order). This is unsatisfying from both a theoretical
and practical point of view.

To put it in a somewhat more general context, if I copy trunk at
revision R into another branch testing, and then continue development
in trunk until revision R', then

(a) cherry-picking _any_ revision Q in the range [R+1...R'] from
testing to trunk must not make cherry-picking _any other_ revision Q'
in the same range from testing to trunk _impossible_, regardless what
revisions in that range will yet be merged and in what order (if Q can
be merged, this means that Q is not dependent on any revision in the
range [R+1...Q-1], so it must be finally possible to merge the
revisions in that range using some unspecified ordering),

(b) _and_ if all revisions [R+1...R'] have been successfully merged
from testing to trunk in the end, the testing branch should be
_identical_ to trunk.

The test case described shows that b) is not guaranteed by Subversion.
I have another test case from the past where a) is also broken with
Subversion's internal diff3 library (but there are no problems using
external /usr/bin/diff3). This, however, is a separate issue, and
there exists a simple workaround (using /usr/bin/diff3).

Regards,

Christoph

Received on 2013-04-11 17:31:15 CEST

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