Friday, August 6, 2010

Managing remote branches with git svn

git svn is a great way to work locally using git for remote svn repositories.  The basic workflow is rebase, hack, commit, hack, commit, etc, rebase, dcommit.  You'll get lots of google results by just searching for git svn.  One feature that's really nice is interactive rebase.  For example, to interactively examine the last 8 (local) commits and have the option to delete or combine commits (squash), do
git rebase -i HEAD~8

I recently needed to create a new feature branch on the remote svn, work on it, and then merge it back into the trunk.  It took a whole lot of digging to figure this out, so I thought I'd share what ended up working. I can't vouch for the optimality or safety of any of this.  I just know that it worked for me.
First of all, I made sure to check out the repository using the --stdlayout option.
git svn clone svn+ssh://user@server/svn/repos/project --stdlayout
Then, to create a new remote svn branch called "new_feature",
git svn branch -m "Branch to add in new_feature." new_feature
And check out the new branch locally
git checkout -b new_feature new_feature
Then the usual.  Hack, commit, etc.  It's not a bad idea to first do "git svn dcommit -n" to make sure your dcommits will go to the branch directory in the remote repository.
When it's finally time to merge back into the trunk (this was the hardest part to find - this post at stackoverflow was really helpful), re-checkout the trunk to a new local branch, which I called "merge".
git checkout remotes/trunk -b merge
This seems to be the key step.  Merge the feature branch with the --squash option.
git merge --squash new_feature
Then commit and dcommit.  You may want to do a dcommit -n to reassure yourself that you're committing to the trunk.
git commit -m "Merge new_feature branch"
git svn dcommit -n  (make sure commit will go to trunk)
git svn dcommit
That's it!  You may want to clean up your branches.  This is what I did.
git checkout remotes/trunk
git checkout -b localtrunk
git branch -D new_feature
git branch -D merge


Zaak said...

Wow, nice write up. I'll definitely read this more thoroughly later today. In the lab we use old svn (b/c of RHEL 5 I think) and it's branching and merging capabilities are quite limited. This seems like using git svn might help me manage my branches and merges better.

Dan said...

Thanks, Zaak. I like git. I've started using git for new projects and even thinking about switching existing svn repositories over to git. I *do* still like websvn better than gitweb.

git svn can be a little clunky... I think mostly due to the fundamental differences between their repository models (which I don't totally understand). It's also relatively young. Ultimately you're limited to what the svn repo will support, so you can't do anything *too* fancy. IMHO interactive rebase is worth the price of admission, regardless.

As a side note, I totally recommend using git for publications. I'll make a new directory, put all of the latex / matlab /data / figures in it and make it a git repo. If you keep up on committing, it forces you to organize your work. You can create tags when you send it to your advisor, submit, etc. It's also a really good way to be able to work on a document on multiple machines. It's occurred to me that you could probably use this to manage bib files across multiple documents, though I haven't had time to mess around with it.