Roland's homepage

My random knot in the Web

Converting RCS to git

This article describes how to use cvs-fast-export to convert old RCS histories to git.

My original revision control system (up to 2007) was the venerable rcs. This worked well for maintaining collections of text files like configuration files and source code. But for e.g. LaTeX documents which would contain images and other binary files, rcs is not the best choice since it doesn’t really handle binary files.

For a time, I switched to subversion since it could handle binary files, but I found creating and maintaining repositories cumbersome.

Then git came along, and I switched to using that for new projects. I’ve also converted the stuff I had in subversion to git.

Meanwhile I still have a fair amount of older files in rcs. Most of that is older, archived stuff that I don’t use very often.

The last RCS-managed files I have are from 2009 and I have long since excluded rcs from the list of things that are being built on my FreeBSD machines.

Since I haven’t got rcs installed anymore, I thought it would be a good idea to document how to convert their histories to git format. I’ve tried several tools for conversion. ESR’s cvs-fast-export works best for me.

Building cvs-fast-export

As of this writing, there is no FreeBSD port of cvs-fast-export. I’ve written one but haven’t submitted it yet, since this is a pretty specialized tool which one doesn’t use often.

After downloading the tarball from ESR’s website, I built the software as follows. Note that this is on FreeBSD 11, where GNU make and GCC are not the default tools. I have used them because the code contains some GCC-only attributes and using BSD make gives errors.

> cd ~/tmp/src/
> tar xf ../cvs-fast-export-1.40.tar.gz
> cd cvs-fast-export-1.40/
> gmake CC=gcc49 cvs-fast-export
> install -s cvs-fast-export ~/bin
> rehash

Note that I’m not building the manuals here, since I don’t have asciidoc installed. The manuals are text files, so they can be easily read as-is.

Converting RCS history to a git repo

As an example, I will convert my CV (in LaTeX) to a git repo.

First I make a copy of the old directory, just to be sure.

> mkdir attic
> cp -Rp cv attic/

Then I make a fast-import stream. I’ve put my username information in ~/authormap.

> cd cv/
> find . |cvs-fast-export -A ~/authormap >../
cvs-fast-export: no commitids before 2007-04-08T19:52:06Z.

Next, create a git-managed directory and import.

> mkdir cv-git
> cd cv-git
> git init
Initialized empty Git repository in /home/rsmith/latex/cv-git/.git/
> cat ../|git fast-import
Unpacking objects: 100% (35/35), done.
git-fast-import statistics:
Alloc'd objects:       5000
Total objects:           35 (         0 duplicates                  )
    blobs  :           13 (         0 duplicates          8 deltas of         13 attempts)
    trees  :           11 (         0 duplicates         10 deltas of         11 attempts)
    commits:           11 (         0 duplicates          0 deltas of          0 attempts)
    tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           1 (         1 loads     )
    marks:           1024 (        23 unique    )
    atoms:              5
Memory total:          2344 KiB
    pools:          2110 KiB
    objects:           234 KiB
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =          1
pack_report: pack_mmap_calls          =          1
pack_report: pack_open_windows        =          0 /          1
pack_report: pack_mapped              =          0 /      15596
> git checkout
> git status
On branch master
nothing to commit, working tree clean

As it turns out, the version of the Makefile from rcs did not match that in the tree. So I copied over the working files from the old RCS tree, just to be sure I didn’t miss anything. Additionally I also modified the .gitignore to better match a LaTeX project.

> cp ../attic/cv/Makefile .
> cp ../attic/cv/*.tex .
> cp ../attic/cv/RFS.jpg
> cat - >.gitignore

Now that everything works, remove the old dir and rename the new repo.

> cd ..
> rm
> rm -rf cv
> mv cv-git cv

Note that I’ll keep the originals in attic, just to be sure.

←  PDF tricks Removing big files from git history  →