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

Re: Bug during (interactive) merging?

From: Paul Burba <ptburba_at_gmail.com>
Date: Tue, 10 Jun 2008 14:01:25 -0400

On Tue, Jun 10, 2008 at 11:29 AM, Jens Seidel <jensseidel_at_users.sf.net> wrote:
> Hi,
>
> is no one willing to comment this or is it already known?
>
> On Thu, Jun 05, 2008 at 05:53:35PM +0200, Jens Seidel wrote:
>> I noticed an unexpected behaviour during a merge with a recent 1.5
>> snapshot. I tried to reproduce it but I (at least partly) failed.
>>
>> Nevertheless here is the story:
>>
>> * Create a branch as copy of trunk
>> * Add a file to both, trunk and branch, (same filename and content, but
>> no common history)
>> * Rename the file in trunk
>> * Remove the renamed file in trunk
>>
>> * Merge the renaming and removal in trunk to branch.
>>
>> Since the files in trunk and branch share no common history I'm unsure
>> whether the merge should conflict. It didn't, OK (I first expected this).
>>
>> The status in branch is now:
>> M .
>> D file
>
> Command was svn merge -r 2:4 URL
> (r3: renaming, r4: removal)
>
>> If I merge first the renaming and after it the removal (without
>> intermediate commit) I get:
>>
>> M .
>> D file
>> A + file.old
>
> That's equavalent to using svn merge -r 2:3 -r 3:4 URL
> so "svn merge -r r1:r2 -r r2:r3" is not identical to "svn merge -r r1:r3"!

At one point in the development the following were all equivalent:

  svn merge [-c8,9 | -r7:8 -r 8:9 | -r7:9]

We made some assumptions about what the user wanted when multiple
ranges/revisions were specified and tried to compact and sort the
requested revs/ranges. But after some discussion - see
http://svn.haxx.se/dev/archive-2008-01/0091.shtml - it was decided
that the compaction logic should be removed (see r28871 and r28872).

The upshot of this is that when specifying multiple revisions/ranges,
that merge does exactly what you ask, in the order you ask, and the
end result should be the same as if you did individual merges *in that
order*, e.g.:

  'svn merge -c8' == 'svn merge -c8,9' == 'svn merge -r7:8 -r 8:9'
  'svn merge -c9'

All three of the above *always* result in two merge editor drives. On
the other hand, 'svn merge -r7:9', could result in two drives (if the
source URL was renamed in r8) but could also (as in the example you
give) result in only one editor drive. A lot of the time there will
be no difference in the final result, but you've hit upon a case where
there is: The second merge is trying to delete a path scheduled for
addition with history, merge won't do this unless you use --force.
You didn't mention this, but I assume you saw that this path was
reported as skipped during the second merge, something like this
(using my own example to mimic yours):

>svn log -v -r9:10
------------------------------------------------------------------------
r9 | pburba | 2008-06-10 11:52:17 -0400 (Tue, 10 Jun 2008) | 1 line
Changed paths:
   D /A/C/nu
   A /A/C/nu_renamed (from /A/C/nu:8)

------------------------------------------------------------------------
r10 | pburba | 2008-06-10 11:52:33 -0400 (Tue, 10 Jun 2008) | 1 line
Changed paths:
   D /A/C/nu_renamed

------------------------------------------------------------------------

>svn merge %url%/A A_COPY -c9
--- Merging r9 into 'A_COPY':
A A_COPY\C\nu_renamed
D A_COPY\C\nu

>svn st
 M A_COPY
D A_COPY\C\nu
A + A_COPY\C\nu_renamed

>svn merge %url%/A A_COPY -c10
Skipped 'A_COPY\C\nu_renamed'

>svn st
 M A_COPY
D A_COPY\C\nu
A + A_COPY\C\nu_renamed

If you reverted and tried the merge again with --force I expect you'll
see what you expect:

>svn merge %url99%/A A_COPY -c9,10 --force
--- Merging r9 into 'A_COPY':
A A_COPY\C\nu_renamed
D A_COPY\C\nu
--- Merging r10 into 'A_COPY':
D A_COPY\C\nu_renamed

>svn st
 M A_COPY
D A_COPY\C\nu

Notice the two '--- Merging' notifications? There we clearly see that
two editor drives are occurring. Unfortunately the previous merge
without --force doesn't have a notification header for the merge of
r10 since all paths were skipped (I know this was done on purpose, but
can't find the thread).

>> Is this a bug? At least after reading the changelog and especially
>> 'svn copy A B ; svn move B C' now the same as 'svn copy A C' (issue #756)
>> I assume that there should be no other result. It should not matter
>> whether I split the merge into two merges or not. Right?

So yeah, it does matter. Don't really think it is a bug though.

The bug I do see is in the way mergeinfo is set when doing the merges
separately or with -cX,Y. Looking back of my first example the merge
of c10 skips 'A_COPY\C\nu_renamed'. That's ok, but the mergeinfo set
on the merge target 'A_COPY' makes it look like there merge really
occurred!

>svn merge %url99%/A A_COPY -c9
--- Merging r9 into 'A_COPY':
A A_COPY\C\nu_renamed
D A_COPY\C\nu

>svn merge %url99%/A A_COPY -c10
Skipped 'A_COPY\C\nu_renamed'

>svn pl A_COPY -v
Properties on 'A_COPY':
  svn:mergeinfo : /A:9-10

'A_COPY' now has mergeinfo for r10, so this prevents a repeat merge
attempt of r10 from doing anything:
>svn merge %url99%/A A_COPY -c10

Ok then we'll try --force, but that does nothing since the mergeinfo
thwarts the repeat merge attempt anyway:
>svn merge %url99%/A A_COPY -c10 --force

Oh wait, --ignore-ancestry will cause the mergeinfo to be disregarded:
>svn merge %url99%/A A_COPY -c10 --ignore-ancestry
Skipped 'A_COPY\C\nu_renamed'

Still nothing...we need both --force and --ignore-ancestry to make the
repeat merge happen and actually delete the path scheduled for
addition with history!
>svn merge %url99%/A A_COPY -c10 --ignore-ancestry --force
--- Merging r10 into 'A_COPY':
D A_COPY\C\nu_renamed

Ugh, I could just scream. I think we might need to reopen issue #2829...

>> I tried to reproduce a situation in my large repository where a merge of
>> both actions at a time resulted exactly (no svn:mergeinfo change) in:
>> D file
>> A + file.old
>>
>> But please note that I had a conflict in this directory (before the
>> rename) which I resolved interactive and now I wonder whether this
>> interactive merge is aquivalent to separate merges. I assume that
>> without the conflict I would just get:
>> D file
>>
>> PS: issue #756 was reopened. Should it stay fixed in the CHANGES file?
>
> Please have also a look at the svn merge help:
>
> 3. merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [WCPATH]
>
> I wonder about specifying "N" for option -c. The help text doesn't
> explain it:
>
> 3. In the third form, SOURCE can be either a URL or a working copy
> path (in which case its corresponding URL is used). SOURCE (in
> revision REV) is compared as it existed between revisions N and M
> for each revision range provided. If REV is not specified, HEAD
> is assumed. '-c M' is equivalent to '-r <M-1>:M', and '-c -M'
> does the reverse: '-r M:<M-1>'. If no revision ranges are
> specified, the default range of 0:REV is used. Multiple '-c'
> and/or '-r' instances may be specified, and mixing of forward
> and reverse ranges is allowed.
>
> Is "-c M,N" identical to "-c M -c N"?

Those are the same yes.

Paul

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-06-10 20:01:39 CEST

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.