Migrating from TFS to Mercurial
The distributed revision control systems that have emerged in the last few years are so much better than what came before, you have to wonder why it took so long. I’m working with Mercurial at the moment and although my initial “play time” was encouraging, I couldn’t help wondering what it would be like when a repository has been in heavy use for a year or so. Would it mature like fine cheese? Or would it mature like… most cheese?
I’ve been working off a Microsoft TFS 2005 system for about five years now. The main folder I check into was created in April 2009, and since then it’s had ~4K changesets added to it. If only I had a time machine, I could go back and tell myself to use Mercurial, so that now I would know if it had been a good idea or not.
But I do have a time machine! For all its faults, TFS does at least allow me to get the state of the source tree at any point in the past. So why not do the following:
1. Make a Mercurial repository hosted on our in-house server,
2. Clone it to my hard drive.
3. Tell TFS that my working directory is the root of the repository where I just cloned it.
4. Look up the changeset number of the first changeset in TFS. This is my initial current changeset number, which we’ll say is
5. In the working directory/local cloned repository (for it is now both of these things), type:
tf changeset 12672 /noprompt
This will dump out a bunch of information, including the check-in comment, username and original date/time of check-in:
Date: 6 April 2009 16:08:26
Comment: Updated the build number.
So, not exactly earth-shattering as changes go, but still… to continue!
6. Tell TFS to bring my working directory to the state it was in immediately after that check-in occurred:
tf get . /version:C12672 /noprompt /recursive
7. Tell Mercurial about this change:
hg commit -u tfssetup -m "Updated the build number (TFS changeset 12672 6 April 2009 16:08:26)"
8. Increment the current changeset number.
9. Go to step 5.
Along the way of course there may be some changesets that related to other folders, so they need to be skipped. They can be detected by looking at the paths referred to in the
Items: section of the
tf changeset output.
So this is what I did (well, not personally; I got my computer to do it). So now I have a fully ripe and matured Mercurial repository with a year’s worth of busy activity in it. What’s it like?
It’s about 2 GB of code. A clean
get from TFS would take ~15 minutes. A fresh clone from the Mercurial server takes ~17 minutes. Give that this includes getting an extra 1.5 GB of
.hg metadata containing the entire history of the repository, this means Mercurial is working a lot faster in terms of handing out data, and as a marginal difference in the total get-time I’m perfectly happy with it. A local clone took 9 minutes – to do the equivalent of that in TFS (where you create a branch on the server) is like this huge ceremony and usually seems to take half an hour or so (with multiple steps to it).
If you run
hg status it takes ~10 seconds from a cold start, but then after that it takes a second. To commit a change to a single file takes ~5 seconds.