$Id: vss2cvs_readme.txt,v 1.1 2006/01/05 09:15:39 bosse Exp $ If you need more info on these scripts, you can email me (Laine) directly, at laine+vss2cvs@laine.org, or send mail to info-cvs@gnu.org, which gets your questions out to a much wider audience ;-) A history of these scripts, as described by Jerry Nairn: > This web site belongs to Laine Stump who improved these scripts and > incorporated some changes from suggestions by Ephraim Ofir. I did > the first version, based on vsstop4, which was written by James > Strickland at Perforce. > > Perforce is another superior CM tool. It's a commercial product, but > is free for free software development. Perforce's website is at http://www.perforce.com - you can find the original vstop4 script there (it may be help explain some of the odd things that occur in vss2cvs.pl) QUICK INSTRUCTIONS: vss2cvs.pl must be run on a Windows machine. In addition to perl (I use ActivePerl 5.6.0), you'll need the following executables in your path: * cvs.exe If you didn't already have this, you wouldn't be here ;-) * rm.exe * chmod.exe Both of these commands must support the "-R" (recursive) option. I've found that the best way to get these is to install the cygwin tools (http://www.cygwin.com). *Don't* install cygwin's cvs.exe, though, unless you like specifying your CVSROOT as, eg, :local:/cygdrive/f/cvsroot, instead of :local:f:/cvsroot. Also, don't install cygwin's perl - it insists on using a strange notation for directories that only other Cygwin applications can understand. Instead, install Activeperl, available at http://www.activeperl.com. * ss.exe This is a part of MS' Visual Source Safe installation. It is usually in /common/vss/win32 - add that directory to your path. Once all of these are in place, just read vss2cvs.pl and determine how you should set the environment/commandline variables. To run the script, just do: perl vss2cvs.pl optionname=value optionname=value optionname=value ... Once the script is done (it takes a *long* time for large repositories), you should run massagecomments.pl on each ,v file under the CVS repository. This will replace the "fake" date/username info for each commit with the actual date/user of the *original* commit. Re-Syncing In the future, if more changes have been made to the VSS repository (*AND* if nobody has commited anything to CVS, ie as long as the CVS repository is effectively read-only), you can re-sync the two repositories by running exactly the same commands again - it will take much less time, because already-commited changes will be skipped, and only new changes will be operated on. Note that if anyone does a "rollback" of a change in VSS, or deletes a file, those will *not* be handled automatically!!! In the case of a rollback, you should delete the ,v file associated with the rolledback file from the CVS repository, and redo the conversion from the beginning. In the case of a file deleted from VSS, you should manually delete the file in CVS (checkout the file, rm it, cvs delete it, then cvs commit). ***************************************************************** CAVEATS 1) If your VSS client are setup to use a different date format than that used in the U.S., you'll need to change the regexp used for parsing the date in parse_user_and_timestamp(). Look for the comment: *** DATE FORMAT CHANGE HERE *** and modify the code accordingly. There is already a commented out version of the regexp for U.K. date format. 2) If your CVS server is contacted using pserver mode, you'll find that the server probably locks out all CVS actions after a minute or two - they will be coming so fast that inetd will think it is under attack. To remedy this, either modify /etc/inetd.conf to allow a larger number of connections within a 60 sec. period, or switch to using local mode (I've found that local mode is much faster anyway, and is acceptable especially during the initial conversion when nobody else is using the CVS repository anyway - you can just convert locally, then move the completed repository to your true server). As an example of turning up the max connection limit - on a BSD machine, you would change the line for pserver in /etc/inetd.conf like this: cvspserver stream tcp nowait:1000 root /usr/local/bin/cvs cvs --allow-root=/cvsroot pserver (the important piece here is the ":1000" - this says that it is okay to have up to 1000 connects to the cvspserver within a 60 second period). 3) One user reported silent failure of the scripts, which they tracked down to the fact that they hadn't installed all the Cygwin components necessary to make the rm & chmod applications work correctly (I believe they hadn't installed cygwin.dll). Whatever Unix utility set you use, verify proper operation of the commands by hand before you start the script - make sure they are installed completely. ***************************************************************** Here's a brief summary of my changes to Jerry's scripts, as of Oct 14, 2000: First, changes to vss2cvs.pl: 1) vss2cvs conversion is "restartable". In other words, you can stop it in the middle, then restart it later. Or (and this is *much* more important) you can run it once to get a module into CVS, then run it again at some later time to "re-sync" the CVS module with the VSS project. As long as you don't allow commits to the CVS module, this will permit you to have a much shorter "downtime" when you finally make the conversion (since you'll only need to lock everybody out from checkins/commits during the relatively shorter "re-sync" time, rather than during a complete conversion time). 2) Options can now be specified either on the commandline or in the environment before starting the program. To enter an option on the commandline, just specify it as shown below (eg "SSROOT=xxx"). Slashes can now be used in place of backslashes in all options (including SSROOT), to minimize the amount of character escaping you must do if you're running a unix-like shell (eg bash) on your Windows box. If any of the options have spaces in them, you should quote the entire option string (eg "SSPROJ=My Projects/this one"). (NOTE: I haven't tested a project with spaces in the names, although I have tested *files* with spaces in the names). Possible options (full explanations below, where needed): # SSROOT=xxx - VSS repository location # default: nothing (uses whatever is already in %ENV{'SSDIR'}) # example: SSROOT=//server/share/vss # CVSROOT=xxx - CVS repository location # default: nothing (uses whatever is already in %ENV{'CVSROOT'}) # example: CVSROOT=:pserver:laine@cvs.laine.org:/cvsroot # SSPROJ=xxx - VSS project name # default: none - THIS IS A REQUIRED argument # example: SSPROJ=Projects/Widget/current # notes: if this string doesn't start with "$/", one will be prepended # CVSPROJ=xxx - CVS project name # default: VSSPROJ with the leading "$/" removed # example: CVSPROJ=Widget # CVSBRANCH=xxx - branch tag to use for CVS commits # default: none - commits to the trunk # example: CVSBRANCH=4.0 # notes: "." is automatically replaced with "_", and a "b" is # prepended if the first letter is numeric. Also, a tag # of $CVSBRANCH-initial is put at the branchpoint, in # addition to the branchtag. # SSUSERPASS=xxx - username,pass for VSS # default: none - uses the current Windows login # example: SSUSERPASS=joe,mypass 3) You can now separately specify the VSS project name and the CVS module name (SSPROJ vs CVSPROJ). This allows you to reorganize the tree as a part of the conversion (you'll have to modify the Makefiles for the new org yourself! ;-) 4) You can now specify a CVS branch which you want all checkins of a file to go to. This permits you to merge multiple VSS branches (which, at least the way we use VSS, end up just being different directory trees within the VSS repository) into a single CVS module. For example, if you had the following in VSS: Projects/Widget/current - "trunk" of widget project Projects/Widget/4.0 - "4.0" branch of widget project (the "current" and the "4.0" directories would have the same files, but different revision histories starting at the point after the branch). You could do this (assuming CVSROOT, etc are already set in the environment): vss2cvs.pl VSSPROJ=Projects/Widget/current CVSPROJ=Widget vss2cvs.pl VSSPROJ=Projects/Widget/4.0 CVSPROJ=Widget CVSBRANCH=4.0 This will commit all the revisions in Widget/current to the trunk of Widget in CVS, then look for the first non-common revision in Widgets/4.0, put a branchtag of "b4_0" at that point in CVS, and commit all revisions after that to the branch. (This feature is based on the example of how branching is handled in our VSS repository. I have no idea if this is the way it's normally done, as I'm pretty much an idiot about VSS. Basically, to do a "branch", we "share" the entire tree into a different tree (eg, Projects/Widget/current is shared to Projects/Widget/4.0), then break the links on all the shares so that new checkins to .../current don't affect .../4.0. The result is that the 4.0 tree contains all of the "current" tree history up to the point of branch, then its own unique history after that.) 5) cleaned up the output a bit - of course this is subjective, but I find it easier to wade through the output now. 6) eliminated initial get of entire project from vss, thus making it faster. (If you're interested in max. speed, you'll also want to use a ":local:" CVSROOT - especially when doing the tags, the overhead of opening a TCP socket to a remote machine is quite significant.) 7) Removed spurious \r's (and also extra newlines) previously added to the end of checkin comments. 8) NEW REQUIREMENT - you must now have a "Unix-like" rm.exe and chmod.exe in your path. In particular, chmod must understand the -R (recursive) parameter, and rm must understand "-rf" (recursive, forced). Changes to massagecomments.pl: 1) Can now be rerun over a set of ,v files that have previously been "massaged" (or partially massaged) without destroying the ,v file. This goes hand in hand with item (1) for vss2cvs. (BTW, you don't *need* to run massagecomments.pl after each run of vss2cvs.pl - vss2cvs will still get the right timestamps for comparison (it looks both in the comments and in the real CVS timestamp). 2) Automatically moves the massaged file in place of the original, so you don't need a separate mv or rename command outside of massagecomments. I call massagecomments like this (this is the *Unix* find, not the MS one!): find . -name \*,v -print | while read f; do massagecomments.pl "$f"; done (the quotes make it properly handle filenames with spaces). Changes to listshares.pl: 1) Format is more compact. Rather that listing each file and its shares separately, it combines all files that are shared in exactly the same directories. 2) All output is sorted (the list of directories for a particular "link set" are sorted, as are the list of files for that set, then the entire file is sorted according to alphabetical order of the directory lists.) 3) Made commandline arguments similar to vss2cvs.pl - SSPROJ, SSROOT, and SSUSERPASS are recognized. 4) Added DIRMATCH and DIRREPLACE arguments. DIRMATCH is a regexp that is compared against each directory under the toplevel project (given by SSPROJ). Any directory *containing* that regexp is searched for shared files. DIRREPLACE is a string that is used to replace DIRMATCH in the directory names in the resulting listing. This is done so that lists of shares on different branches can be more easily compared with diff tools (since they will be in the same order, as they were sorted using *exactly* the same directory names) revision 1.5 date: 2000/11/09 19:50:38; author: laine; state: Exp; lines: +91 -111 * Change method of setting entire directory to branch to speed things up (idea from Ephraim Ofir). * Gather list of filenames from ss dir command rather than running separate ss properties command, again speeding things up (idea and code from Ephraim Ofir). NOTE: this may break the ability to properly convert files which are in the "save latest version only" mode in VSS - I don't have any such files, so I can't say for sure. * don't make cvs add dependent on finding a revision 1 of file in VSS - sometimes they start at a different revision (idea from Ephraim, code from me). * Explicitly supply directory name to ss get to avoid inadvertant gets to the wrong directory "when ss feels like it". * Add -r global option to cvs co, update, commit commands to guarantee that file in working dir is always read-only (otherwise, ss get barfs). The lack of this, and of the previous change, had caused numerous incorrect results in the past. * add access mode to mkdir call, so the script will run with older (5.00x) versions of perl. revision 1.7 date: 2001/01/29 18:21:43; author: laine; state: Exp; lines: +5 -4 * Fix error when a new branch is created for a file that both (1) already exists on another branch, and (2) never existed on the trunk. revision 1.8 date: 2001/01/31 22:01:54; author: laine; state: Exp; lines: +151 -114 * Handle the case when the source for a particular version isn't available in VSS - put the next newer version into CVS. * print out *every* cvs / ss command that is issued, in a consistent manner revision 1.9 date: 2001/02/01 22:07:45; author: laine; state: Exp; lines: +12 -10 * Fix problem with re-syncing of files that are in a subdirectory of the project. This was failing because the file wasn't "cvs update"ed prior to doing the commit, which meant that cvs didn't have any local info about the file (so the commit would fail). ********************************************************* Things that I haven't done anything about: * dealing with shared files. This is a tough one, and I think it really needs to be done by hand. One thing you might want to know about: If a file is shared, and it was tagged differently in different places, VSS keeps the tags (labels) separate (although it doesn't keep the revisions separate). So, if you want to keep the file "shared" in CVS (using whatever means), you'll need to do the two conversions separately, then merge in the tags from one ,v file to the other (you'll find that the rest of the file is identical). * dealing with "rolled back" changes and deleted files during re-sync operations. You'll need to fix these by hand.