[Top][All Lists]

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

Re: Documentation suggested to clearer state restrictions to merging

From: Derek R. Price
Subject: Re: Documentation suggested to clearer state restrictions to merging removed files
Date: Thu, 07 Dec 2000 13:38:19 -0500

"Cameron, Steve" wrote:

> Derek Price wrote:
> > >         But this has another problem, namely that file removals will
> > >         be handled *without possibility of conflict*... according to
> > >         the comments around line 2177 of update.c (cvs 1.11)
> > >         which say:
> >
> > [snip]
> >
> > >         And when I first came across that, it seemed like a bug, but the
> > >         more and more I thought about it, considering especially that
> > the
> > >         two -j options can refer to *any* two revisions, I'm convinced
> > that
> > >         what the comments say here is the correct way.
> >
> > Can you provide me with an example of when this might be the desired
> > behavior?
> >
>         [smc]  Consider a reverse merge to roll back a bunch of changes.
>         cvs update -d -P -j newer_tag -j older_tag
>         Suppose some file was added between older_tag and newer_tag.
>         The reverse merge should remove that file.
>         "unless there's a conflict", you say?

RCS_merge manages to figure that out when there are changes to the file.

>         Well, how can you tell if there's a conflict?  What are
>         you going to use for the common ancestor so that you
>         can know what changes have been made since that
>         common ancestor in the code that's being merged
>         into, and thus know that this reverse merge conflicts with
>         those changes?  You can't just assume that "newer_tag" makes
>         sense as a common ancestor.

Yes you can - 4 way merges aren't necessary.  What you're actually assuming is
that all a merge cares about is the differences between the greatest common
ancester (gca) of newtag and the destination.  In the simple backout case this
simplifies to newtag:

       ^       ^         ^
       o       n         t

Regardless of the merge direction (n->o or o->n), if a file is being removed
due to this merge, then all we care about for a conflict is whether the file
changed between n & t.  If it didn't (meaning no new revisions - a readd, even
with the same contents as the file at n might be because another file was added
after n which could make use of the file.  I'm not sure this case would occur
more often than a backout, redo, backout sequence, but it might be that neither
case is common enough to quibble about this and the "alert the user" case is
best) or the net change was a remove, there is no conflict.  Otherwise there

Here's the rest of the cases to prove this math always works.

            ^       |
            o       ------------------
                              ^      ^
                              n      t

Same as above.  Includes all cases where o, n, & t are in "line".

            ^       |
            o       ------------------
                      |       ^
                      |       n

If a file (f1) was removed before t.parent, then it is already removed at
t.parent & removal is a conflict if the net change between t.parent & t is an
add.  If f1 was removed after t.parent, then removal is a conflict if there is
a change to f1 between t.parent & t and the net change is not an rm.

In the next two cases, the spearation of o & n is functionally equivalent to
being in a straight line.

  | |               |
  | -----------     |
  |         ^       |
  |         o       ------------------
  |                           ^
  |                           n

Again, if f1 has changed since t.parent and is not a net rm, conflict.

    |          |                |
    -------    |                |
       ^       |                |
       o       -----------      -------
                       ^            ^
                       n            t

Changes between n.parent & t relevant.  Changes between o.parent & n.parent are
irrelevant because, if relevant,  they are contained in the diff between o & n.

    |          |
    -------    |
       ^  |    |
       o  |    -----------
          |            ^
          |            n

If f1 has been removed between o & n, then it must happen somewhere between
o.parent & n.  Therefore, changes are relevant to conflicts if f1 exists on t
and has changed since o.parent, again, the gca of t & n.

All the other cases I could come up with simplify into one of the above.


Derek Price                      CVS Solutions Architect ( http://CVSHome.org )
mailto:address@hidden     OpenAvenue ( http://OpenAvenue.com )
This score just in: OS/2, Windows 95, LinuxPPC 2000.

reply via email to

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