bug-cvs
[Top][All Lists]
Advanced

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

[Fwd: [Fwd: CVS merge issue: "cvs update -j -j"]]


From: bjacob
Subject: [Fwd: [Fwd: CVS merge issue: "cvs update -j -j"]]
Date: Thu, 3 Apr 2003 19:33:08 -0800

Owen VEENSTRA writes:
> Jacob Burckhardt writes:
> > Frederic Gioanni writes:

> > When two changes conflict, a merge utility should add conflict markers
> > that show both of the changes.  But the above file shows only one of
> > the changes, namely the addition of d and e.  But it does not show the
> > deletion of b and c even though that deletion conflicted with the
> > other change.
> 
> My reading of this situation is different.  The update command has been asked 
> to
> (1) identify the change delta between rev-1 and rev-2, and (2) to insert 
> change
> delta at the appropriate point into the local clone's copy of the
> file.

That would work if it really was a clone or a copy, but it is not a
copy since it is different than rev-1

>    The
> change delta between rev-1 and rev-2 should contain the insertion of lines 
> <<d>>
> and <<e>>.  The change delta should not contain references to <<b>> or <<c>> 
> as
> they do not represent changes between rev-1 and rev.2

I agree that b,c is not a change between rev-1 and rev-2, but it is a
change between rev-1 and the local working copy.  Since that b,c
change I mentioned is at the same place in the file as the d,e change, it
is a conflict.  cvs wants to mention that one of the files had b,c and
the other did not.  That way the user can decide if perhaps b,c is
something he wants in his local working file

> 
> Consider the following CVS branch structure and consequential Venn diagrammes.
> Here the developer has a clone of V1.5, and performs the command "cvs update 
> -j
> 1.2.2.2 -j 1.2.2.3 file".
> 
>    The branch structure...
> 
> +-----+    +-----+    +-----+    +-----+    +-----+
> ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !   <- The main trunk
> +-----+    +-----+    +-----+    +-----+    +-----+
>               !
>               !
>               !   +---------+    +---------+    +---------+
>   Branch R1fix -> ! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
>                   +---------+    +---------+    +---------+
> 
> 
>    The corresponding Venn diagrammes for the above branches (relevant bits 
> only)
> ...
> 
> File@V1.5       File@V1.2.2.2   File@V1.2.2.3
> +---------+     +---------+     +---------+
> |    A    |     |    A    |     |    A    |
> +---------+     |    B    |     |    B    |
>                 |    C    |     |    C    |
>                 +---------+     |    D    |
>                                 |    E    |
>                                 +---------+
> 
> The below Venn diagramme shows the computed delta of the change from V1.2.2.2 
> to
> V1.2.2.3 ...
> 
>    Delta b/n V1.2.2.2 and V1.2.2.3
>    +---------+
>    |    D    | <= set insertion
>    |    E    | <= set insertion
>    +---------+
> 
> The below Venn diagramme shows the result of insertion of above delta above 
> into
> File @ V1.5
> 
>     +---------+
>     |    A    | <= from V1.5
>     |    D    | <= from delta
>     |    E    | <= from delta
>     +---------+

There are no conflict markers there.  But cvs correctly does put
conflict makers in it since there is a conflict since File @ V1.5
deleted text at the same place that File@V1.2.2.3 inserted text.

> > This is analogous to how the person resolving the conflict in the
> > above file will not know that anyone deleted b and c.  But suppose
> > that that deletion was a mistake.  If only the person who is resolving
> > the conflict knew that someone deleted it, then he might realize that
> > that person made a mistake.  The above file will not help him notice
> > that mistake which means the mistake would remain uncorrected.  The
> > file below is better because it does show that someone may have
> > mistakingly deleted b and c.
> 
> I disagree.
> 
> There is no concept of <<b>> or <<c>> in either V1.5, or the delta (resulting 
> from
> the difference from V1.2.2.2 to V1.2.2.3).

I think that concept is in the delta in that the delta says to insert
some text right after b,c.  But since V1.5 does not have b,c, it is
impossible to follow the instruction which says to insert after b,c.

Also, the delta from V1.2.2.2 to V1.5 is to delete b,c.  That delta
conflicted with the delta to add d,e.  They conflict because they both
involve changes on or next to line 3.  The changes are close enough that
they conflict.  Since they conflict, cvs should mention both deltas,
including the delta of deleting b,c.

> 
> As such, it should not be proposed by CVS as a part of the conflict.
> 
> > >
> > > However, "cvs up -j -j" ends with:
> > >
> > >     a
> > >     <<<<<<< file
> > >     =======
> > >     b
> > >     c
> > >     d
> > >     e
> > >     >>>>>>> rev2
> > >
> > > When resolving the conflict, the user thinks that 4 lines were added
> > > between rev1 and rev2 whereas only 2 lines were added.
> >
> > Whenever one version of a file has some text which another file does
> > not have, it can always be interpreted in two ways: either someone
> > added the text to one file or someone deleted the text from the other
> > file.  The user in your example is mistaken if he does not consider
> > both possibilities.  When cvs made the file above, cvs did not imply
> > one interpretation over another.  Therefore the user should likewise not
> > assume one interpretation must be the right one based on only seeing
> > the above file.  However, the user will have other information which can
> > help him decide which interpretation is correct.  Specially, the user
> > will remember what changes he made so he will know whether he added or
> > deleted anything.  Knowing that will help him know if the other file
> > added or deleted anything.  Therefore, he can figure out which
> > interpretation is correct.  And if he forgets what changes he made, he
> > can ask cvs to show him the complete file of rev1.  That will make it easy
> > to see whether these changes are additions or deletions.
> 
> I disagree.
> 
> CVS should not attempt to imply one interpretation from the other;

I agree.

> CVS should not
> imply anything.

I agree and I think that cvs did not imply anything.  Above, I
explained why I think it did not imply anything.

> > So, in my opinion, CVS is acting correctly.
> 
> I disagree.  In my opinion, which is based upon my reading of the CVS man and 
> info
> pages, CVS is not performing correctly in this situation.
> 
> You may will continue to state that this behavior is correct, but if so then I
> contend that this contradicts the CVS documentation.

Some of that CVS documentation says:

"... imagine that you checked out revision 1.4 and started
editing it.  In the meantime someone else committed revision 1.5, and
shortly after that revision 1.6.  If you run `update' on the file now,
CVS will incorporate all changes between revision 1.4 and 1.6 into your
file."

    "If any of the changes between 1.4 and 1.6 were made too close to any
of the changes you have made, an "overlap" occurs.  In such cases a
warning is printed, and the resulting file includes both versions of
the lines that overlap, delimited by special markers."

That documentation uses different revision numbers than your example.  For
example, the documentation uses 1.4 and 1.6 which corresponds to your
example revisions of V1.2.2.2 to V1.2.2.3.  Those changes were to add
d,e.

When the document says "changes you have made" it refers to
the changes between version 1.4 and the local working revision.  The
correspondence to your example would be the change between V1.2.2.2 and
your local working revision.  Those changes were to delete b,c.  

The documentation says that if the changes were too close, it adds the
special markers.  So the next question is whether your example had
changes that were too close.  The first change I mention above added
lines 4 and 5.  The second change I mention deleted lines 2 and 3.  So
one change involved line 4 and other change involved line 3.  Lines 4
and lines 3 are right next to each other, so I think that is
definitely "too close".  So I think it is good that cvs added the
special markers.

The document also says that "the resulting file includes both versions
of the lines that overlap".  The lines that overlap in one version are
d,e, so they should be included in the merged file.  The "lines that
overlap" in the other version are b,c, so they should be included in
the merged file.  Fredrick disagreed with the second include I just
mentioned.  But note that the documentation agrees with both of my
inclusions sense the documentation says "includes both versions".

Since I have quoted the documentation which I thought is consistent
with cvs behavior, would you please also quote the cvs documentation
which you thought was inconsistent with cvs behavior?



Often times when there is conflict, it is because two people decide to fix
the same bug in different ways.  In these cases, it is common to just
pick one of the two versions of the file to use and completely ignore the
other versions.  cvs supports this by showing both versions of the file.
Consider how this would work in your example in which cvs gave this:

    a
    <<<<<<< file
    =======
    b
    c
    d
    e
    >>>>>>> rev2

Suppose you want to take only rev2's changes and get rid of file's
changes.  I.e., keep all of the text in the rev2 section of the
conflict markers, and delete all text in the file section.  Then you
end up with the following which is the the original rev2 version:

    a
    b
    c
    d
    e

On the other hand, suppose you decide to handle it differently.
Suppose it is the other person's change you want to keep.  I.e., keep
all of the text in the file section (in this case there is no text
there), and delete all text in the rev2 section.  Then you end up with
the following which is the the original file version:

    a

So in both cases, cvs shows you how to easily take one person's version
and get rid of the other person's version.  But this does not work
with the following output which is what Fredrick expected cvs to do:

    a
    <<<<<<< file
    =======
    d
    e
    >>>>>>> rev2

If you go through the same process above of taking only the rev2
section, you get the following which is different from rev2.  I.e.,
you wanted to get rev2's exact version, but the following is not
rev2's exact version.

a
d
e

So Frederick's proposal does not allow you to see what the two
conflicting versions looked like.



Below is an example which has additions and deletions that are similar
to your example.  This is an example of a file which contains automobile
driving directions.  This file is checked into cvs, and two people edit
it concurrently:

rev1:
    To get to Maple Street, go North.
    When you get there, note that it is next
    to a preschool with students running about.

rev2:
    To get to Maple Street, go North.
    When you get there, note that it is next
    to a preschool with students running about.
    Therefore, be sure to slow down so
    you do not hit the students.

file:
    To get to Maple Street, go North.

As you can see, the person who wrote rev2, thought that additional
clarification was needed, so he added the two lines which said to
"slow down".

But the person who wrote the file revision, thought that it was
unnecessary to warn about the preschool students since any competent
driver knows to drive carefully around preschool students.  So he
decided to delete the unnecessary 2 lines warning about the preschool
students.

The delta from rev1 to rev2 is to add the two lines.  If you add those
same two lines to the file revision, you get:

    To get to Maple Street, go North.
    Therefore, be sure to slow down so
    you do not hit the students.

But that file does not make sense.  The earlier part of the file does not
mention any students, so the reader will wonder what "students" refers
to.

Fredrick would expect cvs to say:

    To get to Maple Street, go North.
    <<<<<<< file
    =======
    Therefore, be sure to slow down so
    you do not hit the students.
    >>>>>>> rev2

But the same problem exists about what "students" refers to.

But what cvs actually does is this:

    To get to Maple Street, go North.
    <<<<<<< file
    =======
    When you get there, note that it is next
    to a preschool with students running about.
    Therefore, be sure to slow down so
    you do not hit the students.
    >>>>>>> rev2

That definitely makes more sense, because you can see what "students"
refers to.

The extra two lines that rev2 adds are dependent on the previous two
lines in that revision.  The file revision deleted those two lines.
rev2 needs those lines, but file does not want those two lines, so
rev2 and file are in conflict about whether they want those two lines.
Since those two lines are in conflict, cvs should show them.  Likewise,
cvs should show the two lines b,c, since rev2 might need those lines
in order for d,e to made sense

cvs does not know that the "slow down" lines refer to the the previous
lines about the "preschool".  Only a human who understands the English
language would know that.  But cvs does know that those two lines
about "slow down" were added right after two lines which the other
file deleted.  Therefore cvs assumes that since the lines were added
right after some deleted lines, then it is a conflict.  It assumes
that since the two changes were so close together.  In my example, cvs
made a correct assumption that the changes were related.  Maybe in
your example, it was a wrong assumption.  But cvs always assumes the
worst.  I.e., it is conservative in how it goes about
auto-merging.  It does not want to auto-merge when there is even a small
chance of a conflict.  So it has to assume that adding d,e might
conflict with deleting b,c.


Here is another example using C code:

rev1:
    #include <stdio.h>
    /* function f: */
    int f() { return 1; }

rev2:
    #include <stdio.h>
    /* function f: */
    int f() { return 1; }
    /* function g: */
    int g() { return f() + 9;}

file:
    #include <stdio.h>

rev2 added two lines to define function g.

file revision deleted function f.

Maybe you want the functionality of g in the file revision, so you merge
it with -jrev1 -jrev2.  You would propose that it merge it like this:

    #include <stdio.h>
    /* function g: */
    int g() { return f() + 9;}

But when you compile it, it would say:

t.c: In function `g':
t.c:3: warning: implicit declaration of function `f'

So I would not want cvs to merge it that way since it will not compile
correctly.

Fortunately, cvs is smart enough to know that since function g is
right next to function f, it might be related.  So since the other
file deleted f, it knows that it might be a conflict.

Maybe your example was different.  Maybe you had a function g that does
not call f, which means it would have compiled in your case.  But cvs
cannot be expected to know that function g does not depend on function
f.




reply via email to

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