dinsdag, november 08, 2005

CVS to GIT and back

The first step is to import a CVS tree into GIT:

mkdir foobar.git
cd foobar.git
git-cvsimport -p x -v -d :ext:takis@cvs.sourceforge.net:/cvsroot/someproject foobar

We will not make any modifications to the project in that directory, this directory is purely intended to be a GIT conversion of the CVS repository. Instead, we'll create a clone of that archive and do our hackery in there:

git clone -l foobar.git/ foobar-pi.git/

The "l" flag makes sure that git uses hard links instead of copying files, if possible.

Next, we'll make some modifications to the project and commit them using git-commit or cg-commit. As said earlier, we'll make those modifications in the foobar-pi.git directory:

cd foobar-pi.git
... do stuff ...

If new changes are committed in the CVS repository, we need to fetch those in our foobar.git repository, which is kind of a GIT mirror of the online CVS repository.

cd foobar.git
git-cvsimport -p x -v -d :ext:takis@cvs.sourceforge.net:/cvsroot/someproject foobar

Now, we'll pull in the CVS-commits to the clone directory.

cd foobar-pi.git
git pull

This results in a way to have a nice GIT repository of a project being hosted using CVS. Your GIT repository makes it easy to view changes in the project as you've got the full history locally on your system.

To prepare you modifications to be send as a patch, do the following:

git-format-patch origin..HEAD

This will give you a set of files, containing patches, which you can post to a mailinglist or maintainer.

If you've got write access to the CVS-repository, you probably want to commit these patches back into the CVS yourself. To do this, checkout the CVS repository somewhere on your filesystem:

export CVS_RSH=ssh

Get into the CVS working directory, and set the environment variable GIT_DIR to point to the .git directory within your git directory:

export GIT_DIR=/usr/local/src/foobar-pi.git/.git/

View the GIT-logs and select which commits you want to push into the CVS-repository:


Copy and paste the commit-identifier (being an SHA1-hash) and use it as a parameter to git-cvsexportcommit:

git-cvsexportcommit 4a20cbafdf25a141b31a8333284a332d1a4d6072
unset GIT_DIR

Do not forget to unset the GIT_DIR environment variable!

This will output:

$VAR1 = '4a20cbafdf25a141b31a8333284a332d1a4d6072';
Ready for you to commit, just run:

cvs commit -F .msg Uiml/uiml.net.build

Repeat the command shown above:

cvs commit -F .msg Uiml/uiml.net.build

The patch which you wrote and committed in your clone GIT tree, is now committed back into the CVS repository.

Now, you can resync your GIT-CVS mirror tree:

cd foobar.git
git-cvsimport -p x -v -d :ext:takis@cvs.sourceforge.net:/cvsroot/someproject foobar

Now, your patches which you committed in the CVS repository, will be pulled back into the GIT-tree which acts as a mirror of the CVS-repository.

Now, you'll want to merge this back into your GIT-clone tree, which is where you do your actual work:

cd foobar-pi.git
git pull

Now, you've come full circle. You patches which were initially committed in foobar-pi.git, were committed to the CVS tree, and pulled back into the mirror GIT tree (foobar.git) and finally back into your clone/working GIT tree (foobar-pi.git). Ofcourse your patches were already in foobar-pi.git and GIT will notice this.

6 opmerkingen:

micha zei


need more infos ;)

how about using cvs commands, which links/uses git
(have some old developers, they didn't need to now that they are using git ;) apt-get remove cvs;apt-get install git-cvs-replacments)

Johan zei

Thanks for the tutorial.

I would like to point out that if you want to import a cvs-tree from sourceforge, it works much faster if you first get the complete cvs-repository to your own computer, eg:

/yourproject/* .

(without the linebreak ofcourse)

and then import that project. You save yourself a lot of time, and you put less stress on the sourceforge cvs-servers.

Johan zei

correction should of course be
rsync rsync://yourproject.cvs.sourceforge.net/cvsroot/yourproject/*

Patrick McElhaney zei

Here's some up-to-date information on using CVS with Git.


jdavidb zei

The -p x on the git cvsimport line above is wrong. You have to pass -p -x if you want the option to make it to cvsps correctly. Unfortunately, neither git-cvsimport nor cvsps will let you know if you do it wrong.

Anoniem zei

Very handful guide, well explained, everything worked as expected :)