Be Present Now

durdn is here talking about tech stuff. or so he says.

Using Git with Subversion: Tips that will make your life easier

In the last couple of years I've been working on various projects that - unfortunately - still use Subversion as their version control system. I moved to git already a few years ago and I wanted to keep using it as much as possible.

Luckily git-svn is an incredibly complete tool to interact with a Subversion repository without leaving the comfort of the git power toolset. But there are gotchas. This post assumes you are already a little bit aquainted with git-svn and you know how to interact with a subversion repository using it.

In case you are not or you want a refresher, please have a look at this post from Bart or google it. The list below is a list of all the tips I had to research and integrate in my workflow to keep using git joyfully in conjunction with Subversion. Enjoy!  

Setting up the files to ignore

You should make sure that git ignores the same files svn does. The simpler trick is to append the list of svn:ignore files to the default git exclude file:

git svn show-ignore >> .git/info/exclude

An alternative method is the magical update-index:

git update-index --assume-unchanged files to ignore

This is quite a fine trick I've consistently used in the past year. If you need more information, have a look at this post on Stackoverflow. If you use the latter method, how do you find out later that a file has been ignored in git? You can use this:

git ls-files -v | grep ^[a-z] | sed -e 's/^h\ //'

Shallow clone big repositories

I've worked with codebases that are above 1.5Gb for a full Subversion checkout. I am not kidding. Checking out the entire history commit by commit - the way git-svn does - would be impossible. The repository is simply to big. The way around it is to create a shallow clone of the repository, instead of copying the entire history of the project you just copy the last n commits and proceed from there. For example:

git svn clone -s -r604:HEAD http://nick@svn.xxxxxx.com/repos/ -T trunk -b branches -t tags

Mandatory Stackoverflow reference.

If you added the .svn folders by mistake in git

Sooner or later you'll run into a few snags. For example one time I didn't use git-svn right from the start, I just checked out a project from subversion and I wanted to do my own tracking using git. At that time I mistakenly added the .svn folders to the index (staging area) in git.  How to keep those important files but remove them from the index?  Tricky! Here's how to untrack files without deleting them in git:

git st | grep .svn | awk {'print $3'} | xargs git rm --cached

Very clearly explained in this chapter on progit.

What to do when a Subversion repository moves

When a Subversion repository moves (or when you have to access it via VPN and do some smart tunneling that will change its address) you have to follow the correct procedure to avoid a full checkout. The first method listed at the git wiki is the one with which I had consistent success. Directly from the wiki here is the important part:

  • Edit the svn-remote url URL in .git/config to point to the new domain name
  • Run git svn fetchThis needs to fetch at least one new revision from svn!
  • Change svn-remote url back to the original url
  • Run git svn rebase -l to do a local rebase (with the changes that came in with the last fetch operation)
  • Change svn-remote url back to the new url
  • Run git svn rebase should now work again!

This will only work, if the git svn fetch step actually fetches anything!

Conclusion

Working with git is a joy for me. You have total freedom and total control. You can commit endlessly, reformat your commits, squash them into clean ones, branch like crazy. You can bring the same joy with you even if you have to interact with Subversion. I've done it for the past 2 years. And it works beautifully.

6 July 2011

comments powered by Disqus