views:

37

answers:

2

I've been using ComponentSoftware's CS-RCS Basic for many years now to manage my various single-developer projects. It's worked very well for me, but now I want to migrate to a modern revision-control system, and after studying my options I decided on Mercurial.

The problem is that I've always used a central repository for CS-RCS, and I'd now like to use individual Mercurial repositories for individual projects, keeping the history from my RCS repository.

After some in-depth Googling I concluded that the only way to do this is to convert my RCS repository to individual CVS repositories, then convert those to Mercurial. These two sites were probably the most helpful:

In keeping with Jeff Atwood's idea of asking and answering my own question, I'm going to answer this for anyone else stuck in this situation, and in case I have to find it again later. As you'll see, though I did find a solution, it's clunky and has at least one significant problem. If anyone else has any better method I'd certainly like to hear about it.

+1  A: 

Here's the method I came up with, warts and all. It's a bit 'cargo culty', since I basically know nothing about CVS and not much (yet) about Mercurial:

I have a Windows XP virtual machine that I can take snapshots of, so I did that and then installed CVSNT and the Windows command-line version of Mercurial (I use TortoiseHg on my main machine). I did this in a VM so I could easily get rid of CVSNT, Mercurial, and anything else I had to create while doing this one-time migration. Yeah, I probably didn't have to do this, but the VM was already available and I've already got enough odd bits of apps left over from install/uninstall cycles over the years. :-)

As far as I could tell, CVSNT was the only program available that could easily set up a CVS server on a Windows machine. It seems that this was free at one time but the owner's current site now asks for money. That's not a bad thing, but I really couldn't justify spending money just to do a one-time conversion. I did eventually track down an older version of CVSNT with a Google search and installed that without problems.

Here are the notes I took while learning how to make this conversion work:

The Long Version

Copy the source-code folder you need from the main computer's drive to the VM's drive. Copy the various ",v" files from the C:\RCS folder structure to this same source-code folder on the VM. Just copy the ,v files from the corresponding folder in C:\RCS. Open a Command Prompt box on the VM and type the following:

path %PATH%;C:\Program Files\cvsnt
mkdir \cvs-repo  [or clean the folder out if it already exists]
cvs -d \cvs-repo init
[A DIR of \cvs-repo should show a CVSROOT folder in there.]

Make a copy of your source code folder in \cvs-repo. \cvs-repo should now just have two folders: CVSROOT and your new folder. Copy in the appropriate ",v" files as well.

mkdir \cvs-checkout [or clean that folder out if it already exists]
cd \cvs-checkout
cvs -d \cvs-repo co name_of_your_source_code_folder

A DIR of "\cvs-checkout\name_of_your_source_code_folder" should show all of your source code files, which are now checked out of CVS.

If you haven't already done so, download Mercurial from http://mercurial.selenic.com/ and install it. Open a copy of Notepad and drag the file "C:\Program Files\Mercurial\hgrc.d\Mercurial.rc" into it. Under "[extensions]", remove the semicolon at the start of the line ";convert =". Save the file to "C:\Documents and Settings\user_name\Mercurial.ini"

Back at the VM command line:

path %PATH%;C:\Program Files\Mercurial
mkdir \my-repo.hg  [or clean that folder out if it already exists]
hg convert --datesort \cvs-checkout\source_code_folder_name \my-repo.hg
cd \my-repo.hg
[A DIR of \my-repo.hg should show a new ".hg" folder.]
hg update
[A DIR should now show the ".hg" folder and all the checked-out files.]

Copy the ".hg" folder from \my-repo to the source code folder on your main computer's hard drive. The destination folder will now show up in TortoiseHg with all of the appropriate change history, but all files marked as Changed (icon overlay of an exclamation mark in a red circle). This is because the new Mercurial repository thinks the files were checked in with Unix line endings (0x0A) instead of Windows (0x0D,0x0A). This seems to happen in the "hg convert" process, and I haven't found any way around it.

The Short Version

Once everything's set up in the VM, here's what to do:

  • Delete everything in \cvs-repo, \cvs-checkout, and \my-repo.hg.
  • At the command line, cvs -d \cvs-repo init.
  • Back on your main machine, copy the source-code folder into your Virtual Machine's shared folder (that's how you do it in VirtualBox; other VM software might let you just drag-and-drop the folder into the VM).
  • Copy the appropriate ",v" files into the source-code folder in the Virtual Machine shared folder.
  • Back in the VM, move the source-code folder to \cvs-repo.
  • cd \cvs-checkout
  • cvs -d \cvs-repo co name_of_your_source_code_folder
  • hg convert --datesort \cvs-checkout\name_of_your_source_code_folder \my-repo.hg
  • cd \my-repo.hg
  • hg update
  • Copy the .hg folder from \my-repo to the L: drive on the VM (L is the mapped drive letter of my VM shared folder).
  • Move that folder from the Virtual Machine transfer folder to the final source-code folder on the host computer.

Handy Batch File

Once I got this working, I set up this batch file on the VM to automate the process as much as possible:

@echo off
rem Converts source code under RCS control to a Mercurial repository.
rem This batch takes one argument: the name of the source-code folder (in quotes if necessary).
rem
rem This is for a VirtualBox VM that already has CVSNT and Mercurial installed, and has a Shared Folder mapped to drive L.
@echo On the host, copy the source-code folder into the Virtual Machine Transfer folder.  Copy the appropriate ",v" files into the source-code folder in the Virtual Machine Transfer folder.
pause
@echo on
cd \
rmdir /S/Q \cvs-repo
mkdir \cvs-repo 
rmdir /S/Q \cvs-checkout
mkdir \cvs-checkout
rmdir /S/Q \my-repo.hg
mkdir \my-repo.hg
cvs -d \cvs-repo init
xcopy L:\%1 \cvs-repo\%1 /E/I
cd \cvs-checkout
cvs -d \cvs-repo co %1
hg convert --datesort %1 \my-repo.hg
cd \my-repo.hg
hg update
xcopy \my-repo.hg\.hg L:\.hg /E/I

Conclusion

So, this all worked but left me with files that had the wrong line endings. Looking at this question, I see I'm not the only one with this problem. I can live with this, but I'd still like to fix it if anyone knows of a solution.

Gordon Brandly
A: 

If Mercurial has fast-import/fast-export support, and if your multi-file repositories do not use branches, you can probably try using my rcs-fast-export tool (available @ http://git.oblomov.eu/rcs-fast-export ). Although I've only used it to export from RCS to git so far, I am not aware of any git-specific fast-export commands being used so it might work.

Oblomov