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