You are a happy user of SVN? Fine. You probably don’t need my receipt.
You use Git wherever possible but sometimes you need to resort to SVN as not everybody has yet seen the beauty of the Git workflow? 🙂 Good. Maybe this workflow fits yours.
We’ve been starting to use the Object RDF Mapper SuRF in our team and are happy with its overall support. There are however a few cases missing and some issues here and there we’d like to fix. Now SuRF uses Google Code for hosting which is perfect for many projects. I myself host two of my projects there. But it’s showing its age a little and Github is the place to got for all my new projects.
So while working a bit on SuRF which is hosted on SVN I’d like to use the beauty and ease of Git on Github without making it impossible to keep the fork in sync.
If you come from the SVN world, you might understand “fork” differently to those from a Git background. Forking with the former is a generally negative process as a project splits up and people who probably worked together before now go their own ways. With git however forking and merging back is so easy that everybody forks right away and then creates a merge request (a Github feature) to sync the changes back to “upstream”, the main author’s source.
So now that I get a personal Git account I can move freely and also share my changes with the world. No need to have my patches hidden away separately in a bug tracker. Also in general, once the main projects looses momentum others are readily available to take over. This is especially useful with smaller projects I’d say.
Synchronizing Git from SVN
There are several articles out there on how to set up a bridge between SVN and Git. I found http://www.fnokd.com/2008/08/20/mirroring-svn-repository-to-github/ to be very helpful.
Using git-svn the author sets up a repository on his server and creates a “vendor” branch to be updated with changes from SVN. A cron job then regularly checks the SVN repository for changes and pushes them to the Github Git repository. Own changes go to the master branch which can from time to time has the “vendor” branch merged in via “git merge origin/vendor”.
Getting changes back to SVN
In my case as I will play around a bit to test different ideas not all changes should go straight back to SVN. Also as I’m not sure what policy upstream applies for changes I am not interested in directly pushing changes upstream. Also, I’ve already set up a project in the past that tries to run Git and SVN both ways which resulted in a not-so-nice Git history due to the incompatibilities between both versioning systems.
Instead I will focus on extracting patches to go upstream.
However, nothing is as easy as it seems, and git doesn’t produce Diffs consumable by SVN. There is a short script from http://gist.github.com/582239 called git-svn-diff which will do the conversion from the diff between the last SVN version and the version given to the script. As this script needs the git-svn history locally I simplified the script and documented the workflow for everybody to use. You’ll find the script under http://github.com/cburgmer/surf/blob/master/git-svn-diff.sh.
The following steps will download (“clone”) the repository, create an empty branch and pick the given Git commit that we will create the diff for. Not too simple but doable:
$ git clone git://github.com/cburgmer/surf.git$ cd surf$ git checkout -b mydiff origin/surfrdf$ git cherry-pick COMMIT_SHA1_ID$ wget https://github.com/cburgmer/surf/raw/master/git-svn-diff.sh$ sh git-svn-diff.sh > /tmp/my_patch.diff
This patch can then be applied to SVN from the source directory:
$ patch -p0 < /tmp/my_patch.diff
Update: Fixed an issue with selecting the right branch