My story with Git and Subversion

Subversion is the main code repository for the company that I work for currently. The same story also has happened for me as many other people: maintaining Subversion branches is difficult and annoying!

When I searched on the net about to possibly use on top of Subversion, there is a huge amount of content that explains how to maintain them on the server side. What I really needed was:

  • I do not have administrative privileges so I cannot touch Subversion server in this regards.
  • I did not aim to completely mix Git on top of Subversion.
  • I want to have Subversion as my main code repository. And, I need to have maintain local branches to track my development with feature branching and other useful concepts.
  • When my local work is done, I will just update Subversion repository with my updated code and optionally purge the local Git branches.

During my searches, I came across a very useful post by Rein Henrichs; the post talks about how to use Git branching feature to manage the work flows for branching with agile teams. The good point about such work flow is that it does not talk about the server side of the code repository. After some playing around, I came up with the following work flow with the following basic principles:

  • I do not use git-svn extension utility.
  • I do not use Git on top of my Subversion.
  • The main code repository is Subversion.
  • I have a local Git server to maintain my local changes.

So, my current daily work flow is roughly as follows: I start by checking out code from the main Subversion repository:

$ svn co svn+ssh://server/project project

On the side, I have installed an instance of GitLab on a machine in the network (let’s call it local Git server). So, next, I initialize a Git repository:

/project $ git init --bare

Having the project defined in GitLab, now I can push my original Subversion checkout as the initial commit to the master branch of my local Git:

git push origin master

It goes without saying that .git is ignored in Subversion configurations and .svn is the same in Git configuration. So, in the big picture, I have code base that is updated from the main Subversion repository, then worked on, locally pushed to a Git server and finally updated in the main Subversion repository.

Here comes the sweet part! Git branches are managed in such a way that Subversion has no clue of. So, I just follow Rein’s post on how to have branches and maintain local branches for different tickets that I work on. Occasionally, when there are Subversion updates, I simply

  • Checkout master
  • Push the Subversion updates to the origin master
  • Switch to a local branch
  • Perform a git rebase origin/master

Merging would be that simple and keeping the local branches just as up-to-date as the main Subversion repository. Again following Rein’s post, when my local work is done then I simply

  • Make sure that current branch is updated with master
  • Perform git rebase -i origin/master choosing the commits that I really want to have
  • Checkout master
  • Perform a final git merge MY_LOCAL_BRANCH

And, now I have a master (Subversion trunk), that is ready to be committed to Subversion repository. Since I started to follow such a workflow, I must admit that life has been much much more enjoyable with Subversion. I just did not get started with all the good stuff that I already have with Git. More interestingly, it seems that people are getting interested to collaboratively try GitLab and see how branching works. I look forward to this as a migration motivation for the team to move to Git very soon!