Branching and merging in Subversion is a great way to work on large new features without disrupting mainline development on trunk. However, it has a reputation for being so difficult that many developers never take advantage of it. In this post I’ll show just how easy it really is thanks to some newer features in Subversion and Subclipse (a Subversion plug-in for Eclipse). You should be using Eclipse 3.5, Subclipse 1.6.x and Subversion 1.6.x. Instructions on this page were inspired by the Subversion Red Book.
The discussion below assumes that you have a Subversion repository that uses the standard trunk/branches/tags structure. In other words, a repository at http://site.com/project with trunk, branches, and tags subdirectories.
I’ll also assume that you have already checked out a local working copy of trunk, and that you’ve already created an Eclipse project using this working copy.
When you want to work on a new branch you’ll follow these general steps using Subclipse, which are described in more detail below:
Your local working copy reflects some directory in the remote Subversion repository. If you initially checkout trunk, then your working copy reflects trunk. If you initially checkout a branch, it reflects that branch. Using the svn switch command you can have Subversion modify your working copy to reflect another directory in the repository. Switching may not sound that exciting but it’s key to branching and merging, as you’ll soon see.
First off, ensure that your working copy has no local changes. Either commit your changes or revert them.
Next, right-click your project in Eclipse’s Project Explorer, select the Team submenu, and click the Switch to another Branch/Tag/Revision… item. All of Subclipse’s actions are in this Team menu, so from now on I’ll refer to specific actions like Team > Switch to another Branch/Tag/Revision.
In the To URL field, you specify the URL of the repository directory you want to switch your local working copy to. If your working copy initially reflects http://site.com/project/trunk, you could specify a branch as http://site.com/project/branches/somebranch. Generally you’ll want to leave all of the other options in this dialog box as they are.
Creating a new branch is almost trivial. First, switch your local copy to trunk (if it’s not already trunk). And again, make sure you have no local changes.
Next select Team > Branch/Tag… and specify http://site.com/project/branches/yourbranch in the Copy to URL field. This will create a branch named yourbranch.
Click Next and leave HEAD revision selected. Click Next again, enter a commit message like “Created the yourbranch branch”, check the “Switch working copy to new branch/tag” checkbox, and click Finish.
That’s it! You’ve created your new branch in the repository and switched your working copy to it. Now you can implement your major new features in your branch and commit them to subversion without affecting trunk.
While you’re working on your branch, you should periodically merge the latest version of trunk into your branch to make sure you’re not straying too far away. Eventually, you’ll also need to do this as the last step before merging your branch back into trunk, to ensure you won’t cause any conflicts with trunk.
First you’ll need to switch your working copy to your branch, if necessary. Subversion will merge the changes from trunk into your working copy, and then you’ll commit your working copy to your branch to fully integrate the changes from trunk. So it’s vital that you start with your working copy as a mirror of your branch. And again, ensure you have no local changes.
Click Team > Merge… and select the “Merge a range of revisions” option. Make sure “Perform pre-merge best practices” is checked and click Next. On the next page, if it asks you to perform any actions, like updating your working copy, perform them and click Next.
On the next page, make sure you’re merging from trunk and getting all eligible revisions, and click Next. Leave all of the defaults for conflict handling and click Finish.
After the merge, the results screen will show you what happened. If you got any conflicts just resolve them as usual. Then commit any changes to your branch, and you’re done!
When you’ve finished development in your branch, you need to merge your branch changes back into trunk, so everyone else can share in the glory of your awesome new feature. This is usually where developers turn pale and run away, but fear not; Subclipse will guide you through.
Make sure you only perform this merge when you are completely finished with your branch! After merging your branch into trunk, you will no longer be able to use your branch. In fact, you should delete your branch after merging it into trunk (see next section).
First, merge trunk into your branch and commit any changes to your branch, as described in the previous section. We need to make sure your branch is consistent with trunk before merging it back.
Next, switch your working copy to trunk. Remember that Subversion merges changes into your working copy first, and then you commit them back to the repository. So Subversion will apply your branch changes to your working copy of trunk, and then you commit those changes to trunk.
Click Team > Merge… and select the “Reintegrate a branch” option. Make sure “Perform pre-merge best practices” is checked and click Next. On the next page, if it asks you to perform any actions, like updating your working copy, perform them and click Next.
On the next page, make sure you’re merging from your branch and getting all eligible revisions, and click Next. Leave all of the defaults for conflict handling and click Finish.
After the merge, the results screen will show you what happened. If you got any conflicts just resolve them as usual. Then commit any changes to trunk, and you’re done!
As previously mentioned, after merging a branch into trunk, the branch can no longer be used. Subversion keeps track of merges using the
svn:mergeinfo property. Because of the way it uses this property, once a branch is merged into trunk it can no longer be involved in merges properly. For the full story, please consult the last few paragraphs of this section on branching and merging.
Subclipse does not provide a way to delete an entire branch, so you’ll need to just run this command manually:
svn delete http://site.com/project/branches/yourbranch -m "Removing completed branch"