git-svn: a better svn client

A month or so ago, I decided I really should spend some time learning Git to see what all the fuss was about. Unfortunately, nearly everything I work on is in Subversion repositories. Thus, I really don’t have an opportunity to really see everything that Git has to offer.

However, I did decide to give the git-svn integration a whirl to start getting a feel for git. Basically, learn some of the basic commands, experiment with the tools, etc…. I must admit, I’ve been pleasantly surprised and I now feel that git-svn is nearly the perfect svn client. I don’t think I’ll be going back to normal svn clients for day-to-day work anytime soon. Why do I like it?

  • It’s fast – a “git pull” is much faster than a “svn update”. What’s more, “git pull” updates all branches, not just the one I’m working on. Other options like “git blame” and “git log” and such are nearly immediate where with svn, they take forever.
  • Disk space – yes, disk space is cheap these days, but it does matter. A fresh “svn checkout” of CXF trunk takes about 225MB of space. A fresh “git clone” of CXF takes about 154Mb of space. The git version also has the advantage of having all the branches and tags in that 154MB of space. With svn, I need an additional 225MB for each tag/branch.
  • Works better with tools – thing like “grep -r” and “find . -name” and such work much better with git as there is only the top level “.git” dir, not a “.svn” all over the place. I had to create a bunch of silly wrappers to various things to make using those tools in svn easier.
  • All tags/branches are available – if someone posts a stack trace to a JIRA, it’s trivial to flip over to whatever tag they are reporting it against to see what lines the line numbers line up with. Takes just a couple seconds. No “svn checkout” of various tags (or keeping 225MB of space per tag around) or digging through fisheye or similar.
  • Saves me a TON of time by allowing me to test multiple “commits” together.

That last entry is really key. If you read my last blog post, you know I’m a firm believer in “DON’T BREAK THE BUILD”. The best way to achieve that is to run the full set of tests before committing any changes. However, the full CXF test suite takes a little over 1/2 hour to run on my machine. Thus, it’s not something you WANT to run on all the little changes. It kind of becomes a limiting factor with how many commits/changes you can do in a day if you always run it.

That’s where git-svn comes in. It’s brilliant. With svn, if you make a small change and then “svn commit”, it’s immediately sent to the central repository for all (and the CI builds) to grab. Thus, you BETTER have run all the tests. With “git commit -a”, you just commit the changes locally on your branch. Thus, I can make some changes, run just the unit tests and maybe a couple of related sys tests, commit the changes, then move to the next JIRA/bud, make some changes, run a few tests, commit, etc… Basically, collect the changes as individual commits in my local git branch. At the end of the day, run a full “mvn install” to make sure ALL the tests pass. If so, run “git svn dcommit” to push the changes back into SVN. The way “git svn dcommit” works is that each commit to the branch goes to SVN as an individual commit. Thus, each JIRA or other change that was worked on and committed locally appears in SVN as an individual commit. This is good as you may need to merge (or backout) just those individual changes. With SVN, I always ended up committing several things together as a single commit which made things harder to track/merge to the fixes branches and such. Separate commits also help boost your commit count. 🙂

There are some downsides to using git-svn:

  • The egit eclipse plugin sucks, even compared to the subversion eclipse plugins. Call it a “work in progress”.
  • Merge tracking – for CXF, we’ve decided to use the script to track merges between the fixes branches. This doesn’t work with git so I still need the fixes branches checked out to do the merging. Ideally, everything would be “pure git” and we could all use the git merging, but that day isn’t going to come any time soon. 🙁
  • No integration with maven release plugin – I have no idea how the release plugin would deal with git-svn. Releases still need a “pure” svn checkout.

Anyway, I’ve started pretty much using git-svn for most of my work. I’m definitely happy with it. I’d be happier if Apache would allow us to go 100% git and not have the svn repo, but for now, this is certainly better than svn.