Parallel DevelopmentThis is a featured page

Parallel Development allows teams to work on various aspects of the same product source code base. As you near the end of feature development for the current release, freeze the code, and begin more "formal" testing, you will find some developers with time on their hands. For this reason, it makes sense to apply this ever-growing group of developers to work on the next release. Therefore, we create a new branch:
  • Since we do not want to risk making changes to the "release" code we are about to deliver,
  • Since we do not want to simply have developers working in their own workspaces until the current release is made and they can start "checking in" code again, and
  • Since we want to make it easy for a developer to halt their new development and fix a bug (requiring restoring their system to match the current release code base, and reverting back again once their bug fix is approved and checked in).
Hence, we end up with a high-level view of the parallel development process as follows:
Parallel Release Branches Note, for a moment, the overlapping nature of Figure 2. Except for the fact that you are likely resource-limited, development never stops. Market research, client feedback, and planning the next version do not stop either. In addition, a release comes every X months, like clockwork. It is all very rhythmic and should have a non-chaotic flow to the process. The concept of a "code freeze" is just in terms of the code base for the current release about to be shipped (to allow stabilization of the source). The rest of the developers keep right on working on the main trunk code base. Essentially, this large "outer loop" surrounding release-style development has an overlapping region. As the code is frozen on Release N and formal testing commences, new development starts on Release N+1 by part of the staff. To keep the code safe, this is when branching is done for this style of development. This requires all folks involved with developing a release to be very aware of the rhythmic nature of this process. Marketing, product champions, field engineers, documentation, trainers, management, etc., all have to be working ahead of the team in terms of planning the next release. Depending on your overall release schedule duration, you need to be aware of potential bottlenecks with some of the non-development-related issues. For example, marketing would be hard-pressed to plan for the next release at the same time as getting the current release out the door.

Triggering a Test Cycle

If the software world were perfect, all you would need to do is to create features, have them "ensured" by automated unit and acceptance tests, do some manual testing for those areas that require a human touch, and shorten the "Formal Testing" cycle down to mere days. Obviously, this is rarely the case in complex software. But a worthy goal to strive for, nonetheless. You should attempt to shrink the amount of time devoted to testing under code freeze to as short as possible. This is largely a balancing act between improving the entire development process, improving quality of code, automating as much testing as possible, making manual testing as efficient as possible, and doing the "right amount" of testing to deliver a quality product. Over time, a team should be able to improve and reach an optimal balance. In addition, you should not turn out QA builds one after the other every time a bug is found. Every time QA gets a new build, the test cycle restarts, costing $$ and time (and good will) of all the testers. You want to strike a balance here as well.

Branching

Though there are a few different ways to control software releases, the most popular method - and the one supported by most tools - is the simple branching technique. This allows teams to undertake parallel development. That is, you can have multiple project teams working in parallel on the same (in a virtual sense) code base. Of course, "simple branching" is relative. Branching can lead to high degrees of complexity and confusion if not done properly. Branching can even come about due to different reasons:
  • Product enhancements: patches, releases, etc.
  • Platform or OS: maybe you need to support a new internationalization initiative, or a new hardware platform
  • Roles: maybe you branch for the QA team to do their thing
  • Phases: you have a promotion scheme whereby the code goes from development, to QA, to release, to maintenance
The basic problem facing development is that different developers need different bodies of the "same" code at different times for different purposes. Confused? Me too. Lets assume we have a product that looks like this:
  • WidgetFactory
    • v1.0
      • v1.1
    • v2.0
      • v2.01
      • v2.1
      • v2.5
    • v3.0
You need to be able to have developers create workspaces that reflect the proper body of code for their current tasks (be it development of features in the main trunk, bug fixing for v2.1, or exploratory development for a new architectural approach concept).

The Main Trunk

Obviously, we have to start with a hunk of source code for a given application. The code from which we continue to earn a living must carry on into the future. All releases share the main trunk. In theory, you propagate applicable bug fixes for a given release (branch) back to the main trunk to the benefit of all future releases. (Merging assumes that the bug fix still makes sense in the context of the current state of the code.) An even greater theory is that you could build the application from the main trunk and that the automated tests pass with flying colors. This is a style of development that some people prefer. That is, there is an edict that the main trunk should reflect a useful state of running software (sometimes at a given point in time: daily, every Friday, etc.). The Main Trunk represents the latest and greatest. From this trunk you create the branches - hence the tree analogy. If you branch too much, you get a shrub. Avoid shrubbery.

Release Branches

You typically create release branches to establish the code base that you will eventually deliver to the customer. When the current development branch nears Code Freeze, you create the branch so that you can control changes more closely. What underlies the desire to create a new branch is simple:
  • You do not want "harmful" changes to the code as you are squashing bugs, and readying for a stable release/shippable build.
  • You want other developers to be able to continue on the next version underway. That is, they should be able to continue to add new features, undertake major refactorings, and generally do other tasks that could be very disruptive to the code base.
At the stage where a Code Freeze has been enacted, all developers know to not "break" the build. Only bug fixes that have been approved get done (that is, they are demonstrated to truly fix the problem and not wreak havoc on other parts of the system). Developers may be limited in their capability to check-in to the code base. Maybe the chief programmer must approve the changes, after which you can check in the code. Normally, you blast out a stern email message to the team, reminding them to increase their awareness to protect the release code from instability. This means things like:
  • Only change what is minimally necessary to fix a bug.
  • Be very cautious about changes in files/methods that others have many dependencies on. If unavoidable, alert QA that more testing in the affected area(s) may be in order.
  • Though you may spot some other neighboring code that needs "improvements" while you are making a bug fix, resist the temptation to make a "little, harmless fix." (Do it in the new branch, or log it in bug/task tracker for doing in the future.)
  • The less code you touch, the less likely you will create unintended consequences.
Depending on your style of development, you may do one of the following:
  • Preferred: Main trunk is your development stream. You create a new branch N for the release. New development continues in main trunk, and you relegate critical release development to the new branch.
  • You are working in the existing release N branch. You create a Release N+1 branch. New development takes place in N+1, careful bug fixing takes place in the N branch.
With multiple branches and a trunk, you have the potential for a single file to have different revisions that have diverged in content. The section on "Merging" will address what to do.

Tags and Labels

Many times, your version control software gives you the opportunity to apply a special name or symbol to a bunch of files to represent a point in time. For example, when you have finally decided to release the software to your clients, you should label all current files in the branch to be identifiable as the files that went into this official release. This gives you the ability to reliably retrieve the precise body of source code and related files that went into a shipping/deployed version. This is especially useful when it comes time to fix a bug in this version, and deliver a new "patch" or update your delivery files. When you have files tagged/labeled/marked, you can request all files with a given tag. This is kind of like turning the repository upside down and shaking it: only those files that have the requested tag will "fall out." Newer versions of files on the trunk will not be brought forth. In CVS, for example, you can create a branch based on a given set of tagged files. For example, you can create a branch labeled "ver 1 0 patch" based on files tagged as "ver 1 0." (Note: I use labels that indicate major and minor version numbers so that it is clear what I am trying to demonstrate. However, you can use tags that are code names or numeric values as well.)

Merging

The concept of merging is to take changes in one branch, and update another branch and/or the main trunk. The easiest way to visualize this is to consider a single file in your system that goes through some changes. Suppose, for a moment, that one of your customers actually found a bug – as rare as that might seem to you. You have two choices:
  • Fix it in the current new development branch/main trunk, deliver in the next scheduled cycle.
  • Make a bug fix/patch release.
  • Ignore the bug. :0
    I know, I said two choices but gave you three. The third choice (a viable one, I might add) requires no knowledge of releases and branching, so we will stick to the first two.
Lets assume you decide to make a patch release, so you create a new branch based on the release branch. By checking out from the new "patch" branch, the developer is able to quickly get the necessary files for the release in which the offending bug exists. The developer then makes a fix to the source code, does some testing, and checks the code back into the "patch" branch. A patch build should be simple (because you also tagged all supporting files; e.g., build scripts, installer scripts, documentation, tests). You then might go through a full or abbreviated QA cycle to test the change(s). Merging Changes Across Branches:
Merge Across Branches Note how the Figure also shows changes made in the branches being merged back into the main trunk. Of course, this may or may not be done. Some times, a fix in an older version of the file may be unnecessary due to subsequent changes made to the file or the program architecture.


JonKern
JonKern
Latest page update: made by JonKern , Mar 10 2009, 10:42 AM EDT (about this update About This Update JonKern Edited by JonKern

1956 words added
4 images added

view changes

- complete history)
Keyword tags: agile process
More Info: links to this page
There are no threads for this page.  Be the first to start a new thread.

Related Content

  (what's this?Related ContentThanks to keyword tags, links to related pages and threads are added to the bottom of your pages. Up to 15 links are shown, determined by matching tags and by how recently the content was updated; keeping the most current at the top. Share your feedback on Wetpaint Central.)