how to track multiple svn branches in gitPosted on March 3rd, 2014 No comments
[Note: This mirrored blog post was originally online at http://www.jukie.net/~bart/blog/svn-branches-in-git If you know Bart, link him here so I can update this citation.]
I must say that I am no fan of SVN, but SVN and I get a long a lot better since I started using git-svn. Long ago a good friend of mine, Dave O’Neill, taught me how to handle multiple branches using git-svn. I had used that technique until Dave taught me how to do it better.
Recently I saw this blog post which referenced Dave’s article talking about the first method. I guess Dave never got around to updating his blog with the better way. So I am going to do that here:
A few of my clients use SVN. Some I am guilty of introducing to SVN. But for this post I need to give you an example that you can follow along with. So let’s use shell-fm — my favorite last.fm client — with an SVN repo located at
NOTE: You should use a modern git release. If
git --versionis older then
1.5.3, you need to upgrade.
Let’s start by cloning this repository using git-svn:
$ git svn clone svn://nex.scrapping.cc/shell-fm -T trunk -b branches -t tags
NOTE: if you have commit access you may want to modify your svn:// url appropriately.
--stdlayoutis a short form for
-T trunk -b branches -t tags, and new versions of
This process will take longer then an
svn checkoutwould… a lot longer. There are two reasons for this. (1) you are getting all the history of the project, and (2) SVN has a very slow protocol for this purpose.
Anyway, once it’s done (it took me about 5 minutes) you will have a directory called
shell-fmwith the contents of
trunkchecked out in it. If not for the fact that the
.svndirectory is replaced with a
.gitdirectory you would have thought that you were using a slower SVN.
Enter into your new repository and you will see that you have a master branch that is, by default, following
$ git branch * master
I would like to insert here an advanced topic of packing your repository. I don’t want to explain it here, see the [man page], but trust me it will make your git experience much more enjoyable if you run the following once in a while:
$ git gc
Now, to update your working tree to the latest of the branch you are currently tracking, you would run:
$ git svn rebase
This is similar to
svn update. There are likely no updates available now, so this will do nothing.
Next, if you want to share something with the upstream svn server you would run:
$ vim source/main.c $ git commit -m"this is a test" source/main.c $ git svn dcommit
This is similar to
Now, let’s look at these branches I was promising:
$ git branch -r 1.2 autoconf clean plugins ripperbahn tags/0.1.3 tags/0.2 tags/0.4 trunk
Each of the above is tracking a remote branch in SVN, except for trunk which is tracking
trunk. When you run
git svn fetchall branches will be updated, and new branches on the remote will be added.
git svn fetchfetches the updates with out modifying the local working files (which
git svn rebasewould).
git svn fetchmimics standard
git fetchbehaviour with an upstream git server.
Working off remote branches is usually done on local topic branches — that is to say, not on
master— but you can use whatever you want as git-svn doesn’t care.
Let’s thus create a new branch for fixing a mythical bug on the 1.2 branch.
$ git checkout -b fixing-bad-1.2-bug 1.2
Almost immediately, and without server interaction, we get a checkout of branch 1.2 contents. You can see where you are with:
$ git branch * fixing-bad-1.2-bug master
If you carefully inspect output of
git logyou can see that git-svn reveals the branch name and upstream SVN commit ID on the last line of each commit:
$ git log -1 commit 308244b0d275db460e3b4527afd51258cece4d33 Author: strogg <strogg@7df44517-d413-0410-91cf-82ca28b36b55> Date: Thu Sep 13 19:39:51 2007 +0000 This is a patch from Wisq to make shell-fm accept 302 redirects as well as 301. git-svn-id: svn://nex.scrapping.cc/shell-fm/branches/1.2@252 7df44517-d413-0410-91cf-82ca28b36b55
We are on
252. If you prefer it, you can even get the svn style log output with
git svn log… but why?
Working on this branch is as easy as working off trunk. You edit, commit, and
git svn dcommitto upstream.
Switching between your local branches is easy…
$ git checkout -f master $ hack hack hack $ git commit $ git checkout -f fixing-bad-1.2-bug # and we're back on 1.2 bug fixing
Note that you don’t have to push your commits back to upstream immediately, or ever for that matter, to make use of the git repository to store your local changes. But if you do decide to you just need to run
git svn dcommit.
If you’re interesting in migrating CVS to git, have a look at the CVS to git Transition Guide.
Leave a reply