On Tue, Nov 23, 2010 at 9:31 PM, Paul Burba <ptbu...@gmail.com> wrote: > 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.
Thanks a lot for the explanation, Paul. Very interesting. I didn't realize that merge tracking currently does not "follow" copies/moves (and that this explicit mergeinfo on URL-to-[WC|URL] copies is a way to implement this). I can envision a future where merge tracking will become more powerful to handle this without explicit mergeinfo (calculating correctly inherited mergeinfo through copies/renames), especially if svn ever wants to be able to handle merges through renames. But I fully appreciate that these things take time to be developed, and the current solution works reasonably well. Now that I understand this, I see that this explicit mergeinfo in behavior B is not a problem, and in fact more correct than leaving it out in behavior A. Maybe I'll continue discussion on the dev-list, but currently lack the cycles a little bit. Anyway, thanks for the background info. Cheers, -- Johan