Maintaining a Drupal module using Git
This guide assumes you know the basics of Git. If not, read up on the excellent Git Community Book located here - http://book.git-scm.com/
You will need:
- A fairly new version of Git, 1.6 or higher
- cvsps
- CVS, of course :-)
(get them from the best source according to your OS)
We will refer to the following names below:
MODULE_NAME: The name of your module.
GIT_CVS_CLONE: Directory where you will create the Git repository using git cvsimport (making changes here directly is not advised!).
WORKING_SANDBOX: The place where you will test the changes you make (consider it your working Git repository, like the test directory of your module in a Drupal installation).
CVS_WC_MODULE: Local working copy of the module's CVS repository.
From CVS to Git
Importing your module's CVS tree
export CVSROOT=:pserver:USERNAME@cvs.drupal.org:/cvs/drupal-contrib
cvs login
mkdir GIT_CVS_CLONE
cd GIT_CVS_CLONE
git cvsimport -a -p x -v -d :pserver:USERNAME@cvs.drupal.org:/cvs/drupal-contrib contributions/modules/MODULE_NAMENote: This will import your module's full CVS tree (all branches) into a git repository with respective git branches. This may take a lot of time if your module has a dense/busy CVS repository.
Creating your workplace
cd WORKING_SANDBOX
git clone -l GIT_CVS_CLONE MODULE_NAMEIf you are working on a branch of a module like DRUPAL-6--1, then you will need to create and checkout the required branch.
cd MODULE_NAME
git checkout -b new_branch_name origin/DRUPAL-6--1You are now on the correct code branch. Check once before continuing!
It's time to commit some changes...
cd WORKING_SANDBOX/MODULE_NAME
...
... making changes
...
git commit -am 'Changed foo'Good job! You've successfully set up most of your Git-CVS workflow!
Keeping your git repository updated with the CVS tree
Before syncing your Git changes with CVS, you should check if the repository has been updated. So let's mimic cvs update:
cd GIT_CVS_CLONE
git cvsimport -a -p x -v -d :pserver:USERNAME@cvs.drupal.org:/cvs/drupal-contrib contributions/modules/MODULE_NAMEAnd update our working sandbox accordingly...
cd WORKING_SANDBOX/MODULE_NAME
git fetch
git rebase origin/HEADCreating a patch
If you don't have CVS commit access, you would want to generate patches to send them to the module maintainer. Here's how to do that.
cd WORKING_SANDBOX/MODULE_NAME
git-format-patch origin..HEADFrom Git, back to CVS
If you have CVS write access to the module repository, you will want to push changes from your Git repository to Drupal.org.
First, get the CVS repository:
cvs -z6 -d:pserver:USERNAME:PASSWD@cvs.drupal.org:/cvs/drupal-contrib checkout -r DRUPAL-6--1 -d MODULE_NAME contributions/modules/CVS_WC_MODULENext, choose the Git commits you want to push to Drupal CVS. Look at git log and note the SHA1 of those commits:
cd WORKING_SANDBOX/MODULE_NAME
git log
git cvsexportcommit -v -w CVS_WC_MODULE <commit-sha1>If there were no problems doing that, you can now commit to CVS:
cd CVS_WC_MODULE
cvs commit -F .msg <some file(s)>Good going! Your changes are now on your Drupal.org CVS repository!
Resync your local Git tree
cd GIT_CVS_CLONE
git cvsimport -a -p x -v -d :pserver:USERNAME@cvs.drupal.org:/cvs/drupal-contrib contributions/modules/MODULE_NAMEResync your working Git sandbox
cd WORKING_SANDBOX/MODULE_NAME
git fetch
git rebase origin/HEADYou can also do all these steps for any other branch of your module. If you run git branch in your GIT_CVS_CLONE directory, you'll see it had imported all branches from cvs.drupal.org. Awesome!
References
http://issaris.blogspot.com/2005/11/cvs-to-git-and-back.html
http://www.kernel.org/pub/software/scm/git/docs/git-cvsexportcommit.html
http://www.kernel.org/pub/software/scm/git/docs/git-cvsimport.html

Can branches be created in Git with this method?
Or must branches and releases be created in CVS and brought into Git? (And in either case, how? :-P ) In short, how does CVS Quickstart Branching and Tagging guide apply when working with git?
benjamin, Agaric Design Collective
Warning and advice request
Warning: Create your branches FIRST (in CVS i assume). Cannot use this method to commit to head?
Successfully did everything up to this step. And then of course CVS fails:
cvs commit -F .msg 'example.module'Resulted in:
cvs commit: sticky tag `HEAD' for file `example.module' is not a branchcvs [commit aborted]: correct above errors first!
Any idea 'now what'?
There are about 15 commits to the git version that I'd like to get over to the CVS version. Neither has any branches yet.
benjamin, Agaric Design Collective
...
http://drupal.org/node/198469 tells us not to use -r with HEAD. Think of this as another reason to put as much distance between yourself and CVS as possible...
benjamin, Agaric Design Collective
Isn't there a simpler way?
I find the "from git to CVS" section in this howto extremely cumbersome and error-prone. it is a killer for the whole idea of developing your modules using git, instead of the dated CVS.
If someone can come up with something simpler (for example, the git-svn bridge has a simpler way of pushing commits), it'll be much appreciated.
--yuval
Automated script!
I mostly followed the setup above and, eventually at the end, created a script for automatically pushing the git commits from a certain date to the project's CVS repository. Lightly tested. Would appreciate others' refinements and enhancements, always:
http://data.agaric.com/node/202
benjamin, Agaric Design Collective