Tip: Converting a CVS repository to git

Posted on December 30, 2011 by Tommy McGuire
Labels: software development, system administration, tip

I have a great load of source code (and other detritus) in a CVS repository that I've been copying around for years. I have not used CVS for anything new in a very long time, but because I was the only one modifying things, I did not bother to move the contents to anything more modern.

Occasionally, I need to reactivate a project, and usually want to move the history into a newer tool, git usually. And every time, I have to look up how to do it. So, here's the latest working scheme, in hopes that I don't have to search around anymore.

  1. Copy the CVSROOT directory and the module from the repository to someplace local. My CVS root (and the master git repositories) live remotely. The destination doesn't matter much.

    scp -r remote:CVS/{CVSROOT,module} CVS
  2. Get a copy of the latest cvs2svn, which includes cvs2git, which seems to be working better than I remember. Use cvs2git to create the two git fast-import format files from the repository.

    cvs2svn-2.3.0/cvs2git --blobfile=module-blob.dat --dumpfile=module-dump.dat --username me CVS/
  3. Create a new git repository to act as the master repository for the project.

    mkdir module.git
    cd module.git/
    git init --bare --shared
  4. Import the project.

    cat ../module-blob.dat ../module-dump.dat | git fast-import
  5. Put the new master repository back on my remote server.

    cd ..; scp -r module.git remote:GIT/
  6. Clone the remote repository to create a local, working repository.

    git clone ssh://remote/home/me/GIT/module.git
  7. The import above leaves the CVSROOT and module directories in the git repository, so the useful content of the module is one level down into the repository. The first git operation on the working repository fixes that.

    git rm -r CVSROOT/
    git mv module/* .
    git rm -r module
    git commit -m 'Removing cvs residue'
    git push

And with luck, that's that.

Comments



I've tried this a few times over the past years and always failed... until now. Thanks a lot for your excellent and concise article. One question: I have many different usernames across the machines and servers I work with (not my choice) so when following your procedure I simply used 'me' for the --username arguments... is this an issue? Will it come back to haunt me later? Again, many thanks.

Jonathan McAuliffe
'2014-03-24T05:01:35.114-05:00'

Jonathan, you're welcome! I'm glad I could help. I bounced off the conversion process several times before, so I'm happy this process works for someone else.

According to the docs, the --username argument is "Use NAME as the author for cvs2svn-synthesized commits (the default value is no author at all." I am guessing that should have no real ill effects---I've certainly never noticed anything special about the username I used.

Tommy McGuire
'2014-03-24T18:03:56.558-05:00'

This article is very useful. Thank you. I have now converted all our CVS projects to GIT. The only problem we have (and perhaps we should have thought about this ourselves) is that we ran the conversion on Linux as per the instructions above, but the developers actually use Windows. This has meant that all the code has been converted from CRLF to LF and that the diff history makes less sense, at it seems that at some point all code was changed. git diff -b doesn't really help. Anyway, thanks again. Daniel

Anonymous
'2015-11-27T03:36:08.667-06:00'
active directory applied formal logic ashurbanipal authentication books c c++ comics conference continuations coq data structure digital humanities Dijkstra eclipse virgo electronics emacs goodreads haskell http java job Knuth ldap link linux lisp math naming nimrod notation OpenAM osgi parsing pony programming language protocols python quote quotes R random REST ruby rust SAML scala scheme shell software development system administration theory tip toy problems unix vmware yeti
Member of The Internet Defense League
Site proudly generated by Hakyll.