Git tips and tricks part 3: working with svn branches and cherry-pick
After several weeks of git usage, I’ve developed a nice workflow. First, we’ll start with working with several svn branches via git.
Working with svn branches via git
Assuming you’ve properly cloned your svn repository, you should have your trunk and remote branches fetched from svn. You can see the remote branches via
git branch -r
If you have colorization turned on, then
git branch -a
Will give you all your branches (local and remote) and color the remote ones in red. The way you want to work is to create a local git branch for every svn branch you’re working with. So you might do something like
git branch local-trunk trunk
git branch local-1.5 branches/1.5
This will create two local branches (called local-trunk, and local-1.5 respectively) that follow the corresponding remote branches (trunk, and branches/1.5).
Now we’ll switch to the trunk…
git checkout local-trunk
Do some hacking, and commit the change
git commit -a -m "this is my hack"
Let’s say this was a bugfix and you also need to apply it to the branch. Switch to the branch:
git checkout local-1.5
To pull individual fixes from trunk you can cherry-pick the fix by its commit hash, which you obtained when you committed or via a log.
git cherry-pick 234adsfa7s8dfasdf
This will automatically pull in the change and commit it to your branch. If you don’t want to immediately commit but want to mess with the files first, then use the -n switch, which merges in the fix but doesn’t commit it. Then you’ll want to git svn dcommit to push your change out to the svn branch. This procedure is much faster than using svnmerge.py.
Nonstandard or wacky branch structure
It so happens that my repository is set up in a slightly nonstandard way due to a particular legacy. Instead of having a structure such as foo/trunk and foo/branches, I have trunk/foo and branches/[branchname]/foo. As it turns out, git supports this very well as long as you specify the format using wildcards in your .git/config
[svn-remote "svn"]
url = http://www.myrepo.com/svn/parent
fetch = trunk/foo:refs/remotes/foo/trunk
branches = branches/*/foo:refs/remotes/foo/branches/*
The format of this file basically has two parts separated by a colon. The first part tells git what the repo looks on the svn side. The second tells it what to call the branches that git creates to correspond to the ones out in svn. You’ll notice the placement of the wildcard on the third line is what generates all the branches correctly.
Note: Please see all posts tagged git for the rest of the series.










1 Comment