What words come to mind when you mention “parallel development” to software developers and projects managers? Complex and painful may be the typical response. Yet parallel development need not be difficult and laborious. By adopting an appropriate branching and merging strategy, parallel development can be straightforward and efficient.
The stable receiving-line, identified in Streamed Lines: Branching Patterns for Parallel Software Development, is a branching and merging strategy that is ideally suited for projects that need to support two or more releases at the same time. The primary benefit of the stable receiving line is that it isolates the development activities for each release while providing a home codeline that is always stable.
This experience report describes how to support parallel development using the stable receiving-line. The approach described below is based on an implementation of the stable receiving-line using StarTeam. The approach follows an early branching style that uses project-oriented branching.
Why Parallel Development?
Parallel development results from crafting a software application over a series of releases. Today, release-based development is common for all software applications, including commercial software products, custom software applications, and web sites.
The most common reason for parallel development is the need to maintain one release of the software application while developing another. When bugs are identified in the release that shipped (or is in production), they often need to be corrected before the next release is ready. The fixes need to be made to the versions of the source code files that were included in the shipped release, not to the versions of the source code files that contain work in progress for the next release. Parallel development isolates the two releases so that the production fixes can be made to the shipped release without introducing code under development for the next release.
Another motivation for parallel development is the need to create two (or more) releases at the same time. If releases are short and frequent, such as for a web application, it is not uncommon for development of a future release to start before development completes on the next release. There are also circumstances when the lead time required to develop a new feature is longer than the typical release. Using parallel development, coding the feature for a future release can begin while development is underway for the upcoming release.
Codelines and the Mainline
A codeline is the term that describes the progression of the versions of source code files that comprise a software application. Typically, a codeline is depicted as a horizontal line with the most recent versions of the files at the right end of the line. The codeline is called a mainline when it is used as the home codeline from one release to the next.
At the start of parallel development, a branch is created from a point along the mainline. The branch forks development into two codelines. Two common types of branches are the release line and the task branch.
In Chapter 17 of Software Configuration Management Patterns, Steve Berczuk and Brad Appleton describe the release line as a way to keep the released version of files stable and isolated from the current development activities. The release line, which is created at the time a release ships, is used to support maintenance of the release.
Fixes to the versions of files included in the shipped release are made in the release line. Eventually, these fixes are merged from the release line to the mainline so that they will be included in the next release.
The release line exists from the time the current release ships until the time when the current release is no longer supported. The release line follows a late branching style because it is created at the time of a codeline conflict. Specifically, the branch is created when required maintenance on the shipped release would conflict with new development in the mainline for the next release.
In Chapter 18 of Software Configuration Management Patterns, Steve Berczuk and Brad Appleton describe the task branch as a way to isolate a long-lived development task from a current development task. Like the release line, the task branch is branched from the mainline. However, the purpose of the task branch is different from that of the release line. The task branch provides the isolation necessary to work on a task that would be potentially disruptive if it occurred in the mainline.
The task branch exists from the time work begins on the task until the task is completed. Changes made in the task branch may be merged to the mainline as work on the task progresses. Alternatively, the changes may not be merged until the task is completed. The length of the task and the stability of the code in the task branch dictate when it is appropriate to merge the changes to the mainline.
Like the release line, the task branch follows a late branching style because it is created at the time of a codeline conflict. In particular, the branch is created when a new task would conflict with development in the mainline.
The Stable Receiving-Line
The stable receiving-line is an alternative to using a release line with a mainline. The stable receiving-line is a mainline, i.e., it is a home codeline. However, the stable receiving-line is a home codeline in which no development takes place. Instead, the stable receiving-line exists solely to collect the changes that are made in a release codeline. A release codeline differs from the release line because the release codeline follows an early branching model. An early branching model means the release codeline is created before any codeline conflicts exists.
When using the stable receiving-line, a release codeline is branched from the mainline at the start of a new release. Development of the entire release takes place in the release codeline. Only stable changes are merged from the release codeline to the mainline. This means every point along the stable receiving-line corresponds to a snapshot from the release codeline that compiles and passes regression tests.
Implementing the Stable Receiving-Line
The stable receiving-line can be implemented using a software configuration management (SCM) tool that supports branching and merging of codelines. Ideally, the SCM tool supports project-oriented branching, meaning branching is viewed from the perspective of all the files that comprise a project or codeline.
When implementing the stable receiving-line in an SCM tool that supports project-oriented branching, the mainline can be the trunk of the SCM tool’s version tree. Each release codeline can be implemented by branching off the trunk. Changes made in a release codeline can be merged back to the trunk at stable points in the development of the release.
Over the last year, I implemented the stable receiving-line for a software project that needed to support parallel development. The project was using StarTeam, a popular SCM tool from Borland® that integrates version control with change management. Features of StarTeam make it relatively easy to implement the stable receiving-line. Before describing these features, it is important to understand the high-level architecture of StarTeam.
StarTeam is a process-enabled SCM tool that stores source code files and process items in a single server configuration. The StarTeam server is organized into projects. A project consists of one or more views. Each view is a container for source code files and process items. A view is the construct used by StarTeam to implement a codeline and to support project-oriented branching. The initial view in a project is called the root view. The root view contains the trunk of the version tree.
To implement the stable-receiving line in StarTeam, I used the root view as the mainline. I used a view branched from the root view as the codeline for first release. I used another view branched from the root view as the codeline for the second release. Eventually, the project contained three views: the root view and two release views. The hierarchy of these views in the view tree is depicted in the figure below.
Developing Using the Stable Receiving-Line
When using the stable receiving-line to support parallel development, development for each release takes place in a separate codeline, or StarTeam view. Eventually the changes made in one release view need to be merged to both the stable receiving-line (i.e., the root view) and to the next release view. The changes are merged to the stable receiving-line so that it is kept current with the latest stable code. The changes are merged to the next release view so that they are included in the next release under development.
The figure below depicts the stable receiving-line and two release views. The arrows in the figure illustrate how changes are propagated.
The top line depicts the progression of the mainline, i.e., the stable receiving-line, over time. Each circle represents the point in time. A new release view was created at some of the points along the mainline. While changes from a release view were merged to the mainline at other points in time.
The second line depicts the progression of the first release view over time. Each circle represents a stable build. When a stable build is completed in the first release, the files included in that build are merged to the mainline. The files are also merged to the view that contains the code for the next release.
The third line depicts the progression of the second release view over time. At the time the second release view was created it contained the file revisions from a stable build in the first release.
Merging Using the Stable Receiving-Line
When employing the stable receiving-line, I merged using a restricted approach at the codeline level. By restricted approach, I mean the merging process was initiated by only a few experienced members of the project team. By codeline level, I mean all the files in the codeline merged at the same time.
Since the objective of the stable receiving-line is to keep the mainline stable, I only merged when a release codeline was stable. Ideally, the release codeline was stable, and ready to be merged, after a successful build and regression test.
StarTeam supported merges at the codeline level using a labeled configuration. I created a labeled configuration by attaching a view label to the revision of each file (in the view) that was included in a build.
When merging from one release codeline to another, I followed a style known as integrator-pull. As an integrator, I was pulling the non-conflicting changes from a labeled configuration in one view to another view. When conflicts arose, meaning the same file was modified by two developers in two views, I relied on developers familiar with the changes to act as the integrator. The developer who made the change in the upstream release view used a three-way merge tool to create a merged file and pull it into the downstream release view.
I chose the integrator-pull approach over the developer-push approach so that I could ensure that all files in the labeled configuration merged at the same time. While the downstream release view was destabilized during the merge, all the changes from the upstream release view were merged once the merge conflicts were resolved in the downstream view.
The stable receiving-line is branching strategy that is effective for parallel development. This strategy is conceptually clear and straightforward to implement using an SCM tool that supports project-oriented branching. StarTeam is a process-enabled SCM tool that is well suited for implementing the stable-receiving line to support parallel development. Views in StarTeam contain codelines and facilitate the project-oriented branching that is needed to implement the stable receiving-line.
 For more information about the features and capabilities of a process enabled SCM tool, see Using Process-Enabled SCM Tools to Facilitate the Software Development Lifecycle.