Visual Source Safe (VSS) to Subversion (SVN) Migration
This code is released into the public domain without restriction. Drop us a line if it ends up being useful to you--we'd love to hear about it.
Hi! You're probably looking for VSSMigrate. This is where it started (you can see the history below), but the best place to go now is probably the C#-based version on CodePlex: http://vssmigrate.codeplex.com/
UPDATE: (3/27/08) Thank you to Jim Watters and Ricardo Stuven who have provided updates. I haven't tried them myself (my archive is already transferred), but browsing through the code it looks like this version is better.
UPDATE 2: (4/21/08) Thank you to Matt Palmerlee and Karl Zeift who both made further updates to include the original userID and timestamp of the VSS checkin.
Karl's change: "To get the correct timestamp, I simply change the system clock to the old timestamp before committing to svn. The commit-comment with the old vss version number is extended to also include the original vss user name. I also removed the code that waits before exiting, so I can use it in batch-files (we have a very large vss-db). The calculated time for the conversion becomes unuseful since I set the system clock."
Caveat: Karl's code assumes VSS is returning dates in YY/MM/DD format (and adds 2000 to YY), which some users have reported is not the case for them.
Get Karl's changes (with compiled VSSMigrate)
Matt Palmerlee does something similar and describes his change via his blog: http://computercabal.blogspot.com/2007/11/vss-to-svn-migration.html.
Caveat: Matt's code doesn't make any date assumptions, it simply takes the date string and passes it to the cmd.exe's date command
Get Matt's changes (with compiled VSSMigrate)
UPDATE 3: (10/22/08) Thank you to Tim Erickson who has create a .NET (C#) port, with some additional benefits.
In Tim's words:
"[My C# version] utilizes SharpSvn so it doesn't have to parse command line input/output for SVN commands, and VSS Interop for the same reason for VSS commands. Additionally, it preserves the username and revision datetime via direct editing of the revprops folder in the SVN repository. Though this requires direct filesystem access to the SVN repository and is not a recommended practice, it works quite well and does not require editing the system clock or matching any usernames/passwords (it can populate a username on a revision that does not exist in the SVN repository)."
Tim's C# VSSMigrate is available here, and Tim can be contacted at tim AT in2words DOT org
UPDATE 4: (11/10/08) Thanks to Erik who updated Tim's C# port with functionality which "removes all of the VSS binding information [from the project files] and doesn't import any of the [VSS] *scc files."
Erik's update is available here. Erik can be contacted via his blog: http://blog.eriklane.com
UPDATE 5: (08/15/09) Brian at NIST has a nice update (apparently to Erik's UPDATE 4 code):
"VssMigrate worked but it wasnï¿½t satisfactory [for my needs] since each fileï¿½s history is imported separately. And that results in the changes to not be in chronological order. So I made some changes to the program. Before if you checked in a set of files to VSS at the same time, each of those file changes becomes a separate revision in the resulting SVN repository. In this new version in that case that set of changes will be just one revision in the SVN repository. And chronological order is correct too."
Brian's update is available here, and Brian can be contacted at Polidobj at Yahoo Dot Com
[End of updates and back to the boring original. Personally, I'd use one of the builds above :) ]
I wrote VSSMigrate after spending almost a week trying the other major script and executable solutions for importing a Visual SourceSafe database into Subversion. Many of them came close, but most would ultimately error out before the end, or miss importing some revisions. The best version I found was a perl script by Brett Wooldridge (http://www.riseup.com/~brettw/dev/VSS2Subversion.html). I've basically taken his approach and re-implemented it in C++ where I have more control (I don't know Perl, so wasn't able to modify his script to my liking). And some people say C/C++ is hard to read! ;)
VSSMigrate will migrate every file revision currently in SourceSafe (under the project you specify) to Subversion keeping comments intact. It doesn't do anything with deleted files or labels.
This is a C++ program written and compiled with Visual Studio .NET 2003. Other than the use of CString, I don't think there is any Microsoft-specific code in there (although I wouldn't think that would be a problem if you're coming from VSS). It isn't visually attractive, but you can see what is happening.
VSSMigrate uses a configuration file for its settings. Just launch VSSMigration without any arguments and it will print out a sample version. Usernames and passwords are optional depending on your environment.
As I mentioned above, I copied Brett's approach which is to go through SourceSafe and get a list of all directories, create them on the hard disk, and import them into Subversion. Next, it goes to each file and checks out each revision and then commits it to svn. This is slow, but it works. The reason I couldn't use Brett's script is I found there were race conditions between launching the Visual SourceSafe command line app (ss.exe) and svn.exe where one of them would still be using the file when the other app needed to do something with it. In VSSMigrate, each command must complete before the next step is taken. Again, this is slow, but I've been able to do a 100% migration (as far as I'm able to tell), whereas I only got about 85-90% of the revisions with the Perl script.
I imported two top level VSS projects at the same time using two instances of VSSMigrate (more on that below). Both the VSS database and the Subversion repository were on the
same machine (different physical drives), and I used the svnservice to interact with the repository. The timings were:
Start time: 05/27/06 09:47:11
End time: 05/27/06 22:05:00
External commands run: 61054
Files Migrated: 2487
File Revisions Migrated: 28038
Start time: 05/27/06 09:47:15
End time: 05/27/06 22:34:33
External commands run: 54619
Files Migrated: 4973
File Revisions Migrated: 22330
As noted above, the comments are brought across to svn. In addition, an extra string in the form of " (vss x)" is appended to each comment where x is the original VSS revision number for that file. This helps track files back to SourceSafe should that be needed.
I used this to migrate a version 6 SourceSafe database (ssexp.exe version is 18.104.22.168) to Subversion 1.3.1.
Don't try to import $/ (I haven't tried it) but instead do the top level projects individually. You CAN run multiple instances of VSSMigrate on different top level projects, however, be sure to use different VSS usernames (when I used the same username, there were errors with ss.exe fighting over the user's 'logged in' file).
If a command fails (I've seen svn.exe fail to start a transaction), VSSMigrate can be configured to retry automatically. If that fails, it will stop and ask you if it should try again. This way you don't have to start all over when an intermittent error occurs.
One failure I saw was SourceSafe reported it had a file named "example.exe;5". I have no idea what the ";5" at the end was (maybe I had deleted and added that .exe back 5 times???). SourceSafe was able to retrieve "example.exe;5" into the directory (as example.exe), but then then VSSMigrate told svn to work on "example.exe;5"--which didn't work. To get around it, while VSSMigrate was waiting for me to decide whether to try again or not, I went to that directory, renamed example.exe to example.exe;5, manually did the add (ie 'svn add example.exe') and then told VSSMigrate to try again. svn was happy and continued migrating--although it just kept adding the same file over and over. So I guess this is the only error case where a revision was lost.
If you have the Microsoft Debug libraries installed, I'd recommend running the Debug version just in case any Asserts fire (the CPU time spent in VSSMigrate is negligible--it's all in the external ss.exe and svn.exe).
When you're done, I HIGHLY recommend you do a fresh check-out/get from each repository and then compare the directories--this was one way I discovered that the other tools weren't working completely. Personally I found that the free WinMerge (http://winmerge.org/) tool worked great.
Let me know if you make improvements and I'll update the binary here.
admin AT poweradmin DOT com