Maintaining branches with SVN

Like many other SCM systems, SVN has the notion of working with separate branches of the same project, meaning that different lines of development are isolated in different parts of the repository, but that it is possible to work with sets of changes, including comparing whole branches and copying changes between branches.

Typically, the 'main' line of development in a project using SVN is called the trunk, but this is not a technical requirement, it is a convention.

Unlike CVS (which supports tags/versions and branches as a direct mechanism) the support for branches and tags are a "by-product" of the SVN repository model, where copying is cheap and where the addressing of specific resources is simplified. The usual SVN repository setup groups the repository into three areas:
  • trunk - the main line of development, the leading edge, where developers usually commit their regular changes.
  • tags - a collection of snapshots of the trunk (or a branch) at a user-defined point in time, for instance release day.
  • branches - active variations of the project compared to the trunk (or even another branch). This is useful when working out a (big) change that needs to be coordinated in a team or when using a single working-copy for the work with the changeproject is not feasible.
While this convention roughly matches the equivalent CVS constructs used for tagging (versioning) and branching, the interpretation is entirely up to you (and your team), and the process of defining and setting up your repository should take this into account.

Assuming that you've set up your repository in the conventional manner, it's easier to discuss tagging, branching and merging.

Tagging

Assuming that most of the work in a project is done in the 'trunk' of the repository, you may want to "save the state" of the repository, for instance whenever you release a version of the ensuing product or otherwise reach a milestone. Obviously, you could just write down which revision number was the current one and then you could always use that information to restore the contents of the project, use it for comparison, etc. However, you can also give the tag an explicit name so that it is easier to refer to.

To compare: In the SVN command line, this is done simply by copying the repository location (like http://svn-server/bigproj/trunk/) to a new, different location (like http://svn-server/bigproj/tags/client-release-0.99/) using svn cp.

Using the Eclipse plug-in, you have this functionaliy available in Branch/Tag... found in the Team menu.

By convention, you never commit anything to a tag repository locations, they merely exist to pinpoint a specific repository revision. That being said, there is nothing which stops you from commiting to a tag (although the Create Branch/Tag dialog will warn you if the URL contains "tags"). Tags are just a convention in SVN. If you need to make a copy and work in a different direction, use a branch.

That being said, the fact that you can commit to a tag folder also has some advantages, as you may have some files that contain version numbers and/or release dates that you would prefer to only update in the tag.

Branching

Creating a branch is the same as creating a tag, a basic repository copy. If you need to work on the branch directly afterwards, using the same working copy (i.e. your Eclipse project), use the 'Team > Switch' command to switch to the new location.

If you are working with a number of changes that you wish to put into a branch in one operation, be sure to clear the "create a copy on the server" check box (as explained in the command's documentation: Your local modifications will then be applied to the base revision your are copying.

Choosing to work with a branch or tag

Creating a branch or a tag does not change your working copy. Instead, you need to switch to the newly created repostory location (or a sublocation thereof).

Note: You do not need to switch an entire project, you can indeed switch at an arbitrary folder level or even an individual file, but it might make it harder to analyze outgoing changes before a commit.

Merging changes

If working on a branch requires the branch maintainer(s) to keep up with the changes being done in the trunk, these changes can be merged into the branch. This is done using 'Team > Merge', which can be used to apply the the differences between the trunk at two different revisions.

Example: Alice is working on project 'X' with two other team members, Bob and Charlie. Alice needs to do a major overhaul of the user interface, so she creates a branch called 'gui_changes' from the trunk. This is committed at revision 8. Now Alice can switch to this location and work as she wishes, being sandboxed off the main trunk, and soon after, she has committed some changes to her branch. Meanwhile, Bob and Charlie have been working on the the trunk, bringing the revision of the entire repository up to 12 (keep in mind, this revision counter is global).

To keep up with the team, Alice needs to add the changes made in the trunk to her branch. This is done by selecting the project, choosing 'Team > Merge...' from the Team context menu, and entering the proper URL for the project she wishes to switch to. If the dialog shows http://svn-server/sw-dev/branches/gui_changes/project-x/, she would have to edit that to http://svn-server/sw-dev/trunk/project-x/, enter '9' as the "from" revision, and enter '12' (or HEAD) as the "to" revision, and merge away. This brings her working copy up to date with the changes done in the trunk, which she can commit to her branch (unless there are any conflicts, which would have to be addressed first)

Note: It is a good idea to only merge changes using a 'clean' working copy (i.e. one without changes), since you may then commit the differences (and JUST the differences), documenting which revisions they were. Some SCM systems can track this automatically (working with "changesets") but not Subversion (although the feature is slated for a later release).

Applying changes from a branch

To apply changes from a branch back to trunk or vice versa, see the Merge documentation.

Backporting

Some branches are just for maintenance or release preparation and cleanup. However, sometimes a change commited to a branch can be useful to put back into the trunk. This process is called 'backporting', and is also done using merge, just with the roles reversed, applying changes between two specific branch revisions into the trunk.