monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Monotone-devel] Automatic (and incorrect) resolution of an ambiguou


From: William Uther
Subject: Re: [Monotone-devel] Automatic (and incorrect) resolution of an ambiguous merge (monotone 0.35)
Date: Wed, 1 Aug 2007 17:16:12 +1000


On 01/08/2007, at 12:57 AM, Daniel THOMPSON wrote:

We stumbled upon this small issue with the monotone merge algorithm the
other day. Basically we created divergence where one branch replaced a
line and the other branch, immediately after the replaced line, inserted
some new code. The resolution of such a conflict is ambiguous since it
is not possible to determine the order of the replaced line versus the
new code.

Monotone (0.35) merges changes like this without flagging a conflict
(and oddly enough by inserting the new code *before* the replaced line).

My opinion is that it should offered me the change to merge manually.

Below are instructions to reproduce. If any one wants it I can send the database before I did the merge. (you can see me backup the database in
the instructions below).

I've reproduced your test case. I can see it isn't doing what you want. This is easily replicated by copying the test case test_a_merge_8 to make a new case (e.g. test_a_merge_9). You then alter data files in the test case as follows:

parent:
void manual_merge(void)
{
        // part 1
        if (test())
                part1();

        // part 3
        part3();
}

left:
void manual_merge(void)
{
        // part 1
        if (test())
        {
                debug_statement();
                part1();
        }
        // part 3
        part3();
}

right:
void manual_merge(void)
{
        // part 1
        if (test())
                part1();

        // part 2
        part2();

        // part 3
        part3();
}

correct: (It isn't, but if the test succeeds you've replicated the bug - and I couldn't be bothered posting the details of inverting the test)
void manual_merge(void)
{
        // part 1
        if (test())
        {
                debug_statement();
                part1();

        // part 2
        part2();
        }
        // part 3
        part3();
}


Let's label the lines in the source files:

A void manual_merge(void)
A {
A         // part 1
A         if (test())
B                 part1();
C
D         // part 3
D         part3();
D }

A void manual_merge(void)
A {
A         // part 1
A         if (test())
L1        {
L1                debug_statement();
B                 part1();
L2        }
D         // part 3
D         part3();
D }

A void manual_merge(void)
A {
A         // part 1
A         if (test())
B                 part1();
R
R         // part 2
R         part2();
C
D         // part 3
D         part3();
D }

A void manual_merge(void)
A {
A         // part 1
A         if (test())
L1        {
L1                debug_statement();
B                 part1();
R1
R1        // part 2
R1        part2();
L2        }
D         // part 3
D         part3();
D }

Note that I labelled these in such a way that all the lines with the same label are treated the same way (essentially as a block) by the merge algorithm.

The first thing to notice is that there is nothing ambiguous about L1. It is always inserted between blocks A and B. So, let's ignore that part of the merge and also collapse the blocks. We end up with the following:

Parent:
B
C
D

Left: (Replace C with L, where L is equivalent to L2 above)
B
L
D

Right: (Insert R between B and C)
B
R
C
D

Result: (Do the replacement and the insertion)
B
R
L
D

This cut down example also cleanly merges in monotone, but not in diff3.

I've committed a test case that xfails.

Will       :-}






reply via email to

[Prev in Thread] Current Thread [Next in Thread]