Merging Does Not Have To Be So Bad

September 18, 2008

Subversion fixed a lot of pain points of CVS, but merging was not one of them. When doing branched based development, you perform lots of merges. Doing this manually in Subversion requires searching for revision numbers for simple tasks like merging a branch back to trunk or merging an updated trunk into a branch. For anything more complicated, it becomes a real mess. I’m unsure why Subversion remains so low level in this regard while tools like bzr and git make merges easy. Luckily, third parties have provided tools to ease the pain for those projects that choose to use Subversion.

:EXTENDED:

Divmod’s Combinator

Divmod’s Combinator is a Python tool that manages branches for projects. It also manages PYTHONPATH for those projects as well.

Combinator adds mkbranch, chbranch, and whbranch commands which create a branche, select a branch, and query the active branch for a project. For merging, you use unbranch. For example, chbranch chesspark website-typos-1234 would change the active branch for the chesspark project to branches/website-typos-1234 (relative to the project root). After you make some changes, you merge to trunk with unbranch chesspark and commit from the trunk working directory.

The Good

The Bad

project/
project/trunk
project/trunk/...
project/branches/
project/branches/website-typos-1234/
project/branches/website-typos-1234/...
project/branches/other-branch-2345/
project/branches/other-branch-2345/...

</code> Each branched directory must be a copy from /trunk.

The Verdict

Combinator does its job well. Some of the error messages can be opaque at times, but if you are willing to live with its path requirements, it is excellent at what it does. Several of us have used Combinator for a few months now for Chesspark development, and aside from the symlinks and /locals management, we haven’t had any problems.

The tool, warts and all, made branch based development easy enough in Subversion that we actually started doing it. Our code is much better for it.

svnmerge.py

svnmerge takes a slightly different tactic. As its file extension implies, it is a self-contained python script. Like Combinator, it makes branch based development easy, but unlike Combinator it can cherry pick patches and handle repeated merges from trunk to a branch.

You use svnmerge.py init to initialize a branch for tracking. svnmerge uses a few special revision properties to store merge information; this helps it keep track of which revisions are already merged. It never commits for you, but it does provide a default commit message that you can use if you choose. For example, to initialize a branch for tracking and merge in the latest changes from trunk:

cd /path/to/branch
svnmerge.py init
svn commit -F svnmerge-commit-message.txt
svnmerge.py merge
svn commit -F svnmerge-commit-message.txt

</code>

You can cherry pick revisions to merge by specifying them as an option to the merge command.

Merging the other way is also easy. You just initialize trunk for tracking a specific branch, then merge from that branch. The only difference from the above is that -S <branch> is used to specify which branch to work with.

The Good

The Bad

The Verdict

It’s simple and easy. It supports advanced functionality that Combinator does not. It makes merge history available to everyone at the cost of an extra commit and some revision properties. It seems to be the winner.

I have not had as much experience with svnmerge as with Combinator, but I’ve started using it for Strophe and Punjab. So far, I’m very happy.

Merging Does Not Have To Be So Bad - September 18, 2008 - Jack Moffitt