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 svnmerge.py 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.
FWIW, I’ve used the maven release plugin with GIT successfully. You just have to have exactly the right project structure. The biggest thing I’ve found is that you MUST release all projects in a particular git repository at once. It seems to have to do with the way the release plugin expects the checked out tag to look.
In SVN, checking out a tagged path results in just that subpath being in target/checkout. With the current GIT scm implementation, it gives you a copy of the whole git repo, which means the release plugin would have to navigate to a subdir to push the release out to the remote repository.
So, release the whole git repo’s project structure at once, and you can use git for releases today. Otherwise, I know Mark Struberg and others have been working on cleaning up the GIT scm functionality in Maven’s apis, so someday… 🙂
Well, I guess I should pay better attention. What I said only applies to “straight GIT”, not to git-svn stuff. But I suppose it wouldn’t hurt to put that sort of functionality on the wishlist, since it should be technically possible to do a release using git-svn.
Just to follow up with John…
I’m aware of the work going on to get the release plugin working well with git. That’s great and probably a good starting point. My specific issue is how that scm provider will work with git-svn. For example, after the tag, will it know to do “git svn dcommit” to push the tag to svn. As part of “perform”, should it use the local tag or should it checkout from svn? Those types of issues are what I’m thinking about.
And also rewriting history on multiple commit is fun.
Moreover git, even if only on client side, give you the opportunity to work with branches for almost your activity…it seems a bad idea from an svn perspective, but git allows you to do that easily.
And what about gitk tool? Isn’t it cool.
And also merging/diff tools like meld aren’t bad used within git day-by-day use.
I definitely prefer Git over SVN for the current open source project I am working on. Git just makes collaboration on a large project that much easier. I still think SVN is an excellent tool though. I’m not sure that either Git or SVN is better than the other, only that one is more appropriate for a given project depending on your workflow and project requirements.