Apache Subversion: Best Practices for Branching & Merging
A version control system (also known as ‘revision control’) provides a central, online repository where you can store your project, whether that’s the source code of a software program, the Word documents of your autobiography, or photos from your weekend away. When you place a project under version control, the system remembers every previous version of your project, so you can recover these earlier “revisions” at any time, for example if the current version of your project contains bugs or unwanted features, you may want to revert to a revision before it all went wrong.
When you’re collaborating on a project, a version control system also ensures that every member of the team has access to the most recent version of the project, regardless of their geographical location.
When it comes to version control, Apache Subversion is a popular and well-established solution. However, despite everything that SVN has to offer, there’s one area that many users are uncertain about - and that’s branching and merging.
The Problem with Branching & Merging
A branch is an additional line of development, where you can work independently of the main development line, which is known as the ‘trunk.’ When you’re happy with the changes you’ve made to your branch, you merge these changes into the trunk, which is where you may encounter the dreaded merge conflict.
Conflicts occur when someone has been working on the same part of the project as you, and has committed their changes before you. Since Subversion cannot easily apply your changes to this modified version of the trunk, you’ll need to try and manually incorporate both sets of changes into the trunk. Most of the time, they’ll be room for both sets of changes - just because someone’s altered the same file as you, doesn’t mean you’ve both modified the exact same parts of that file. If it turns out you’ve both altered exactly the same part of the same file, you’ll need to pick and choose which changes to keep, and which to override.
The prospect of encountering messy conflicts can cause many developers to create branches with caution, or even avoid using them altogether. However, branches are one of the most powerful features that Subversion has to offer, so if you’re going to get the most out of version control, it’s essential that you get comfortable with branching and merging.
This article shares some branching and merging best practices, so you can start harnessing Subversion’s full potential without having to worry about messy merge conflicts.
Branching & Merging Best Practices
- Plan & partition – before you dive in and start working on your project, you should have a plan in place so every member of the development team not only knows what they’re working on, but is aware of what their fellow developers are doing too. This transparency reduces the chances of multiple people accidentally altering the same files, at the same time. You may also want to consider allocating tasks based on their location within the project, for example, each developer could be responsible for fixing all the bugs within a certain area. Partitioning can greatly reduce the chances of encountering merge conflicts, by giving everyone completely different files to work on.
- Perform an ‘SVN Update’ before starting work...... when you run the ‘SVN Update’ command, Subversion applies any changes it finds in the repository, to your working copy. You should get into the habit of performing an ‘SVN Update’ as the last thing you do before making changes to your working copy. Even if you recently performed an ‘SVN Update’ (or even performed a fresh checkout), you should still run a final ‘SVN Update,’ just so you’re sure no one has committed any changes in the meantime.
Even if you’re working solo, it may still be worth running a quick ‘SVN Update,’ especially if you’re working on multiple projects simultaneously, have several working copies knocking around on your computer, or have a tendency to get files and folders muddled up. ‘SVN Update’ guarantees that the working copy you’re looking at is truly the most recent version in the repository.
- ...and continue performing ‘SVN Updates' – while you’re working on your branch, you should perform regular ‘SVN Updates’ so any changes committed to the repository, get replicated in your branch. This is an easy way to check that the most recent version of the project in the repository (also known as the ‘HEAD’ revision) fits with your branch. Even if you’re convinced the work you’re doing is completely separate from what’s going on in the trunk, you should still perform regular ‘SVN Updates,’ just to ensure the trunk hasn’t taken an unexpected turn that renders it incompatible with your branch.
- Merge soon... it’s only human nature to want to delay unpleasant tasks, but when it comes to merging, the reality is that the longer you’re working on a branch, the more opportunity the trunk has to become incompatible with your changes. As soon as it makes sense to merge, don’t procrastinate - take a deep breath and perform that merge! Also remember that it’s easy to create branches in Subversion, so even if you have a list of tasks you still need to complete today, that’s no excuse for delaying a merge. Work on the branch to the point where your changes are stable, compilable, and make sense on their own, and then perform your merge. After that, you’re free to create another branch, and move onto the next item on your ‘To Do’ list.
- ...but plan your merges carefully - while you should merge as soon as possible, don’t get carried away. Only merge when your branch is stable and compilable, and the work it contains makes sense on its own - you should never merge half-completed changes!
- Consider tagging before merging. A tag is a snapshot of your project as it exists at a particular point in time. Although Subversion remembers every version of your project that gets committed to the repository, you also have the option of tagging revisions with a more descriptive, human-readable name (such as “Release 2.4” or “27thMarch_PreMerge”). Tagging a revision means that, if you ever need to recover this revision at a later date, it’s much easier to locate. When you’re about to perform a merge, you may want to tag the branch and/or the trunk, so if you’re unhappy with the results of the merge at a later date, you can quickly and easily locate the version of your project as it existed prior to the merge.
- Delete unwanted branches – to avoid clutter and potential confusion, you should delete a branch as soon as it’s no longer needed. The current version of your project should contain only branches that are currently active, to safeguard against other members of the development team spotting your redundant branch, assuming it’s active, and adjusting their development efforts to incorporate the work they (wrongly) assume is ongoing. As a general rule, you’ll tend to delete a branch following a successful merge.
- Struggling with a merge conflict? Start over - when performing a merge, the worst case scenario is encountering a complicated merge conflict, that’ll take considerable time and effort to sort out. If you do encounter this worst case scenario, it’s worth considering whether it might be quicker to grab a fresh copy of the project’s HEAD revision, re-apply your changes, and then merge this into the trunk. If you do decide to apply your changes to a fresh copy, rather than tackling the merge conflict, you can replace your working copy with the most up to date version in the repository, by performing an ‘SVN Revert.’