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

Re: Switching

From: Edwin Castro <0ptikGhost_at_gmx.us>
Date: Thu, 22 Aug 2013 10:22:27 -0700

On 8/22/13 7:59 AM, Les Mikesell wrote:
> On Thu, Aug 22, 2013 at 6:30 AM, John Maher <JohnM_at_rotair.com> wrote:
>> >
>> > @Andrew there is no need for a svn copy. I do not want to copy a feature in one branch to another; I wish to keep the code isolated.
>> >
>> > And yes I know subversion won't delete unversioned files, I appreciate the info on how subversion works. Some of it was helpful. I was hoping to hear how others may have solved the same problem.
> Your problem is not so much that svn doesn't deleted the unversioned
> files, but that it can't delete the directory containing them.
>
>> > But it seems the only answer is a tedious and manual process for the simplest of enhancements.
> Don't your build tools have commands to remove any spurious files
> they've created or some equivalent of 'make clean' that you can run to
> remove the clutter in a non-tedious way so that svn switch is free to
> work correctly with the versioned content?
>

I typically run into this problem when a "build output" directory exists
due to having built the project that doesn't exist in the other branch.
Something along these lines:

root/
+-- projectA/
| +-- bin/
| | +-- debug/
| | | +-- projectA.dll
| | +-- release/
| | +-- projectA.dll
| +-- src/
+-- projectB/
    +-- bin/
    | +-- debug/
    | | +-- projectB.dll
    | +-- release/
    | +-- projectB.dll
    +-- src/

Let's say in branch1 both projects exist but in branch2 only projectB
exists. The tree above would obviously imply I am currently on branch1.
I would have added the bin directory to svn:ignore on both the projectA
and projectB directories as I don't want to accidentally commit the
contents of the bin directory. The tree above is only an example. The
branches I'm used to dealing with contain hundreds of such projects and
building all of them can take up to 2 hours even on relatively fast
hardware.

If projectA has been built while I'm working on branch1 and I want to
svn switch to branch2, then svn will attempt to delete root/projectA/
but it can't because root/projectA/bin/ still exists. The switch leaves
behind root/projectA/ as unversioned (including the root/projectA/bin/
directory). Now that I'm done working with branch2 I try to svn switch
back to branch1 and svn fails to add root/projectA/ because it already
exists in the working copy unversioned.

We have a root build script that can run the clean target on all of our
projects. Alternatively, I could run clean on individual projects prior
to a switch but that requires that I know which projects do not exist on
the target branch. I could also use the --force argument to svn switch
but it carries it's own hazards. From svn help switch:

     If --force is used, unversioned obstructing paths in the working
     copy do not automatically cause a failure if the switch attempts to
     add the same path. If the obstructing path is the same type (file
     or directory) as the corresponding path in the repository it becomes
     versioned but its contents are left 'as-is' in the working copy.
     This means that an obstructing directory's unversioned children may
     also obstruct and become versioned. For files, any content differences
     between the obstruction and the repository are treated like a local
     modification to the working copy. All properties from the repository
     are applied to the obstructing path.

I'm particularly worried by "This means that an obstructing directory's
unversioned children may also obstruct and become versioned." You might
end up committing files you don't want to commit by using svn switch
--force so you'll want to be very careful. It would probably be a good
idea to follow up svn switch --force with svn status to see if anything
becomes versioned that shouldn't be.

Even though our builds can be quite long, I typically find it much safer
to simply clean all of the projects prior to performing svn switch. I
typically don't use our root build script to clean the projects because
it takes a long time loading up all of those different
projects/solutions to run the clean target. Since I'm on Windows I use
PowerShell to find all ignored and unversioned items and manually delete
them:

svn status --no-ignore --ignore-externals | Where-Object { $_ -match
'^[I?]' } | Remove-Item -Force -Recurse -Path { $_.Substring(8) } -Verbose

I've needed to update the substring index in the past because a new svn
release changed the svn status format on me.

Performing this kind of cleanup allowed svn switch to work correctly
every time. Then again, this does imply that every thing must be rebuilt
post switch which can be very painful when you have as many projects as
we do. If some of the ignored/unversioned files are user files that
should not be versioned, then cleaning like this creates additional
problems. We've worked around these problems by requiring that user
files are not used and adding a target to our root build script which
can fetch build output from our CI server.

With as many as 15+ active branches at any one time, each with hundreds
of projects, it is difficult to copy around user files whenever a new
branch is created. Sometimes those files need to be kept in sync as
merging occurs creating additional synching headaches. We found it much
easier to avoid user files instead of managing their contents manually.

Most of our developers use a working copy per branch and avoid switch
altogether but only because the guidelines they follow told them so.
Even then, rebuilding the entire tree took enough time that we wanted to
avoid it so we grab the latest build output from the appropriate CI
build (we have one per branch) as an optimization. We found rebuilding
only the projects we are currently working on is much simpler and faster
than building the entire tree even when we don't use svn switch.

Of course, given that we've built processes and tools to avoid building
the entire tree we made it possible to use svn switch even though most
people here don't use it. We even added a target to our root build
script cleans everything so that developers do not have to remember the
magic PowerShell incantation required. The guidelines written many years
ago tell them not to trust/use svn switch so they don't use it.

I use svn switch quite successfully and switch between 5-6 branches on a
daily basis but I do have access to tools that help me succeed,
specifically our clean script and the ability to download pre-built
output from our CI server.

--
Edwin G. Castro
Received on 2013-08-22 19:23:33 CEST

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.