On Tue, Nov 23, 2010 at 9:31 PM, Paul Burba <ptburba_at_gmail.com> wrote:
> On Fri, Nov 19, 2010 at 12:25 PM, Stefan Sperling <stsp_at_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:
> | text |
> copy change sync
> | to merge
> | D/H/psi |
> | |
> V V
> 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
> copy of
> D/H/psi to
> The merge in r7 leaves this mergeinfo on the root of the branch:
> >svn pl -vR
> Properties on 'branch':
> 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':
> Properties on 'branch\D\H\psi-URL':
> 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_at_6, is
> already part of the target's merge history (per its explicit
> 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
> 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.
> * 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.
Received on 2010-11-23 22:37:53 CET