Thursday, 22 March 2012

Experiences of Using Git-Svn on a Large Project

I have been dabbling with Git for a little while now on side projects and I have felt that it was a very powerful tool that offered a big improvement over the last generation of version control systems, but it was only this week that I started using it in anger at work on a large project and so far I have not been disappointed.

Git and Svn

As we use Svn as our VCS I am using git-svn to connect between my local Git repo and the remote Svn one. The first thing you notice when moving to Git is the increased speed of many of the actions that previously took what felt like several seconds, for example fetching the commit log is now pretty much instant as is looking at a files history, in fact I have found myself using IDE features such as annotate much more now. I can annotate a file, click to examine all the other files touched in the same commit and then look at a couple of diffs all without any visible lag.


The first thing you have to do is get a git clone of your SVN repo on your machine. Beware, this will take a while, to clone our SVN took approximately 2 hours and resulted in a git repo of 300Mb. This would have taken longer without the --log-window-size option and can also be used with the git-svn fetch command.

git svn clone -s --log-window=10000 gitr

You can also limit the amount of work git-svn has to do by specifying the revision that you wish to clone from.

git svn clone -r 2908 gitr

Pushing and Pulling

The most obvious difference between using git-svn rather than git by itself is that whereas you would push and pull to the remote git repo, instead you dcommit and either fetch or rebase, the later of which reorders the commits that come in to put yours on top.

git svn dcommit
sit svn [fetch|rebase]


A nice feature that comes built in, but switched of by default, is the color coding on the command line which makes the key information stand out, especially when running a quick diff before a commit. To switch this feature on you just need to enter the following.

git config --global color.ui "auto"

To enhance the command line further you may find the script that a friend sent to me useful. It modifies your command prompt not only to tell you the name of the branch you have checked out but also, by the colour of the branch name, whether you have any uncommitted changes.

user@host:~/git/git_svn_bash_prompt (master) $ _

The script itself can be found here on github;

To get it to work just download it and add the following line to your .bash_profile or equivalent.

source git/git_svn_bash_prompt/

The Log

Looking at the commit log in git is not only faster but also more user friendly because of features such as the automatic pagination and the different types of layout available. The oneline display option is so useful that I set it up as an alias.

alias gitlog="git log --pretty=oneline"


Another instant win for me was how easy it was to move my commits from one branch to another. Instead typing this;

svn merge -c 188973 --ignore-ancestry .

It was now a simple matter of cherry picking;

git cherry-pick e4df5


I also found the simplicity of creating a branch made it easier to work on more than on thing at a time. Quite often I will find myself working on a feature only to be asked to look at an urgent issue or to make a quick change somewhere. It is so much simpler now that I can either stash the work if it is incomplete or commit it locally, branch from trunk then make and commit the change, before going back to carry on with the feature.

Encouraging Uptake

While you can use git-svn in isolation with everyone else working away on SVN it can be much more useful if you can encourage others to work on git too. This is obviously more difficult on a large project with many different developers of varying experiences. To this end we have as part of our monthly tech book club ordered 20 copies of the Pro Git book, which we will be following up with some practical sessions to introduce people to the basic workflow.

To be continued ...

I will try to follow this up in the next few weeks with more observations of how using git-svn helps or hinders as opposed to vanilla svn.

1 comment:

  1. Hi Stuart - great post. I have been running git svn in a similar way for the last couple of months, and I found the annotation mode particularly helpful too.
    A couple of other things I found helpful: Rebasing multiple commits into a single commit. This helped the load when pushing back to SVN, where a CI server would often pick up halfway through several commits from git svn dcommit. (There are probably other ways around this, such as the CI server pausing for x seconds before kicking off a build and waiting for any more checkins - I know Team City can do that). Also, the ability to amend the previous commit is particularly helpful, and can often work as a second staging area.
    Out of interest, did you run a garbage collect on your 300Mb repo? I ran it on my 15Mb repo after cloning from svn and that resulted in ~700Kb - Nice!