Some months ago I gave git a first try for developing some stacked core patches. I quickly get used to it and to its nice features (german). Luckily its SVN integration is really nice and simple to use so GIT is even a fine replacement for the usual SVN client. Unfortunately for CVS things are much worse.. :( Poor cvs!
First tries..I decided to don't go back to CVS for maintaining drupal modules. First I tried using the public GIT mirror of the whole drupal CVS from the French drupal community, however I quickly noted that it was broken for the rules module, so I tried to set up my on mirror. I started using Sam Boyer's scripts, however I had some misc small troubles with them, but more important those scripts copy the whole drupal CVS - but I didn't like to waste ~6 gigs of disk space and the time to sync all the unneeded stuff. So I ended writing my own script based on the instructions in the drupal handbook for maintaining a module with git and Sam's script. After some weeks going back and forth I finally ended up with something useful, so here are my experiences:
What is it about?Currently I've set the script up to export the drupal CVS of some of my modules to GIT - its automatically pushing to my github account, which is quite convenient. It syncs only the really needed modules using rsync - which is an important step as its greatly speeding up cvsps when exporting from CVS. The nice thing is that it doesn't overwrite any changes not yet in CVS, so I can use the same git repository on github to develop new stuff and export to CVS later on. You can find the script here. To use it, first adapt the config file to your needs, then manually run "sync-cvs" once - so your git repositories have been created. Then go to your $GITDIR and create a new git repository "$module.git" and add the remote you want to push to as "origin" using
git remote add origin YOUR_REPOS. Now you can try running "run-sync.sh" which will sync all branches found in CVS with your origin repository.
Exporting back to CVSIdeally one wouldn't have to care about exporting to CVS, just pushing to the github repository should be enough. Well I think one could automate this too using github's service hooks, however for now I export back to CVS manually. For that you need a fully working local CVS checkout for the branch you want to commit. I've just created one for each branch I'm syncing. Then I've setup my local git repository that way:
Now for exporting you can just use
# Tell git where to find the local CVS repository
git config cvsexportcommit.cvsdir /full_path/to/repos
git cvsexportcommit -c -p -v -u <commit-id></commit-id>, however having to export each commit on its own is much too cumbersome. So I've setup some useful aliases:
So you can run
git config --global alias.lc "log ORIG_HEAD.. --stat"
git config --global alias.export \!"git cherry | sed -n 's/^+ //p' | xargs -l1 git cvsexportcommit -c -p -v -u -k"
git config --global alias.export-cvs \!"git cherry cvs | sed -n 's/^+ //p' | xargs -l1 git cvsexportcommit -c -p -v -u -k"
git exportto export all commits report by git cherry at once. If you have not pushed your work back to github, this should work great and push everything new into CVS. If you want you can double-check what's getting exported beforehand using "git lc" or "git cherry". However if you have already pushed some work to your remote git repository (github), it won't be exported automatically. For that I set a tag "cvs" for the last revision being in cvs:
git tag -f cvs COMMIT-IDThen the alias "git export-cvs" can be used - and everything since the tag will be exported to CVS... :)
PitfallsWhen doing my script I quickly noted why the French mirror doesn't work for rules: cvsps failed when exporting the rules CVS repository. Luckily I noted that the problem is gone with the cvsps (or git?) version in the latest ubuntu release (9.10). Sorted that problem out I quickly ran into another when exporting to CVS. My patches couldn't be applied to CVS during export so it failed - the cause were the ids
$Id$CVS maintains. When the chagnes are commit to CVS the file changes due to the CVS ids, what might cause the next patch to fail. Really ugly! :( After some investigation I stumbled over the solution: Git supports an option "-k" for the cvsimport command. Those "-k" option makes the CVS Ids being replaced to
$Id$- thus for GIT the ids won't change any more and the patches apply! Yeah! Note: My script already uses that option. However you also need to set to specify -k in your cvsexport command, which is only support for git versions >=1.6.4. For the other way round (cvs -> git) it's supported also in older versions. Ubuntu 9.10 comes with 1.6.3, but luckily there is PPA where you can get the latest version for ubuntu. To update your ubuntu git version just run this commands as root:
apt-get update && apt-get upgrade
Update 22.01.10: Fixed cvsexport command to use -k and mention that git 1.6.3 doesn't know -k for exporting to cvs, but cvsimport does.