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

Re: URL-only renames adds svn:mergeinfo property

From: Stefan Sperling <stsp_at_elego.de>
Date: Fri, 19 Nov 2010 12:10:10 +0100

On Fri, Nov 19, 2010 at 01:40:42PM +1000, Daniel Becroft wrote:
> On Tue, Nov 16, 2010 at 3:54 PM, Daniel Becroft <djcbecroft_at_gmail.com>wrote:
>
> > Hi,
> >
> > I've just found (another) issue with using URL-only renames. If one of the
> > parent directories has svn:mergeinfo recorded on it, then renaming a file
> > via a URL results in the new file containing a full copy of what was on the
> > trunk (but cut down to the individual file).
> >
> > Please see the following output from my test script (using SVN 1.6.13):
> >
> > >svn merge file:///D:/temp/svn_sandpit/repository/trunk .
> > --- Merging r4 through r5 into '.':
> > U A\alpha.txt
> >
> > >svn commit . --message "Merge r5 from trunk to branch."
> > Sending .
> > Sending A\alpha.txt
> > Transmitting file data .
> > Committed revision 6.
> >
> > >svn propget svn:mergeinfo
> > file:///D:/temp/svn_sandpit/repository/branches/branchA
> > /trunk:4-5
> >
> > >svn propget svn:mergeinfo
> > file:///D:/temp/svn_sandpit/repository/branches/branchA/A/alpha.txt
> >
> > >svn rename
> > file:///D:/temp/svn_sandpit/repository/branches/branchA/A/alpha.txt
> > file:///D:/temp/svn_sandpit/repository/branches/branchA/A/beta.txt --message
> > "Rename alpha.txt to beta.txt on branchA."
> > Committed revision 7.
> >
> > >svn propget svn:mergeinfo
> > file:///D:/temp/svn_sandpit/repository/branches/branchA/A/beta.txt
> > /trunk/A/alpha.txt:4-5
> >
> > Notice that the 'svn propget' on alpha.txt indicates that there is no
> > svn:mergeinfo property available, but it gets added to beta.txt during the
> > rename.
> >
> > Is this intended behavior?

I think the rationale for creating this mergeinfo is that Subversion cannot
tell whether you're creating a copy of something (which will not receive
merges directly) within a branch, or creating a subtree-branch (which will
directly receive merges).

Consider a two-level branching scenario:

A branch is created:

 svn cp ^/trunk/ ^/branches/mybranch

This branch is synced to trunk periodically.
Then later someone decides to branch a subtree of this branch (this
is very different from branching the entire branch again!):

 svn cp ^/branches/mybranch/foo/bar ^/branches/mybranch/foo/bar-experimental

The bar-experimental branch now inherits explicit mergeinfo from
the ^/branches/mybranches directory, say /trunk:40-50.
I suppose this is done to prevent further merges from trunk (or subtrees of
trunk) into bar-experimental from merging changes which have already been
merged into foo/bar (the ancestor branch of foo/bar-experimental).

Whether the subtree-branch is just one file or a directory seems to be
irrelevant.

Now, this scenario doesn't really make a lot of sense in terms of a
reasonable branching/merging strategy. Documenting and justifying all
necessary merge steps for a strategy gets complex with subtree-branches.
It raises a lot of questions.

Where do you sync the subtree-branch to -- just its ancestor, or does it also
do more merges from trunk? If so, how do developers decide where to merge from?

Merges done into the subtree-branch affect the top-level branch and vice versa.
When is it appropriate to merge into the subtree-branch and when should merges
into the top-level branch be preferred?

Should developers check out their working copies from the subtree-branch or
from the top-level, or both? Depending on what?

There are without doubt people out there who do things like this.
I'd say that in most cases where subtree branching is done as above,
it's not done according to some predefined branching/merging strategy,
but because of people not knowing what they're doing.

There are variants of this problem. The copy must not be a child of
its parent, i.e. something like this could be done, too:

 svn cp ^/branches/mybranch/foo/bar ^/branches/mybarbranch

Also, you could copy something "interesting" (maybe a new module someone
else is developing) from another branch. This subtree branch that will be
synced to its origin periodically so that both branches share a common set
of code that isn't available on any other branch:

 svn cp ^/branches/anotherbranch/foo/bar ^/branches/mybranch/foo/bar

I suppose that is one compelling reason for subtree-branching, in places
where the mainline is over-protected so reintegration of a branch that
has interesting things for other branches takes a lot of effort. Then
instead of merging interesting branches back into mainline for other branches
to pick up, people cherry-pick things from interesting branches into their
own branch as they see fit. I've seen this pattern a lot with former clear
case users (where this particular scenario works much better than it
does in Subversion).
This pattern likely gets hairy when one of the top-level branches gets
reintegrated into trunk and the other top-level branch syncs to trunk then.
I haven't tried but I think you'll get spurious conflicts (see
http://subversion.tigris.org/issues/show_bug.cgi?id=2897).

So there are some remotely reasonable use cases for doing subtree-branching.
I still wouldn't want to use it, though. It just gets confusing.

If all you're doing is renaming a file within the branch as part of that
branch's changeset, I'd say just remove the explicit subtree mergeinfo
on the file after the rename. Or just leave it alone. Alternatively,
perform your renames in a (fully up-to-date, uniform-revision!!!) working
copy. This intentionally doesn't create mergeinfo.

> Is anyone able to confirm if this is intended behavior? After further
> testing, I get the same results if I run an 'svn copy' via URLs. However, I
> do not get the svn:mergeinfo property added if I 'svn rename' or 'svn copy'
> in my working copy.

Mergeinfo creation during wc-wc copies was explicitly disabled in the
1.5.5 release. From the CHANGES file:
  * do not create mergeinfo for wc-wc moves or copies (r34184, -585)

The corresponding commit was:

------------------------------------------------------------------------
r874258 | pburba | 2008-11-13 22:11:33 +0100 (Thu, 13 Nov 2008) | 22 lines

One small step towards mergeinfo sanity; no more explicit mergeinfo
on a WC-to-WC move/copy destination unless the source had some.

Discussed here:
http://subversion.tigris.org/servlets/ReadMsg?listName=dev&msgNo=145213.

* subversion/libsvn_client/copy.c
  (propagate_mergeinfo_within_wc): Remove.
  (do_wc_to_wc_copies, do_wc_to_wc_moves): Don't set explicit mergeinfo on
  a cp/mv destination beyond what the source had.

* subversion/tests/cmdline/copy_tests.py
* subversion/tests/cmdline/merge_tests.py
* subversion/tests/cmdline/revert_tests.py
* subversion/tests/cmdline/update_tests.py
  Update test expectations to no longer expect WC-to-WC copy/move
  destinations to always have explicit (usually empty) mergeinfo. In a
  few cases where this mergeinfo was essential to the purpose of the test,
  the WC-to-WC cp/mv was replaced with a REPOS-to-REPOS cp/mv or empty
  mergeinfo was manually set on the destination.
  

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

I think this change was good. It allows for the following rules of thumb:

- If you do a copy within a working copy of your branch, Subversion assumes
  that you want to copy something within your branch.
- If you do a URL-URL copy, Subversion assumes that you want to create a
  new branch.
Received on 2010-11-19 12:10:51 CET

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