So you want to migrate from CVSTrac to GitTrac?
You're crazy, of course, but that's never stopped anyone.
CVS to GIT
The first and most obvious thing about this is that you're implicitly migrating from CVS to GIT. This is the point where you may want to rethink the whole idea.
Still with us?
Prep Your Code
You've got a pile of code under your CVS respository, in a bunch of different modules. In CVS, these modules are treated all as independent trees. With GIT, a single repository is one tree.
Single Repository Mode
What this means is that
git-cvsimport expects to be handed a single CVS
module, and if you want everything in one place, you need to create that single
CVS module (no, you can't do it with "-a" or "&" tricks in
That's what I wanted, so it needed a little fancy footwork to make
mkdir /tmp/repo && cd /tmp/repo mkdir code cp -R <path/to/cvsrepository> code mv code/CVSROOT .
Note that this is the place to do any other repository cleanups you need. Also
note that we can get away with this only because
git-cvsimport ignores the
Multiple Repository Mode
If, on the other hand, you want to keep the concept of individual modules, you would git-cvsimport each module into its own distinct GIT repository, then point GitTrac at the directory containing all those repositories.
You could also have a separate GitTrac database instance for each GIT repository/CVS module.
Move Your Code
This should be the easy part.
cd ~ git-cvsimport -d /tmp/repo -k -m -v -i code
At the end of this, if all goes well, you've got a directory called
That's now your GIT repository.
Check Your Code
We're experienced software developers, so we're obviously not going to trust
git-cvsimport to not completely destroy our codebase. We need to check it out
and have a look at things.
mkdir working cd working git-clone <path/to/.git> code
You've just checked out the equivalent to the last CVS HEAD into
around. Run things like
git-log on files and make sure you've got a history.
Make sure your tags and branches are all there (
git-show-branch helps here).
See if all your code builds.
Fix Your CVS Dependencies
When you use CVS for too long, you inevitably start to make a lot of
assumptions. You distribute ChangeLog's generated from CVS commit messages. You
assume magic keywords in code (like
$Id$) mean something. You may even assume
you know which branch you're working on by looking at
hardcore CVS users might even put those assumptions into Makefiles and build
By "you", I really mean "me". But I didn't come up with all those ideas myself, and if you read the same web sites I do then you're probably in the same amount of trouble that I am.
Unfortunately, I don't have the answers here. You need to evaluate whether you really need the same functions, and come up with your own solution.
Other things you may have done with CVS include exploiting some of the
server-based scripting capabilities such as
CVSROOT/loginfo, etc. These sorts of things will obviously not work the
same way, if at all, in a distributed SCM like GIT.
Publish Your Repository
The GIT repository you've created is what's called a private repository. Normally, GIT projects are published to the world as public (or bare) repositories.
git clone --bare working/code code.git
You need to place this
code.git tree somewhere other users can access it. You
also need to put it somewhere GitTrac can access it directly (through the
filesystem). You were probably planning on doing this anyways, right?
There's more than one way to publish a GIT project. I chose to use
and the GIT protocol for publishing, but there's more than one way to do it.
git-daemon was configured to run from
git stream tcp nowait cpb /usr/bin/git-daemon git-daemon --export-all --inetd --verbose --export-all --base-path=/home/cpb/git /home/cpb/git
and we fetch
code.git into a working copy via:
git clone git://localhost/code.git
git-daemon doesn't allow you to publish changes that way.
git push ssh://localhost/home/cpb/git/code.git master
GIT For CVS Users
If you're the only user of your codebase, you can do whatever you want. However, larger organizations may have to cater to less "nimble" developers and other users.
There's some useful documentation for migrating CVS users to GIT.
For the truly backwards users, a CVS server emulator is available which should allow existing users to continue using CVS with minimal disruption and retraining.
CVSTrac To GitTrac
Setting Up GitTrac
First, you need a GitTrac configuration. We assume you've already got a
gittrac executable. In that case, we start by initializing the database:
gittrac init /path/to/database code
gittrac server. Just temporarily, we've got work to do later:
gittrac server 8008 /path/to/database code
Browse to http://localhost:8008/, login as
setup, and configure the GIT
repository. In my example, we're pointing it at
import the repository. I normally like to drop back to the command-line and
gittrac update /path/to/database code
but you may also just browse to the timeline or something. Have a look around, browse the file tree, look at checkins, and generally make sure you're happy with what you're seeing. If something got broken, you really want to fix it before going any further.
Import CVSTrac Data
If you were starting from scratch, you're already finished. The rest of us, however, have years of CVSTrac history which we don't want to lose, and ideally we'd like to have it all in the same place.
Ergo, we need to move all that CVSTrac data to GitTrac.
Many things won't have any issues. Wiki pages and attachments, for the most part, can be transferred directly. The user database and things like custom markups and tools are no problem.
Tickets and check-ins are going to give you trouble.
The trick is that CVS and GIT have entirely different concepts of what a commit looks like. Then, when we run this stuff through CVSTrac and GitTrac, we try to number everything as discrete checkins. CVSTrac tries to merge distinct commits into seemingly atomic operations, but if you've used it in a non-trivial environment you know that falls apart periodically.
So we've got two instances of *Trac containing more or less the same data, but the numbering scheme for the check-ins may be wildly different. And since things like tickets are cross-referenced with specific check-in numbers, a naive database copy from CVSTrac to GitTrac simple will not work.
Fortunately, this is something we can tackle with just a decent understanding of how the CVSTrac database works and an unreadable perl script.
The idea is roughly as follows:
- create a (many-to-one) mapping of CVSTrac checkin's to GitTrac checkin's.
- do the same thing with milestones. This isn't so easy since GitTrac and CVSTrac have different ideas of how to represent tags and such, so it may not be entirely complete.
- copy over the database tables as-is, except the ones GitTrac would have created from the repository (CHNG, FILE, FILECHNG).
- fix check-in cross-references. Some tables are easy, such as INSPECT and XREF. Some, such as the contents of Wiki markup, are really hard since we need to use regular expressions on text.
Fix Your CVS Dependencies
If your CVSTrac installation was relying on CVS-specific tools, you'll need to remove them or switch to GIT equivalents.
You'll also need to update reports. For example, if you've got a report which lists CVS branches, it's probably not going to work the same way with GitTrac. GIT revision numbers are longer, so if you're listing CVS file revisions in reports you may have layout issues.
Fix This Wiki Page
There's no way I've documented every possible problem with this process. If there's something you've encountered which doesn't work or if you've seen better shortcuts, please fix the documentation.