At my work we have a combination of “legacy” Visual Basic applications and more recent J2EE web based applications. The Visual Basic applications use the esteemed Visual Source Safe as their source code repository, whereas we were lucky enough to establish CVS for the Java apps. Well, VSS’s deficiencies in branching and merging have forced us to use CVS for all source (I say “forced”, but this is something I think is a good move and am totally for). So now the challenge is migrating our VSS repository to CVS and maintaining the code history.
The only such tool I have seen to accomplish this is this vss2cvs perl script. However, there doesn’t seem to be any account of a successful conversion effort. Well, this is my attempt to explain how I converted our VSS repository to CVS using this script… Note: I DO NOT claim to know perl. I basically hacked away at this till it worked, please let me know if you see a better way to accomplish any part of this script!
As I’m on a windows client machine, I had to install CygWin with the Perl libraries to execute this command for the transfer:
export CVSROOT=<i>your cvs root</i>
perl vss2cvs.pl SSROOT=//GRUEN/VSS SSPROJ=$/<i>your project</i>
CVSPROJ=<i>your new cvs proj name</i> SSUSERPASS=rdaigle,<i>your passwd</i>
But first, let’s get the script fixed:
- First of all, it seems there needed to be some initial changes to the script outlined by this post.
Once I did that I was still getting errors about invalid SourceSafe syntax. Turns out the command line call to the VSS executable (ss.exe) was formatting the file path incorrectly. So I had to change that line in the script:
- Line 122 changed from
exec_cmd("ss workfold \"$ssproj\" \"$workdir\\$subdir\"
$ssuserpass"); to exec_cmd("ss workfold \"$ssproj\" \"$workdir/$subdir\"
$ssuserpass");
- After line 145 add the following to remove trailing ”:” from the directory names:
$currdir =~ chomp($currdir);
$currdir =~ chop($currdir);
- Before Line 168: (
open(FILETYPE,"ss filetype \"$currfile\" $ssuserpass |");
add $currfile =~ s/\r//g;
to remove leading spaces from the path.
- Line 237 of sub resync_file: add
$file =~ s/^ *//;
to remove leading slashes from file path
After that, I started getting erros about not being a CVS module. Turns out the script was trying to get modules from CVS that hadn’t yet been moved over from VSS (the script claims to be able to re-sync repositories, I have not tried this).
- Wrap the
open(CVS,"$cvscmd |");
and subsequent while loop with this “if” statement: if ($alreadyincvs)
Ok, good. At this point I started getting “attempting to use variables not yet initialized” errors and needed to check that the “highestssver” variable at line 424 was initialized before using it.
At this point I noticed that it wasn’t properly finding the labels and had to:
- change line 433 from
if(/^Label: "(.+)"$/)
to if(/^Label:/)
Here is the resulting file that seems to work pretty well for me: (right click -> save as…). Please let me know if I need to clarify anything or what your experiences are with this conversion. There seems to be a lot of interest in it, with very little real solutions. Hopefully we can remedy that and get people off VSS.
As a side note, here is where the script falls short:
Let me know how it goes.
Paul Glaubitz has kindly given me the updated script he used that properly handles file labels. I’ve updated these links with his version. Thanks, Paul!
Here are the resources mentioned in this post: (right click -> save as…)