Working with Git against Subversion Repositories

Despite my previous post on why Subversion is not Dead, I really do love Distributed Version Control Systems. I’ve wanted for some time to move our development teams over to Mercurial or Git.

Our team is highly distributed so we store out code in a master Subversion repository in the cloud hosted by Codesion. Recently they have offered Git hosting as well. No, we did not need this to move to git but it makes a nice place everyone can push/pull to and from without worrying about VPN connections.

We are currently in the process of migrating projects over to Git. I plan to post about that experience here after everything is working smoothly. In the interim, I have been getting a few developers, including myself using Git+SVN.

Git as a Subversion Client

Git+SVN is a capability that Git has to ‘clone’ a Subversion repository into a Git repository. Essentially, it allows you to locally get the benefits of using Git and still push and fetch from a master Subversion hub. This is a great option for people just starting out with Git and if you are in a company that requires you to use Subversion for whatever reason.

Getting started with Git+SVN is very easy. First you need to download Git and install it. To clone the subversion repository it was as easy as running this command:


git svn clone --stdlayout --username cdail https://url/to/svn/repository git-repo

If for some reason the command dies or hangs, you can resume by running a fetch. This happened to me a few times as my repository I was cloning was huge. To continue after a hang:


git svn fetch

Be warned that this may take a very long time. The first time I ran it, it took around 7 hours.

Most of the operations after this point are standard Git commands. The few exceptions are interacting with Subversion. To pull the latest changes from subversion, run:


git svn rebase

To push any changes already commited to your local Git repository to Subversion, run:


git svn dcommit

Local Branching and Git+SVN

It is possible to leverage all of the capabilities of Git locally like being able to branch easily. The trick of course is making sure everything can get back into Subversion properly when required. A simple ‘git merge’ may not be enough as Subversion requires you to keep a linear history of commits.

Rebasing is what you will need to do to rewrite your history to keep it linear. This concept may be foreign for Subversion users. I had to do quite a bit of reading myself before I really understood how it worked. I would recommend reading this which provides a good summary of rebasing.

Branching is very easy. I’ve compiled a few simple steps that should help you merge your work back into subversion after working on a branch.

Branching

To create a local branch run:

git branch featureX

You can switch between branches by running the checkout command:


git checkout master
git checkout featureX

Merging

First make sure your master branch is up to date with SVN. You can rebase directly from a branch but I chose to rebase from SVN on master only and do my local work on branches:


git checkout master
git svn rebase

The next step is to rebase your feature branch on master. This makes the history linear from master allowing you to merge properly in a way SVN will be happy with:


git checkout featureX
git rebase master

If at any point you want to see what is going, use the ‘gitk –all’ command to see a graphical view of commits and branches. Make sure everything looks linear.

Now that you are rebased, you can merge this feature to master without worrying about losing commits.


git checkout master
git merge featureX

Check in gitk to make sure you changes are all present and linear.

Now you can commit to SVN as you would normally.