Monday, November 30

PowerShell: Remove-SVN: Stripping .svn folders within a target directory tree

Over the past two years or so, thanks to TortoiseSVN and VisualSVN, I've become a fan of the SVN code repository tool. As a long-time Microsoftie, I've used various versions of SourceSafe dating back some 12 years. I've also used Sourcegear's Vault product. Both of these integrate using MSSCCI which offers a pretty seamless experience in my most commonly-used IDE: Visual Studio.

TortoiseSVN makes it possible to work with SVN directly within Windows Explorer, no commandline work required. VisualSVN is a great, cost-effective plugin for Visual Studio that takes integration into the IDE itself. Still, these products don't integrate 100% perfectly with Visual Studio, especially if, like me, you are prone to refactoring without a lot of checkins early on. You can end up making a mess of the .svn folders that these products use to track states of files under their control.

Every now and then, at least in my experience, you will goof up, and you need to strip the .svn folders out, and do a clean checkin. Jon Galloway had a Windows Explorer right-click context menu option for this, but it didn't work for me. I got it to work once from the commandline, but not without tweaking what he has there.

As an old-school VBScript guy, I'd played with PowerShell a few times, ran some one-liner commands, did a little simple piping and recursion, but that was about it. After a couple times of dealing with this SVN hassle, especially after some serious lost time after a machine rebuild, I decided to create a reusable tool in PowerShell to make my life easier.

I initially wrote Remove-SVN as a very simple, rather lean (and I'd like to think elegant :) PowerShell script:


function RemoveSVN
{ param ([string]$target)

If (Test-Path ($target + '\.svn'))
{
Write-Output ('Removing: ' + $target + '\.svn')
Remove-Item ($target + '\.svn') -recurse -force
}
}

$target = 'C:\TargetDirectory'

Write-Output ('Removing .svn for ' + $target + ' and children.')

RemoveSVN -target $target

foreach ($f in Get-ChildItem $target -filter *. -recurse -force)
{
RemoveSVN -target $f.FullName
}

Write-Output ('.svn removed for ' + $target + ' and children. Press a key to exit.')

Read-Host


... then re-wrote it as a significantly fatter C# snap-in so I could call it as a PowerShell cmdlet. Follow these instructions to install and register a PowerShell snap-in for yourself.

Here is a ZIP with both the original PS script and Visual Studio 2008 snapin/cmdlet project files.

One final note: if you're running Vista or Windows 7 64-bit, and you compile the snapin and cmdlet for Any CPU, or x64 specifically, you'll need to make sure you run the 64-bit version of Powershell, or the snapin won't appear when you list installed snapin DLLs, and you simply won't be able to register and use it. (For whatever reason, Win 7 Ultimate N x64 defaults to running Powershell x86. YMMV) You can find the x64 executable under the WOW64 directory: C:\Windows\SysWOW64\WindowsPowerShell\v1.0