Moved from CVS to Git

Last edited

Moved my private repository from CVS to Git

Git encourages a workflow that branches and merges often, even multiple times in a day
From: Pro Git book, written by Scott Chacon

This week I finaly made the move and turned my CVS repository to Git. For over a decade I have used CVS to manage my stuff. The repository contains all the code I have written in those years as well as the texts of all the articles and columns I have written.


My CVS server runs Viewvc so I can use a webbrowser to browse the repository. A great way for sentimental journeys into memorylane ...

Raspberry Pi

My first Raspberry Pi runs as PXE, TFTP, DHCP and NFS server and is the central point in my array of diskless systems. To keep things a bit separated I bought a second Raspberry Pi to act as my private Git server.

Raspbian with Git, Gitweb and lighttpd

There are only a few packages needed in order to run the Raspberry Pi as gitserver.

  • Raspbian is a Debian version optimized for the Raspberry Pi hardware, it runs from an SD card.
  • ssh comes with the standard install of Raspbian.
  • Git, lighttpd and gitweb are all available as Raspbian package.

So this makes the installation process very easy.

Converting CVS repository to Git

Because this was a one-way transistion, I choose cvs2git to convert the CVS repositories to Git.

rsync CVSROOT to the local system

To make the whole operation a little easier I started with moving CVSROOT with all the repositories to my workstation (actually a Linux LXC container running as a Xserver running Debian) with rsync.

Because my CVSROOT contains a lot of repositories I had to create a shellscript to turn them one by one into a Git repository.

The most important part of the shellscript is the actualy conversion:

rm -f ~/cvs2git-tmp/*
cvs2git --blobfile=cvs2git-tmp/git-blob.dat --dumpfile=cvs2git-tmp/git-dump.dat --username=cvs2git /path/to/CVSROOT/$file
mkdir ~/gitrepo/$file
cd gitrepo/$file
git init --bare
cat ~/cvs2git-tmp/git-blob.dat ~/cvs2git-tmp/git-dump.dat | git fast-import
git gc --prune=now

After the shellscript ended I had to hunt down those repositories where cvs2git ran into an error. This was easy to do by looking at the size of the subdirectories with du -sh *.

Because of Git's compression the repositories are a lot smaller then the CVS repositories. Look into the 100k sized directories, on my system this were the repositories where cvs2git did run in somekind of error.

Pushing the Git repoistories to the Raspberry Pi

The next step was to put all the converted repositories to the Raspberry Pi. This turned out to be a two step process:

  1. Initiate the Git repository on the Raspberry Pi
  2. Push the Git repository from the workstation to the bare repository on the Raspberry Pi

Initiating the Git repositories

I wrote a small shellscript on the Raspberry Pi that for every repository creates a subdirectory and initiate Git in it. This last step is done with:

git init --bare

Pushing the repositories from the workstation to the Git server

First I setup passwordless access from the workstation to the right user on the Raspberry Pi. After this another shellscript was used to push every repository to the Raspberry Pi. The shellscript cd-ed into the Git repository directory. From there it ran:

git push --mirror user@raspberrypi:/path/to/repo

Setup the backup scripts

Before actually starting the use of the freshly created Git server there has to be a backup method in place. I simply do a rsync of the directory which contains the Git repositories. On the backup server (with real disks, the Raspberry Pi simply runs on a single SD card) I create a daily targz files for the last seven days, weekly targz files and monthly targz files.

Installing gitweb

(Gitweb)[] can be used as a substitute for ViewVC. Unfortunately gitweb don't offer the great diff views that ViewVC has to offer. It is however possible to get a side by side diff view on a version compared to the master version.

See Gitweb with lighttpd on Debian 6 Squeeze as inspiration on how to install gitweb with lighttpd.

Shut down the CVS server

This was a one way migration, cvs2git is not the right tool if you want both the CVS repositories and the Git repositories to keep synchronised.

My goal was to move completely to Git, therefor cvs2git was the right tool for me. After the conversion the final step was to shut down the old faithfull CVS server, which had been a part of my life for so long. It had run on all kinds of different hardware, the longest period it was running on a 600 MHz VIA Epia running from USB-sticks with nightly rsyncs to a backup server. In all those years only one time I had to use the backup to restore the repository. But because the contents are so important to me, I was very happy to actually have a backup.