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