info-cvs
[Top][All Lists]
Advanced

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

Re: The idea isn't clear...


From: Greg A. Woods
Subject: Re: The idea isn't clear...
Date: Mon, 2 Jun 2003 14:41:03 -0400 (EDT)

[ On Friday, May 30, 2003 at 12:36:21 (-0400), Eric Siegerman wrote: ]
> Subject: Re: The idea isn't clear...
>
> I suspect that the above diff hunk is an unrelated change.  It
> seems unrelated to the conflict-marking style.

Yes, actually it is -- the stat() is there so that one more un-related
change hunk, that I did manage to delete, can work, which is the one
that chmod's the merged file's mode bits back to match the original.

> I used to make this change too (well, the s/-E/-A/ part; the -T
> is orthogonal), but recently discovered a drawback -- for me,

Yes, '-T' is sort of orthogonal, though I've found it's another critical
part of making the conflict markers more easily read and understood.

(note that in theory the '-A' is not necessary since it is the default
with '-m', but I like to be explicit about these things, especially in
places where I need to remember what was intended)

> The problem is that the s/-E/-A/ patch breaks this detection, and
> instead of a nice message, you get spurious merge conflicts.

Well I don't find that to be a show-stopper (far from it), though it is
sad that diff3 does fail to detect this often useful bit of information
about conflicts when '-A' is used.

The real problem I have is that often the spurious conflicts are not
marked properly -- i.e. in the desired full '-A' form.

I find the '-A' form far more critical for daily use than the occasional
spurious or poorly marked conflict.

> I think the problem is in diff3.  -A does two things:
>  1. makes diff3 dumber about identifying conflicts (suppresses
>     the intelligence that would have suppressed the conflict in
>     the above case)

Although the documentation alludes to this I'm not sure it's the full
intention -- just a side-effect.  :-)

I've found the diff3 options to be _extremely_ poorly documented, often
to the extent that the docs seem to disagree with the code.

The code is extremely over-complicated too, with several cases of using
multiple separate variables to control what should be binary flags,
while at other times using multi-state variables to control what should
be separate binary flags.

Coincidentally I had a very similarj discussion with Larry McVoy when he was
working on the merge tool for BitKeeper.  :-)

>  2. once a conflict has been identified, displays its ancestor
>     version as well as the two child versions
> 
> Of course, (2) is what we're after, but diff3 provides no way to
> get that without also getting (1).

Perhaps we should file a bug report with the GNU diff maintainers....

I'm betting these are perfect examples of bugs caused by programmers who
are (or at least think they are) just too familiar with their own code
and who don't bother to test usages they don't use themselves.

Of course there's one other obvious solution to this problem and that's
to use 'patch' instead of 'diff3' for merging, and whenever 'diff3'
fails me that's often what I do (and other times I use Emacs Ediff).  It
would be nice if 'patch' would annotate the *.rej file with comments
about why the change was rejected of course (such as when a specific
chagne is already present), but that's a relatively minor thing and
should be easy enough to fix since it's more or less already spewing
this information on its stdout.

FYI, last I heard from Larry was that he was going to stop using 'diff3'
and instead just do run two separate ordinary 'diff' processes and then
do the merging and conflict detection of their output using his own
code.  This is of course something like what the original AT&T 'diff3'
implementation did (leaving out the obvious error handling):

        case $1 in
        -[ex3])
                flg=$1
                shift;;
        esac
        mine=$1
        ancestor=$2
        yours=$3
        diff $mine $yours >/tmp/d3a$$
        diff $ancestor $yours >/tmp/d3b$$
        /usr/lib/diff3prog $flg /tmp/d3[ab]$$ $mine $ancestor $yours

What CVS really needs to do is take all the changes from DELTA($ancestor
to $yours) and merge them into $mine, marking any conflicts where
changes from DELTA($ancestor to $mine) would conflict with the first set
of changes, and ignoring, perhaps verbosely, changes in DELTA($ancestor
to $yours) which are already present in DELTA($ancestor to $mine).  As
far as I can tell no current variant of 'diff3' implements exactly this
procedure in any way shape or form.

-- 
                                                                Greg A. Woods

+1 416 218-0098;            <address@hidden>;           <address@hidden>
Planix, Inc. <address@hidden>; VE3TCP; Secrets of the Weird <address@hidden>




reply via email to

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