Merging and branching in Subversion 1.5

Upcoming release features automatic merge tracking -- finally!

1 2 3 4 Page 2
Page 2 of 4

Merging before Subversion 1.5

Branching in Subversion is fast and efficient. When you create a new branch or a new tag in Subversion, you are actually creating a reference to the original version, which can be done very quickly indeed. Modifications are successively logged against this new version, leaving the original version unchanged.

To create a new branch in Subversion, you simply use the svn copy command to create a copy of a directory in the Subversion repository. By convention, branches are placed in a repository directory called "branches." For example, in Listing 1, I create a branch of the main trunk called "bug-fix-101," presumably to fix bug number 101.

Listing 1. Creating a new branch: bug-fix 101

C:/>svn copy file:///e:/svn/repos/tax-calculator/trunk \
             file:///e:/svn/repos/tax-calculator/branches/bug-fix-101 \
             -m "Creating a branch to fix bug #101, which is a bit tricky"

Branching and merging have always been supported in Subversion. In versions previous to 1.5, however, Subversion did not automatically track merges. No record was kept of what change sets were merged, when, and by whom. Instead, users were advised to use informative log messages to keep track of merges. For example, to merge all the changes from the previously created branch, you would do something along the following lines:

Listing 2. Merging all changes

C:/>svn merge file:///e:/svn/repos/tax-calculator/branches/bug-fix-101
C:/>svn commit -m "Incorporated fix for bug #101."

Successively merging several bug fixes from a branch (for example, a production release branch), is a bit trickier. In brief, you would need to work out exactly which revisions to merge (using svn log commands and informative commit messages), and provide these revision numbers using the "-r" option, as shown here:

Listing 3. Merging specific changes

C:/>svn merge file:///e:/svn/repos/tax-calculator/branches/release-1.0.0 -r25:28
C:/>svn commit -m "Incorporated latest bug fixes from version 1.0.0."

This approach obviously has its disadvantages. First of all, it relies on human intervention to keep the repository clean and well documented, which is not a good habit. Working out what revisions need to be merged is a painful and error-prone process at the best of times. And, because Subversion doesn't know about what merges have occurred, little automation is possible in the merging process.

As you will see, Subversion 1.5 makes all of this a lot easier.

Merging in Subversion 1.5

For this article, I will be using a Subversion repository containing a single Java project called, somewhat arbitrarily, "tax-calculator," which is an API for calculating income tax. Note that, for the purposes of this article, the actual content of the project doesn't really matter -- if you want to follow along at home you can easily use your own project instead.

The application's main development happens in the trunk, whereas branches are used for specific releases. So the repository directory structure looks like this:

+ repos
      + tax-calculator
          + trunk
          + tags
          + branches

The best way to get a feel for the new Subversion merging features is to work through a practical example. This example will be intentionally simple. See the Resources section for a more complex example of merging with Subversion 1.5, complete with a non-trivial history of merges.

Check out the project

First of all, we check out the project from the main development branch, using a fairly standard approach:

Listing 4. Check out the project

E:\>svn co file:///e:/svn/repos/tax-calculator/trunk tax-calculator-dev
A    tax-calculator-dev\tax-calculator
A    tax-calculator-dev\tax-calculator\test
A    tax-calculator-dev\tax-calculator\test\com
A    tax-calculator-dev\tax-calculator\test\com\javapowertools
A    tax-calculator-dev\tax-calculator\test\com\javapowertools\taxcalculator
...
Checked out revision 20.

In this example, we have already released two versions of our API into production: versions 1.0.0 and 1.1.0. A branch exists for each of these, as shown here:

Listing 5. This application has two branches so far

E:\>svn list file:///e:/svn/repos/tax-calculator/branches
release-1.0.0/
release-1.1.0/

To make things clearer, we have also checked out the latest production release into a separate directory called tax-calculator-prod:

Listing 6. The production release is also checked out

E:\>svn co file:///e:/svn/repos/tax-calculator/branches/release-1.1.0 tax-calculator-prod
...
Checked out revision 21.
1 2 3 4 Page 2
Page 2 of 4