ClearCase Extension Pack

Fundamentals

What is a Change

This page explains how many developers can introduce changes into the source code with minimal interferance and the best possible quality assurance. It covers the following:

The system revolves around one fundamental concept: The Change. A change is the set of modifications required to implement a particular feature or requirement. A change should be atomic in the sense that a further subdivision of a change into multiple steps would not lead to a working product in between those steps, whereas the product should be fully functional after all the steps making up the change have been completed.

Usually, a change is simply an item in your work schedule.

The developer disposes of four basic operations to implement a change:

File Checkout
Prerequisite to modifying a file.
File Checkin
Prerequisite for the next two operations.
Putback
Make your modifications available to other changes being developed.
Bringover
Transfer modifications from other changes to your change.

Note that contrary to CVS, checking in a file has absolutely no effect on other developers. Checking in a file just creates a checkpoint and an opportunity to describe your change. Checking in a file also ensures that any changes are backed up. A checkin is really nothing more than a fancy way of saving a file, and it is probably a good habit to check in a file every time after you saved it from your editor.

Making a change

The basic change model used in the ClearCase Extension Pack is serialized atomic changes. The following diagram illustrates the process:

Simple Parallel Development
  1. We start with our so-called delivery stream. The code stored there is in a stable state, as defined by local policy. Such a policy may be: "it builds and it passes automated unit tests". Depending on your situation, your policy may be looser or tighter than that.
  2. A developer starts on a change. Since this change will most likely destabilize the code, it will not be done on the delivery stream, but on a development stream which branches off at the point where work starts.
  3. Some other developer delivers a change. This delivery is done with the understanding that the result is again a stable state, as defined by local policy.
  4. The initial change is now done, and the developer wants to deliver it. The problem is that since some other developer delivered a change, one cannot simply clobber it or ignore it by delivering the new change on top of it. First, a merge out (bringover) needs to be performed. There may be conflicting changes, and these must be resolved.
  5. Once all the merges are resolved, and nobody else sneaked in another delivery, the initial change can be delivered or put back.
  6. The delivery stream now contains both changes and remained in the stable state, as defined by local policy. Note that all the destabilizing work was done in side streams, and that at no point any ambigouity or uncertainty about the state of the delivery stream ever existed.

Developers should strive to keep up with other developer's work. A bringover should be performed whenever another developer does a putback, otherwise the content in the developer's workspace will start diverging. The longer you put off merges, the harder they will become.

Release management should schedule changes and putbacks in a way to minimize impact for other changes in progress. Sometimes, it is recommended to delay new changes until a particularly hairy change has been putback, as "merge hell" may result otherwise.

Propagating changes

Every once in a while, usually about a month prior to a planned release, a new delivery stream will be branched off. The main purpose is to protect a particularly stable version of the source tree from bleeding edge changes that might create problems. To decrease the probability of the new delivery branch containing too many untested changes, a higher standard for doing putbacks will be put in place for the new delivery branch.

For historic reasons, this is often refered to as a code freeze. Once the delivery branch is created, bleeding edge development may continue unabated in the main stream.

Changes done to a delivery branch will usually be bug fixes. Very rarely will they involve major changes. Most of these changes are desirable in the main branch too, so to save developers the effort having to make the same change twice, changes can be propagated forward, as explained in this diagram:

Propagation of changes
  1. The release stream is branched off the main stream when it becomes apparent that you need to separate long-term work from work purely focussed on stabilizing the next release.
  2. The release stream accumulates bug fixes and tightly controlled changes
  3. The main stream continues to allow larger, more risky changes
  4. Both streams use the same change process, just with a different delivery target. Eventually, the product is actually released, and patches for the release are added later.
  5. The main stream forks off the next release stream.
  6. The patch for the previous release is pulled in, either via a redo or via a ct-bringover -from. Note that the same change process is used - we are just using a more fancy method for changing the files.
  7. Finally, the patch is propagated to the main stream.
  8. Now the main stream contains all the recent changes and the patch, which only needed to be developed once. The propagation can be automated if required.