We migrated from VSS to SVN some years ago, but the question of how to do it still crops up every now and again, so I thought I’d post my notes on the conversion process that I happened to use.
And yes, SVN not git. Git wasn’t really an option back then, and even now, as this is a corporate environment, it’d be a bit of an uphill struggle. But that’s largely irrelevant here! I’m modifying a local wiki post I made about it, so apologies if it reads a bit funny in places.
Also, apologies for unattributed software, like the original author of vss2svn.pl; it has been several years, so I’ve not the foggiest where I originally got it from!
Migrating from SourceSafe to Subversion
This post details the mechanism I used to migrate from Microsoft’s abysmal SourceSafe (VSS) tool to Subversion (svn).
I originally attempted to convert the VSS repo. to Subversion directly using vss2svn (and ssphys from the same site), a Perl script that accesses the VSS database directly and generates a subversion repo. from the data.
Unfortunately, there seemed to be a large of amount of post-processing & tidying up expected, and in my case almost every file was incorrectly converted, which would have required manual intervention at every step of the way. This seemed to be due to the script’s attempts to convert absolutely everything properly, including deleted/purged files.
I was quite happy to lose a certain amount of deleted information in the new repo., leaving that for the archived VSS d/b, and was content to have just current files with their specific file histories (for reference) in Subversion. Thus, an older mechanism was resorted to, which was trialled some years before when a move to Subversion was first mooted. This entailed using yet another Perl script (a modified version of vss2svn.pl downloaded from the Internet) to convert from VSS to CVS first, and then use the tool cvs2svn that is often supplied with Subversion to perform the final step.
This basic process produced, eventually, the most reliable snaphost+history conversion, and is documented below. The first part of the conversion must be performed on Windows, as it uses Microsoft’s ss.exe command-line SourceSafe tool. The second part is currently performed on Linux, but should possibly also work on Windows with the right software.
If you have problems with vss2cvs.pl, try this blog post for more possible bug fixes.
Prepare the VSS database
This must be done on Windows, preferably on a local hard drive. It is suggested that any tools referred to from here on in are copied to a directory C:\bin and this added to your local PATH.
- Create a temporary work directory on a local drive (for the sake of example, we will assume this is D:\temp\vss2cvs).
- Make a local copy of the VSS database in this directory. This may take a while if the d/b is large. It is recommended that a non-live version is copied, i.e., stop everyone from using the d/b, or access a backup from the previous night if such is available. This text will presume the name is D:\temp\vss2cvs\VSSDatabase.
- Edit the srcsafe.ini file in the copied d/b to add (to the top section) the line below. This will make VSS export files with Unix LF line-feeds, which will let Subversion have to chance to manage line-terminators correctly (normally VSS always works with Windows-style CRLF terminators).
EOL = n
- In a cmd prompt window, enter the D:\temp\VSSDatabase\data directory and run the tool ResetVSSPassword which you should be able to find on the Internet. Rename the um.dat file out of the way, and rename the newly created one to um.dat. Do not do this on a live SourceSafe database! This clears out the admin password; you may not need to do this step.
- If you want to try to copy deleted files, you can move on to the next step, however, it is not guaranteed this will work cleanly, and will significantly slow down the conversion.
- It is recommended that you do not try to perform any other major surgery to the SourceSafe database (e.g., moving things around, renaming) to match how you’d like your repository to look in Subversion, as you’re more likely to corrupt your SourceSafe database (if it’s not already). SVN can deal with any changes you want after the import.
- You need the two tools ssdelist and sspurge from ZDS.
set SSDIR=D:\temp\vss2cvs\VSSDatabase ssdelist
- You now have an output file ssdelist.txt, which is the list of files & projects that have been deleted and require purging. Double check it.
- Check the contents of the output file purge.bar. If happy with it, rename purge.bar to purge.bat and run it. Then you will have a clean VSS d/b of only live files. It will also be much smaller! (you may have to change ss purge to ss purge -yAdmin, in the file [note the final comma]).
If you want to speed up the process some more, you may also wish to delete some or all of your old top-level SourceSafe labels.
Convert from VSS to CVS
- At this point to need cvs.exe and vss2cvs.pl somewhere in your path.
- Create a setup.bat in the working directory containing:
PATH=C:\bin;C:\Program Files\Microsoft Visual Studio\VSS\win32;C:\Perl\bin\;C:\WINDOWS\system32;C:\WINDOWS set CVSROOT=D:\temp\vss2cvs\cvsroot del /s /f /q cvsroot rd /s /q cvsroot del /s /f /q convert rd /s /q convert cvs init set SSDIR=D:\temp\vss2cvs\VSSDatabase set HOME=%USERPROFILE% REM vss2cvs.pl SSPROJ=$/ CVSPROJ=trunk SSUSERPASS=Admin, SHOWDEBUG=yes
- This file will prepare the process, but not perform it. It can be run over and over, deleting old attempts, should there be problems. You must run this from the working directory within the cmd window.
- Run setup.bat, and then if all is OK, the final command that it prints (without the REM):
vss2cvs.pl SSPROJ=$/ CVSPROJ=trunk SSUSERPASS=Admin, SHOWDEBUG=yes
- Wait a long time.
All being well, after this, you will have a CVS database in D:\temp\vss2cvs\cvsroot
Prepare the CVS repository
This bit is usually performed on a Linux box. It does not take nearly so long as the previous, but could take upwards of an hour, so don’t hold your breath!
- Copy the working cvsroot directory (the CVS repository) to a Linux-local hard drive, or otherwise make it available to Linux. Do make a copy as the process to create this cvsroot from VSS was the longest part of the job, and you may need to recover it!
- Do not remove the CVSROOT directory; csv2svn requires that it is there.
- Move the contents of cvsroot/trunk up into cvsroot itself, and delete the empty trunk subdirectory. cvs2svn will create another trunk location for you.
- Fetch and add to your PATH (or call directly) the script do-massagecomments.pl (this uses the massagecomments.pl which comes with vss2cvs). vss2cvs saves who checked in a revision and when by adding it to the comment in cvs. This script takes that info out of the comment and puts it into the metadata in the RCS *,v file within the CVS database. Run it:
- At this point, you can do some pruning of your code base, e.g., removing large binary files that can be kept solely in SourceSafe. It is possible, but untested, that you could also move things around, as CVS has little if no knowledge of its directory structure embedded in any meta files, just the hierarchy in which the ,v files are stored.
You now have a cvsroot directory that should mirror, in some fashion, your VSS database tree (albeit with lots of ,v CVS files instead of the real names).
Create the Subversion repository (basic version)
This is the last leg, and hopefully the most straightforward! This presumes you have the edited cvsroot in pathto/cvsroot and want to create a Subversion repository at pathto/NewRepo (NB, you will need direct write access to the repository using these instructions. You will need a copy of cvs2svn, which is available in most Linux distributions and should come with the full Windows subversion install.
If you wish to create a Subversion dumpfile that can be imported later on, use the –dumpfile=dumpfile.svn argument to cvs2svn instead of the -s NewRepo one.
Get the config. file autoprops to the current directory, modified according to taste.
cvs2svn -s pathto/NewRepo --auto-props=autoprops --no-prune pathto/cvsroot
And there you should have it! You should probably apply the auto-props to the database configuration so as to catch new files as well.
If you would like the tool to not give you tag and branch entries for your SourceSafe labels, add the –trunk-only argument.
If you wish to do anything more clever, you need to consider the more advanced method of calling cvs2svn below.
Create the Subversion repository (advanced version)
For more formal conversions, it may be preferable to run cvs2svn with an options file. This is run as:
The options file allows much more fine grained control of the conversion process; read one of the examples for details. An example is cvs2svn.options. You still need the autoprops file listed above.
This is configured to do pretty much exactly the same conversion as the basic one-liner above, but it also has a list of usernames that will be converted at the same time, as we wished to normalise user access to sensible names (in this case, the user portion of the email address) instead of arbitrary IT-assigned Windows login names.
Loading the subversion dumpfile
Presuming you’ve created a dumpfile instead of creating the repository directly (which is likely if you’re not going to have write access to the new repo. server), this is what you (or your admin.) will have to do to get the data into a new repository.
We’ll add a little extra step here just to tidy things up. The VSS -> CVS route has left us with a rogue top-level CVSROOT directory which we don’t want, so let’s filter that out first. It used to be possible to remove this prior to running cvs2svn, but it uses that to validate your CVS repo. now, so it is no longer possible. Presuming you created orig.svndump out of cvs2svn:
svndumpfilter exclude trunk/CVSROOT < orig.svndump > edit.svndump
Now create and populate the new repo.:
svnadmin create /local/svn/repos/myrepo svnadmin load /local/svn/repos/myrepo < edit.svndump
You will need to change the permissions on this new repo. to match those required by your repo. server (Apache or svnserve).