Thursday, July 09, 2009

Merge Tracking with Subversion 1.5

A year or so ago, a few of us at the office piled into a conference room to watch a webinar about all the new features Subversion 1.5. One of those features that sounded cool, but was conceptually opaque to me, was merge tracking. But, recently, I've had to get my merge on, and wanted to see what it was all about, and it was one of things I'd wished I'd taken the time to do sooner.

The bottom line, is that now Subversion actually has a workflow for keeping your branch in sync with the trunk, so you've got less surprises when it's time to put your work back into the trunk. You no longer need re-branch in order to get the latest trunk changes for your branch. You can just tell SVN to get any changes from the trunk since you either made the branch, or last took changes from the trunk.

The workflow is pretty simple. You make your branch, you work on it for a while, you say, "I'm going to be merging into the trunk eventually, I'd better make sure that goes smoothly." so you update your branch with the latest from the trunk:


$ pwd
/home/user/my-calc-branch

$ svn merge http://svn.example.com/repos/calc/trunk
--- Merging r345 through r356 into '.':
U button.c
U integer.c


So, since we didn't specify revisions, you can see that Subversion is fully aware of what revision of the trunk your branch came from. Also, Subversion is going to store all the revisions that you've just merged into your branch. You can do this to see:


$ cd my-calc-branch

$ svn mergeinfo http://svn.example.com/repos/calc/trunk
r341
r342
r343

r388
r389
r390


You can also see which changes from the trunk that you're missing:


$ svn mergeinfo http://svn.example.com/repos/calc/trunk --show-revs eligible
r391
r392
r393
r394
r395


So, you can repeat this process often, which I'd recommend. The more frequently you integrate the changes from the trunk, the more unicorns and rainbows come merge time.

Another benefit of Subversion keeping the merge information around, is that you can undo merges:


$ svn merge -c -303 http://svn.example.com/repos/calc/trunk
--- Reverse-merging r303 into 'integer.c':
U integer.c


This is just for keeping your branch in sync with the trunk. How bout when you want to move your changes into trunk when your work is complete? Well, all this merge history will be taken into account when you decide to merge back into the trunk. Subversion will understand what has already been pulled in from the trunk (or any branch for that matter), and only merge the revisions that aren't in the merge history.

This is a very handy feature, it's a shame I waited this long to dive in.

(Note: all these examples I shamelessly copied from the svn book)