Tuesday, October 31, 2006

Different types of branching in version control systems

There are many different ways to use branches in software development. In fact, there are enough to fill a small book devoted to the subject. Don't worry about all of that. There are two branch types which solve most development problems:

  • Fixes Branch: while feature work continues on the trunk, a fixes branch is created to hold the fixes to the latest shipped version of the software. This allows you to fix problems without having to wait for the latest crop of features to be finished and stabilized.
  • Feature Branch: if a particular feature is disruptive enough or speculative enough that you don't want the entire development team to have to suffer through its early stages, you can create a branch on which to do the work.

These two types of branches have different use patterns involving branch point, merge policy, and lifetime. We'll examine them each in turn.

Fixes branches

A fixes branch (or maintenance branch) is used to apply bug fixes to a shipped version of the code. It lets you release follow-on versions of the software with bug fixes without having to incur the risk of shipping partially finished features.

Branching: the branch is created from the revision that actually shipped. This guarantees that no extra changes have accidentally slipped into your maintenance release. Use the -r argument to the svn copy command to ensure that you have the proper starting point. The branch should be named with the version number or revision number it branched from: fixes_v2_1, or fixes1234, for example.

Changes: For the most part, fixes are made on the trunk, then merged to the branch. This is because most fixes are appropriate to the trunk, and are chosen for inclusion in the maintenance release. Occaisionally, you may have to fix a bug in a maintenance release in a way that differs from how you would fix it on the trunk, because of changes in the trunk since you shipped. In that case, make the change directly on the fixes branch.

Merging: Only merge from the trunk to the branch. This is one of the reasons to make fixes on the trunk first. By keeping all the merging in only one direction (trunk to branch), you simplify the process and reduce the possibility of conflicts.

Merges will be done only for specific changesets, those with the bug fixes that should be included in the maintenance release. The merges will therefore be sparse, picking and choosing only those changes needed. The longer the branch is active, the greater possibility that a merge will not be possible because of conflicts introduced by missing changes from the trunk.

Lifetime: The lifetime of a fixes branch depends on your release model. If you are building a web site or other software that is "shipped" to only one place, the fixes branch will be obsoleted the next time you deploy the trunk. In a more traditional model, the fixes branch will have to stick around for a long time, until you end support for that version of the product.

A popular variant of the fix branch is a release branch: as development nears the point of releasing, a branch is created for the final polishing. This is fine to do so long as it doesn't violate the trunk-majority rule. If everyone is still working on polishing, and all of that work will be merged back to the trunk, there's no point branching yet.

Feature branches

A feature branch is used by developers creating a major feature, or one which is speculative, and may not be included in the product. Using one or more feature branch allows your developers to work independently of each other while still using Subversion as a way to share their work within the feature group.

The feature branch is generally kept up to date with the trunk as work progresses. Once the feature is done, the whole branch is merged back to the trunk.

Branching: the starting point of a features branch is less sensitive than with a fixes branch. When feature work begins, branch from the head, and dive in. Give the branch a descriptive name based on the feature, for example, 3d_ui.

Changes: the changes on the feature branch are whatever work has to happen to implement the feature. Make the changes on the branch and check them in.

Merging: the bulk of the merging on the feature branch will be to bring trunk changes over to keep the feature branch current with the trunk. These merges are a periodic maintenance task on the branch, for example, done once a week or so.

Subversion doesn't record the history of merging, so to do this periodic trunk update, you have to manually note which revision you are current with. For example, when the branch is created, note the revision:

$ svn copy http://svn.myrepo.com/trunk http://svn.myrepo.com/branches/3d_ui
Committed revision 1701.

When the time comes to merge the trunk over, you merge from there, including everything from the latest trunk revision merged, to the head:

$ svn update
At revision 1812.

$ svn merge -r1701:1812 /work/trunk /work/branches/3d_ui
U    3d_ui/source/hello.py
...

$ svn ci -m "[3d_ui] Merged the trunk from 1701 to 1812."
Sending        3d_ui/source/hello.py
...
Transmitting file data ..
Committed revision 1813.

After another interval of work (week, month, whatever is appropriate to your environment), you'll have to merge again to get the recent changes to the trunk. Again, you'll specify a revision range that takes only the changes you haven't already merged:

$ svn update
At revisioun 1865.

$ svn merge -r1812:1865 /work/trunk /work/branches/3d_ui
U    3d_ui/source/util.py
...

$ svn ci -m "[3d_ui] Merged the trunk from 1812 to 1865."
Sending        3d_ui/source/util.py
...
Transmitting file data ..
Committed revision 1866.

The checkin comments are important here, because they are the simplest way to keep track of what the latest merge revision was.

Eventually, the feature is done, and needs to be merged back to the trunk. Now you will merge all of the revisions from the branch point to the head from the branch back to the trunk:

$ svn update
At revision 1911.

$ svn merge -r1701:1911 /work/branches/3d_ui /work/trunk
U    /work/trunk/source/hologram.py
U    /work/trunk/source/volume.py
...

$ svn ci -m "Merged the 3d_ui branch back to the trunk."
Sending        /work/trunk/source/hologram.py
Sending        /work/trunk/source/volume.py
...
Transmitting file data ..
Committed revision 1912.

Lifecycle: at this point, the feature branch is done. You can go back to working on the trunk, or creating a new branch for the next big thing.

Get more information

Can't find what you're looking for? Try Google Search!
Google
 
Web eshwar123.blogspot.com

Comments on "Different types of branching in version control systems"