subversion-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Burba <ptbu...@gmail.com>
Subject Re: URL-only renames adds svn:mergeinfo property
Date Tue, 23 Nov 2010 20:31:03 GMT
On Fri, Nov 19, 2010 at 12:25 PM, Stefan Sperling <stsp@elego.de> wrote:

Hi All,

The short story, the following behaviors are intentional:

A) WC-to-WC [copies | moves]: Destination only gets explicit mergeinfo
if the source has it.

B) URL-to-[WC | URL] [copies | moves]: Destination gets explicit
mergeinfo if the source has it.  If the source doesn't have explicit
mergeinfo, but inherits it, then that inherited mergeinfo is made
explicit on the destination.

The slightly longer story...

As Stefan already mentioned, in 1.5.0-1.5.4 'A' behaved like 'B'.
When we changed the WC-to-WC behavior in 1.5.5, we purposefully didn't
change the URL-to-* behavior.  But honestly, this was probably as much
out of caution as for any other reason, since there are use cases
where 'B' helps you even when doing copies within the same branch (see
my example that follows).

If someone wants to make the argument on the dev list that 'A' should
be the default behavior for all copies and moves, I for one am quite
willing to listen and probably assist, and maybe do all the coding
(which should be pretty minimal), but this isn't on my personal TODO
list at the moment.

> On Fri, Nov 19, 2010 at 12:38:57PM +0100, Johan Corveleyn wrote:
>> I don't see why it matters that it's a "sub-branch". It's still a
>> (grand-)child of mybranch, so can perfectly inherit that mergeinfo.
>> AFAIU it only needs explicit mergeinfo if it starts to deviate from
>> the mybranch root (e.g. if something is (sync-)merged directly to the
>> sub-branch). Or am I missing something?
>
> Hmmm.. I don't see any reason either. Explicit mergeinfo could probably be
> created later when the subtree actually becomes a merge target.
> I guess the current logic in the code simply doesn't account for the case
> where the copy destination is a child of the source? Not sure.

The basic problem with not making a copy* source's inherited mergeinfo
explicit on the destination is that a bit of merge history can get
lost.  Here is a simple example of this:

Say we have a simple two branch (trunk and branch) repos like this:

---trunk@1---r6-------@6------------------------->
      |     text      |
     copy   change   sync
      |      to      merge
      |    D/H/psi    |
      |               |
      V               V
    branch@2----------r7----------r9-------r10--->
                               WC-to-WC    identical text
                               copy of     changes to
                              D/H/psi to   D/H/psi-WC
                              D/H/psi-WC   and
                                 and       D/H/psi-URL
                               URL-to-WC
                               copy of
                              D/H/psi to
                              D/H/psi-URL

The merge in r7 leaves this mergeinfo on the root of the branch:

  >svn pl -vR
  Properties on 'branch':
    svn:mergeinfo
      /trunk:2-6

Nothing unusual there.  The WC-to-WC copy made in r9 creates no new
mergeinfo, but the URL-to-WC copy does create mergeinfo on psi-URL:

  >svn pl -vR
  Properties on 'branch':
    svn:mergeinfo
      /trunk:2-6
  Properties on 'branch\D\H\psi-URL':
    svn:mergeinfo
      /trunk/D/H/psi:2-6

This is exactly the behavior Daniel initially reported.

Note that r10 makes some changes to psi-URL and psi-WC that conflicts
with the changes made in r6.  What happens if we attempt to re-merge
r6 directly to psi-WC or psi-URL?

In the case of psi-URL, nothing happens, the merge is a no-op:

  >svn merge ^/A/D/H/psi branch\D\H\psi-URL -c6

  >svn st

  >

Nor should anything happen, since the merge source, ^/A/D/H/psi@6, is
already part of the target's merge history (per its explicit
mergeinfo).

Now let's try the same merge, but targeting psi-WC.  We know from the
preceding diagram that psi-WC's merge history should be semantically
equivalent to psi-URL's and we *should* get a no-op, but instead...

  >svn merge ^/trunk/D/H/psi branch\D\H\psi-WC -c6
  Conflict discovered in 'branch/D/H/psi-WC'.
  Select: (p) postpone, (df) diff-full, (e) edit,
          (mc) mine-conflict, (tc) theirs-conflict,
          (s) show all options: p
  --- Merging r6 into 'branch\D\H\psi-WC':
  C    branch\D\H\psi-WC
  Summary of conflicts:
    Text conflicts: 1

Why did this happen?  Because psi-WC's actual merge history (i.e. its
natural history and explicit/implicit mergeinfo) doesn't include
'/trunk/D/H/psi:6'.

Now you may be thinking, "but doesn't it inherit that history from the
root of branch?".  Unfortunately it doesn't, it does inherit mergeinfo
from branch, but it inherits '/trunk/D/H/psi-WC:6', which is obviously
not what we are merging and has the added distinction of not even
existing in the repository**

This is because mergeinfo inheritance is a simple path-wise
calculation: A path without mergeinfo inherits the mergeinfo of its
nearest parent with explicit mergeinfo, with all the merge source
paths adjusted by the path difference between the path and its parent.
 Yes, I'd love to come up with a more concise way to explain that!

Anyhow, that is where not recording the source's inherited mergeinfo
on the copy destination can bite us.  Is is a big problem?  Not sure,
but the workaround to avoid it, using WC-to-WC copies, doesn't seem
that draconian.  If you agree or not, I'm more than happy to kick
around improvements on the dev list.

Thanks,

Paul

* I talk about copies here, but the same issues apply to moves.

** In 1.7 I made improvements so that such bogus inherited mergeinfo
doesn't get recorded, see
http://subversion.tigris.org/issues/show_bug.cgi?id=3669, but in
1.5-1.6 we have that added insult.

Mime
View raw message