Going Rogue with git-svn on OS X

I’m sure that most of you have discovered that Git and github are the new hotness in source control. Once you go Git… well, you get the point. But what happens if you DO have to go back to Subversion? Not to worry, git still has you covered in the form of git-svn.

The git-svn command allows you to interact with a subversion repository through a git front-end on your local box. You get all of the fun branching and general git-ness without pain of svn. Even the mythical developer on a plane can make commits without a network connection!

Preparing the Goods

If you already have git and svn installed you might notice that you have a bunch of git commands available — although the all-important git-svn may be missing. If this is the case, the likely reason is that you are missing the perl bindings for subversion. This is okay and is easily fixed via macports. The first thing you need to do is uninstall git-core:

sudo port uninstall git-core

Then you need to reinstall it with svn support (which will setup the svn perl bindings automatically):

sudo port install git-core +svn

After this finishes (takes a few mins), the ‘git-svn’ command should be a available.

Going Rogue

If your project is stuck in svn purgatory; you can still use the new hotness while it readies itself for the coming liberation. The first thing you need to do is smuggle the code out of svn and into a local git repository:

git-svn clone http://svn.foo.org/project/trunk

Okay, now this is going to take a while. Git is going to build a local git repo from scratch using each revision starting out at revision #1. If your svn repo has a bunch of commits (1000+) it’s going to take a while. It’s worth it though, trust me.

After this finishes you’ll have a fully functioning git repo on your box that is connected to your svn repository. The one thing that clone doesn’t take care of for you is mirroring all of the svn:ignore stuff. You can do this two ways:

Stay completely rogue and keep the ignore files locally:

git-svn show-ignore >> .git/info/exclude

Help out your other git-svn comrades by committing a .gitignore file to the svn repo:

git-svn show-ignore >> .gitignore

The first one doesn’t touch the svn repo and will keep your git-svn usage under the radar. The second will add .gitignore to the svn repo and will only need to be done once. This can be useful if you’ll be busy converting others to the git-monster as the new recruits will have one less thing to worry about.

At this point you should have all of your local git commands available for your disposal.

Code Trafficking

You can work with your local git repo just as you would with a normal git repo. The usual suspects are there: ‘git commit’, ‘git branch’, and ‘git stash’ will all work as expected without touching the svn repository.

You can grab the latest changes from the svn repo by issuing:

git-svn rebase

This will pull all of your local changes out of the repo temporarily, pull down the latest changes from svn, merge them into your git repository, and then apply your stashed changes on the new ‘base’.

When it comes time to get your wares back into subversion you can use:

git-svn dcommit

This will take all of your local outstanding git commits and translate them each into a standard svn commit complete with message, one at a time. The other repo denizens will be none the wiser because when you issue a dcommit — you’re generating plain old svn commits.

Exit Strategy

Hopefully at this point your suffering has been alleviated, freeing you to champion an underground git movement in your team and repository.

You now have the real ultimate power at your fingertips; go forth and dominate… silently.