On 09.05.2013 22:08, Andrew Reedick wrote:
> Problem:  Subversion doesn't have branches.  
>
> Subversion has directory objects, and we Humans(tm) arbitrarily decide that 
> some directories are "branches," thereby giving these directories (branches) 
> magical powers and mystical significance.  Meanwhile, Subversion grinds on, 
> treating those magic branches as mundane directories.
>
> You can see the effects of this problem when you change a parent directory 
> common to multiple branches, e.g. changing "/projectFoo/branches" to 
> "/projectBar/branches" will cause every "branch" in "/projectBar/branches/*" 
> to have a shared revision.  This complicates finding branch points 
> (--stop-on-copy), finding the common ancestor, etc..
>
> Are there any plans to address this issue or otherwise make branches a first 
> class object?  Or at least add a switch to 'svn log' to skip over extraneous 
> "only the parent dir path changed" revisions?
>
> Demonstration:
>
> $ svn mkdir -m "" ^/project1/branches
>       Committed revision 73.
> $ svn mkdir -m "" ^/project1/branches/alpha
>       Committed revision 74.
> $ svn mkdir -m "" ^/project1/branches/beta
>       Committed revision 75.
> $ svn log -q -v ^/project1/branches/alpha
>       ------------------------------------------------------------------------
>       r74 | test | 2013-05-09 15:27:49 -0400 (Thu, 09 May 2013) | 1 line
>       Changed paths:
>          A /project1/branches/alpha
>       ------------------------------------------------------------------------
> $ svn log -q -v ^/project1/branches/beta
>       ------------------------------------------------------------------------
>       r75 | test | 2013-05-09 15:27:50 -0400 (Thu, 09 May 2013)
>       Changed paths:
>          A /project1/branches/beta
>       ------------------------------------------------------------------------
>
> As you can see from the svn logs, the "alpha" and "beta" branches are 
> completely independent.  They have no revisions in common.
>
> But by renaming the parent "project1" dir to "project100", we create a 
> linkage between the two:
> $ svn mv -m "" ^/project1 ^/project100
>       Committed revision 76.
> $ svn log ^/project100/branches/alpha
>       ------------------------------------------------------------------------
>       r76 | test | 2013-05-09 15:29:11 -0400 (Thu, 09 May 2013)
>       Changed paths:
>          D /project1
>          A /project100 (from /project1:75)
>       ------------------------------------------------------------------------
>       r74 | test | 2013-05-09 15:27:49 -0400 (Thu, 09 May 2013)
>       Changed paths:
>          A /project1/branches/alpha
>       ------------------------------------------------------------------------
>
> $ svn log ^/project100/branches/beta
>       ------------------------------------------------------------------------
>       r76 | test | 2013-05-09 15:29:11 -0400 (Thu, 09 May 2013)
>       Changed paths:
>          D /project1
>          A /project100 (from /project1:75)
>       ------------------------------------------------------------------------
>       r75 | test | 2013-05-09 15:27:50 -0400 (Thu, 09 May 2013)
>       Changed paths:
>          A /project1/branches/beta
>       ------------------------------------------------------------------------
>
> Note that the independent branches "alpha" and "beta" now have revision 76 in 
> common... even though neither branch was changed.
>
> Adding insult to injury, "svn log --stop-on-copy" will stop on revision 76, 
> i.e. it treats r76 as a branch point:
>
> $ svn log --stop-on-copy -v ^/project100/branches/alpha
>       ------------------------------------------------------------------------
>       r76 | test | 2013-05-09 15:29:11 -0400 (Thu, 09 May 2013)
>       Changed paths:
>          D /project1
>          A /project100 (from /project1:75)
>       ------------------------------------------------------------------------
> $ svn log --stop-on-copy -v ^/project100/branches/beta
>       ------------------------------------------------------------------------
>       r76 | test | 2013-05-09 15:29:11 -0400 (Thu, 09 May 2013)
>       Changed paths:
>          D /project1
>          A /project100 (from /project1:75)
>       ------------------------------------------------------------------------
>
> As you can see, the "independent" alpha and beta branches now have revision 
> 76 in common.  All because Subversion doesn't have branches.

Well, given that you have not created any branches, this works as
expected :)
There are no branch points in your repository; only directories. A
branch is created by copying a directory (with "svn copy"), not by
creating it (with "svn mkdir"), and that is why your --stop-on-copy
works the way it does -- the only copy is a side effect of the rename
(which is currently represented as copy+delete), hence --stop-on-copy
stops ... when it sees the copy.

The real problem here is that Subversion does not treat /renames/ as
atomic operations. This is indeed being addressed, but a complete
solution will take time. I'm not going to go into technical details
here; if you're interested, you're welcome to join the dev@ list and
listen in (or participate) in the discussions there.

In the meantime, Subversion 1.8 will go part of the way towards properly
supporting renames: it will track renames in the working copy, with "svn
status" annotating deletes and copies with rename source/target info,
and will, for example, prevent users from committing only half of a
rename. To go the rest of the way, we'll need rename support on the
server side and -- most significantly -- in the merge module.

-- Brane

P.S.: I agree that --stop-on-copy is an awkward UI for branch point
detection; but that's another topic altogether.

-- 
Branko Čibej
Director of Subversion | WANdisco | www.wandisco.com

Reply via email to