On Fri, Nov 19, 2010 at 12:25 PM, Stefan Sperling <s...@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: ---tr...@1---r6-------@6-------------------------> | text | copy change sync | to merge | D/H/psi | | | V V bra...@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/p...@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.