Common ClearCase Practices

Best Practices, Traps, and Pitfalls

by Brad Appleton


Introduction

This page attempts to catalog common practices with the ClearCase software configuration management tool. At present, no attempt is made to distinguish which practices are "good"and which ones aren't. At a later date, I hope to be able to sort the common usage patterns listed here into "best practices"and "traps and pitfalls."

I hope to determine this by having people from various development shops answer the following questions for each practice that they actually use:

Currently, the practices are partitioned into the following areas (with some overlap):


Branches

Early Branching

Early Branching is when codelines for new development or integration are created right away, as soon as any work on the corresponding project or release begins. This is often used when the mainline is a "Stable Receiving Line" reserved only for merges of baselines. New codelines are spawned off the mainline as soon as the corresponding work begins.

For example, if work on release 1.0 has completed and work on 1.1 is taking place, and at the same time, work on release 2.0 is about to start, then a new codeline is branched off mainline for work on release 2.0 at that point (and if it isn't already, work on release 1.1 and other version 1 maintenance releases) goes on its own branch.

Thus Early Branching merges into mainline with the old baseline, and then branches out from mainline for the new development/release.

Deferred Branching

In contrast to "Early Branching", Deferred Branching (also called Lazy Branching) is when branch creation for new development/integration codelines is put off until the last minute. This is often used when the mainline is a "Latest and Greatest Development Line" (or "LAG Line"). The latest and greatest development work takes place on the mainline, or the main development line (which might not be /main), and codelines are branched off only when the corresponding work is no longer the latest and greatest.

For example, when working on release 1.0, development happens on the mainline. Work on 1.1 and 1.2 (and 1.x) also happens on the mainline until work on the next release (2.0) starts to take place in parallel. At that point, development for release 2.0 takes over the mainline, and then a separate branch is created for maintenance work on release 1.x.

Thus, instead of branching for a new release-line as soon as work begins on the release, we wait to branch it off mainline, until it goes into maintenance mode or until development on a subsequent release begins in parallel from existing work. At which time its out with the old (it gets a new codeline branched out from main) and in with the new (the new development work comes in on the mainline).

The reasoning here is that by branching later rather than earlier, there is a single codeline for a longer period of time and changes simply get merged into the single codeline instead of having to get merged into two parallel codelines. Once the second codeline is split off from the first (regardless of early or late creation), then changes made in the newly branched codeline often need to be propagated back to the parent codeline somehow (either my merging the changes themselves, or by merging the codeline to its parent to "synch-up"). This is a trade-off of safety in favor of liveness (productivity): by waiting longer before splitting off a new codeline, the amount of propagation and synch-ing effort is reduced, at the risk of having less separation/isolation of change.

Directory Branching

Some shops avoid branching directories in ClearCase because when directories are created on a branch, or their contents are altered on a branch (a file is added or removed to its list of elements), they sometimes run into problems with visibility of elements, often resulting in the same element being created twice on different branches.

Other shops use branches for directories in the same way they would for any other elements. And if they have a reasonably organized and disciplined and consistent use of branching, and are sure to integrate early and often, they tend not to suffer too much from the aforementioned problems.

Branch Naming Conventions

Many groups use specific naming conventions for the various kinds of branches that are created. There will typically be some portion of the name that indicates the type of branch (release-line, component-line, integration-line, fix/feature). If the branch corresponds to a major or minor release, then the release number is usually included. If it corresponds to a record in a tracking database, the database-ID of the record is often part of the branch name as well. Some may also employ the primary developer's username as part of the branch-name.

Branch Type Prefix

Use of a prefix to indicate the type/purpose of a branch (e.g., "rel", "int", "fix", "feat", "dev", "tst", "comp", "prod", "proj", etc.)

Release ID in Branch Name

Use of the major and/or minor release version in a branch name (e.g., "rel1", "rel1.2", "rel2.X").

Request ID in Branch Name

Use of change requests tracking systems corresponding request ID as all or part of the branch name (e.g., "cr123", "bug243", "feat331").

User ID in Branch Name

Use of sole or primary developer's username as all or part of the branch name (e.g., "calvin", "hobbes_bug243", "suzy_feat331").

Component ID in Branch Name

Use of a component-name or subsystem-name as all or part of the branch name (e.g., "GUI_rel2.6", "MMI", "ACG-1234").

Task purpose in Branch Name

Use of an indentifier corresponding to the purpose of the task as all or part of the branch name (e.g., "flush_on_write", "fix1234_confirm-exit").


Task Branches

A Task Branch is a branch that is used only for development of a single task. When the task is completed and the changes have been tested in isolation, then the change-task branch is merged into the integration branch (usually its parent). After the change-task is completed or integrated, its not uncommon for it to be "locked down" (retired) from any future changes.

If all change-tasks must be performed on their own task-branch, this is called the Branch per Task approach. Some groups instead prefer to use a Branch per Major Task creating task branches only for more involved (higher risk or longer-lived) efforts, and performing short and (seemingly) simple tasks "on-line" (directly on the codeline instead of on a separate task-branch).

Fix Branch

A Fix Branch is a task branch created for the purpose of fixing a "bug" in the software.

Branch per Request

This is basically the same thing as "Branch per Task". The main difference is that in this case, branches are only created for formal requests logged in a bugtracking and/or change-request tracking database, and other untracked change-tasks might or might not have their own task-branch.

Feature Branch

One of the more common uses of codelines is to house development work for a specific major or minor release (minor releases are sometimes called "point releases" because they only affect the number after the first "point" in the version name/number). Some groups also use branches to shore up work in major or minor system features, (possibly independent of which release-line they may end up getting merged to).

It's common for a group to use task-branches for enhancements and bugfixes that stem from change-requests and/or bug-reports. Its less common to see this same philosphy applied to initial feature development as well (before an initial baseline is created), or before a codeline goes from pure development mode maintenance (and development) mode.

With feature branches, "feature" tasks are created in the tracking system that correspond to new development features to implement in the next or current release. Some of these features may encompass more than a single discrete development task, but often they will correspond to a single task. (In the case of the former, the feature branch may turn out to be a special kind of subproject line called a "feature line" - feature lines typically are smaller units of functionality than "functional lines").

Private Task-Branches

A "private" task branch is a task-branch that is specifically locked right after creation so that only the assigned individual developer make checkout/checkin any versions on the branch. Sometimes groups simply use "private branches" by explicit convention, but don't actually enforce them using ClearCase locks or triggers.

Shared Task-Branches

A "shared" task branch is a task-branch that is deliberately planned and used for development by two or more people on the same branch and task. This may take place in separate views for each developer, or the developers might use a shared view (to conserve diskspace and network reources) if they can obey conventions to prevent each other from modifying the same sets of files (or at least at the same time).

Task-Migration Branch (a.k.a. Transfer-Branch, Carry-over branch)

A Task-Migration branch (or Carry-over branch) is a change-task branch that is created to propagate a change task from one "mainline" to another "mainline." When a group is using multiple mainlines which are long-lived (sometimes each mainline is a different functional-variant line) then change-tasks made in one mainline often need to be propagated to one or more other mainlines. Since the context in which the original change-task occurred may include things that were specific to its particular variant or configuration, a separate migration branch is created for each mainline to receive the propagated change. This keeps the changes isolated on a separate branch of the new mainline so they can be merged, integrated, and stabilized, before adversely impacting other users of the mainline.

Its not uncommon for task-migration branches to require a partial ordering in their integration to a given mainline. Tasks from the same mainline usually need to be propagated to other mainlines in the same order they were completed in their initial mainline (unless the tasks are completely independent and don't share any common context besides a common baseline).

Codeline-Owner as Integrator

The Codeline-Owner serves as the integrator and is responsible for merges all Task-Branches into the codeline. When development is completed on a task-branch, it has to get merged to the integration codeline. Sometimes this is done at periodic intervals by a special "codeline integrator" who is responsible for performing all integrations into their codeline and maintaining a consistent state.

If done right, it works swell. If done wrong, it can result in a "throw it over the integration wall" scenario where there is very little and/or infrequent communication or cooperation between developers and integrators and working relations between them can become very strained and unproductive. It also makes it harder for each group to appreciate the work and needs of the other and they will frequently resist changes to their own work-habits for the benefit of the other group if they can't perceive any benefit to their own group.

Merge Your Own Code/Change

This is when developers are responsible for merging their own change-tasks back into the codeline. It is usually done as soon as the individual task is completed (including after code-review and unit-test).

If done right and with discipline, this too can work out just great. If done wrong, you can have haphazard changes integrated at irregular times, and consistency and stability of the codeline can be next to impossible to rely upon. Regardless of whether developers or separate integrators merge changes to the codeline, there needs to be a responsible "codeline owner" who takes to heart the duty of ensuring that changes are merged in an organized manner and frequency, and that the codeline is as consistent and stable as possible at all times.

Sync Before Merging (sync before export, pre-merging)

Some shops encourage or require developers to merge the latest state of the codeline into their task branch and view before allowing the change to be integrated to the codeline. This ensures that the merge to the codeline will always be a trivial one (provided its performed very shortly thereafter or else in a controlled order) regardless of whether the merge to the codeline is performed by the developer or an integrator.

The downside of this is decreased separability of the change-task from its initial baseline/context. If any merges were made to files on the task-branch, then the branch now contains (and may depend upon) more changes than just the task plus the baseline it was first branched off from. Backing out such changes can be harder to locate or disentangle unless other measures are taken (like checkpointing the versions on the branch before syncing-up with the codeline). The likelihood of merge problems to be handled by an integrator is often decreased because changes are merged by the developers who made them, and codeline integration is usually trivial. But when a problem does occur, its likely to be more of a hassle to resolve.

The main issue has to do with whether the particular environment makes developers more or less likely to be as familiar with the latest state of the codeline as they are with their own changes. If they are, then the developer is typically best suited to do the merging; otherwise the codeline-owner is usually the better choice (and sometimes you need both :-)


Integration Branches

An Integration Line is a branch that is used primarily, or even exclusively for performing integrations of incoming changes. Some like to make the distinction between an "integration line" versus an "integration "branch" (or "integration-task branch"). They use the term Integration Line to refer to a codeline that is created in advance, ahead of many of the changes that will be integrated. When a change is made on its own task-branch, after the change is debugged and tested, it then gets merged into the already created integration line. So the integration-line lives on after the merged task-branch is completed and remains active to in order to merge many other task-branches as they start and finish during the lifetime of the integration-line.

Integration-Task Branch

In contrast to an Integration Line, an Integration-Task Branch typically doesn't get created until after most of the development changes to integrate have already begun, and often isn't created until most of the development changes are ready to be merged. The "integration-task branch" is then created (and sometimes the codeline is frozen from further development changes until the integration is completed). The integrator then merges in each of the ready-to-be-merged development changes in rapid succession (hopefully in some intelligent order based on change-dependencies). So the lifetime of an integration-task branch usually doesnt span over multiple task-branches; it typically doesnt start until most of the task-branches are well underway and ready for integration.

On-line Development (development allowed on integration line)

Some groups allow developers to checkout/checkin on the integration line. It may be that all development happens on the integration line until an initial baseline is created and/or the codeline goes into "maintenance mode." Or else developers perform minor change-tasks "online" using task-branches only for what they consider "major" changes.

Off-line Development (development only on task-branches)

Some groups forbid development tasks on the integration-line, reserving it only for integration of task-branches (which might be performed by an integrator, or by the developer).

Platform Lines (branching for platform variants)

This is a codeline created to house platform-specific work of the system. It might be for a different operating system, or different hardware, or a different windowing environment. But code specific to the particular operating environment has its own platform-speficic integration line.

The more commonly recommended way to handle this is to use platform specific subdirectories and files. Rather than use a sea of #ifdefs to create conditionally compiled spaghetti code, platform-specific code is split out into separate compilation units in a subdirectory named after that platform (or the platform might be a prefix in the filenames). Then a variable can be used in the Makefile(s) to select the specific platform files and directories.

Platform-directories are usually preferred over platform-branches, but occasionally one runs into cases where platform-branches really do seem to make sense.

Feature-Set Lines (Functional Lines)

If the product being constructed has several different functional variants that need to be built, then either each functional variant is given its own codeline; or else each major function that may be varied is given its own codeline and then the versions from the appropriate mix of functional lines is configured to form the desired functional variant of the product.

Component Lines

Sometimes the system is partitioned up into an explicit list of component or subsystems. And a separate team is often assigned to work on each component. It's not uncommon for each component team to create its own component development barnch as the main integration branch for the component, and then development for the component takes place on the component line, or else on one of its sub-branches and is eventually integrated to the component line.

Baselined versions of each of the various components are usually integrated together to configure a complete system build. Sometimes this is done by having each component line merge its latest state into a system-wide integration line, sometimes it's done simply by integrating in the LATEST versions on each components, and sometimes its done simply by selecting the appropriate baseline label for each component in the config-spec (there is rarely ever any overlap between the sets of files making up a given component).

The difference between a "component line" and a "functional line" is that a functional line is for a variant piece of functionality that is not always part of every released configuration. Whereas a "component" line is reserved for work on a particular subsystem regardless of whether or not it is always released with every configuration.

Subproject Lines

A project line may be thought of as virtually any branch or codeline created for one or more related tasks with a common goal. A release-line (the main development or integration line for a specific release) can be thought as a project line whose goal is to deliver a particular release.

It is extremely common for groups to have a main integration line for their work on a particular release (or project), and for all other work to take place other directly on the release-line, or else on a single branch off the release-line for a single task (a bugfix or enhancement) which then gets merged into the main integration line upon completion.

A Subproject Line is a codeline branched off the main integration line that is used for work which spans more than one development task (and hence more than one "task-branch"). Sometimes two or three people work on interdependent tasks on their own separate branches. Rather than each referring directly to the others branch in their configurations, the create a common subproject integration line for their work, and refer to the subproject line instead of someone else's task branch. When someone needs the latest state of someone else's branch, they ask that person to merge to the subproject branch. When all the interdependent tasks are finished and integrated to the subproject branch, then the subproject branch is ready to be merged back to the main integration line.

So a common indicator of a subproject line is when branches are more than one level deep off the main integration line for the release or project codeline. It helps avoid the scenario of "spaghetti branching" where individual task branches explicitly depend on other task branches in a haphazard fashion, much like the haphazard use of unstructured gotos in a program leads to spaghetti code.

Third-Party Line (Vendor Line, Vendor Branch)

When source-code (or other kinds of files) are supplied by some external third-party vendor or supplier and require local modifications they need to be version controlled. The problem is that this needs to be done in a way that minimizes integration effort when obtaining a new release of files from the supplier while accommodating local changes that had to be made.

The common approach to this problem is to use a Third-Party Line or Vendor Branch. Rather than trying to maintain both the vendor-supplied versions and the locally modified versions on the same codeline, a separate codeline is used to hold only the vendor supplied releases of the files. The first time the files are received, the vendor line is created separate from the local development branch (which one branches off of which isn't a big deal, it can happen either way). Then local changes are made on the local development line. When a new release is received, it is checked-in to the vendor-line, and then merged (integrated) into the local development line.

Staged Integration Lines (Promotion Branches)

Sometimes various "promotion levels" are defined along with the linear progression from one promotion level to the next. The criteria used to decide what constitutes a "promotion level" and when to promote something to the next level may vary widely depending on how the group chooses to define them. These promotion levels may correspond to levels of testing or SQA (e.g., inspected, unit-tested, intg-tested, sys-tested, ...), or to levels of scope/scale (unit, component, subsystem, system, ...), or to levels of authority/responsibility.

One way of using promotion levels is to use a separate integration line per promotion level for each release or each mainline. When a version is merged from one promotion branch to its successor, it has been "promoted" to the new level.

Codeline Promotion (Branch Promotion, Promoted Branches)

Staged Lines is when there is a promotion branch for each promotion level. Codeline Promotion (or Branch Promotion) is when the branches get promoted, rather than the versions. Instead of having a branch-per-level, a single codeline has a "level" or state associated with it that indicates the current promotion level of all versions on that branch-type. (One typically uses an attribute on the brtype to indicate the promotion level, and hyperlinks might even be used to indicate predecessor and successor levels). When the versions on a codeline are deemed stable and ready to proceed to the next level, the level is associated with the branch, and the branch itself is what gets promoted (instead of copymerging all the versions to another branch).

Change Propagation

This deals with propagating changes from other integration branches. If a change is made in one codeline that is needed in another codeline (for example, a bugfix in release 1.0 might happen on the release 1.1 codeline, and the fix also needs to find its way into the release 2.0 codeline), some groups simply wait for some (possibly long) durations before merging those changes from one codeline to the other.

Other groups however will propagate changes early and often, syncing up the changes in one codeline (e.g. the rel-1.1 codeline) with the other codeline (e.g. the rel-2.0 codeline) at regular and frequent intervals (sometimes per-task, other times daily, or weekly).


Release Branches

A Release Branch is a codeline reserved for work towards a particular release or a major release. Usually the release codeline is a kind of integration branch. Sometimes a Release Codeline will have its own separate integration branch, but that is relatively rare.

Major Release Line

A major release codeline is one that would be created for all releases with the same major version number (e.g. 1.0, 1.1, ..., 1.x). So a release 1.x codeline would be used for integration (and/or development) of all features for release 1 and all its subsequent maintenance releases and patches. If early branching was used, the major release line is created right away. Otherwise if lazy (deferred) branching was used, it might not be created until just before or just after the initial major release of that code (in which case most of the development happened on a LAG mainline, and the branch was created for release engineering and integration as well as for subsequent maintenance).

Codeline per Release

This is when a release branch is created for every release (major and minor). More often than not, each release-line is branched off from the mainline (possibly after syncing up the mainline with other release lines first, to "refresh" it with the latest baselines before branching off of it - this helps avoid continually cascading release lines off release lines).

Sometimes a release-line is branched off the major release line for each specific release (instead of from the mainline). In this case the Major release-line may serve as either a "Stable Receiving Line" if Early Branching is used, or a "LAG development line" if Deferred Branching is used.

Codeline per Major Release

Sometimes major-release lines are always created, and branches are only created for a specific release of the major-release in the event they seem absolutely necessary for a bigger/tougher than usual release engineering effort (in which case they are often quickly merged back to the major release-line when finished).

Patch Line

In addition to branching for major or minor releases, sometimes a separate branch is created for a specific patch-effort. The effort might simply be for a single task that results in a released "patch", or it might be more long-lived over several tasks (usually for a limited period of time, like a month or two) and results in a released patch (possibly before or after merging it back to the release-line).

The more common case is where code on the patch-line is released only after everything on the patch-line has been integrated and baselined. However some groups that need to very quickly respond to a set of internal or "in house" users will use the patch-branch (and its corresponding workspace) as a kind of emergency patch-release area to quickly push out incremental fixes to a recent release.


Mainline

A mainline is kind of a "homing line" or "anchor" for all other paths of development branched off from it. If there is only one persistent variant of the code (e.g. no platform-lines nor functional-lines are needed) then only one mainline is usually required. (And in ClearCase this will almost always be "/main".)

Mainlines are typically used primarily for integration, and serve as a stable receiving line; or else they are used as the primary LAG development line. Some groups even use a LAG development mainline that gets periodically merged to an integration mainline.

Mainlines serve as the main-stream from all other major codelines are branched. And every major codeline eventually must merge back to the mainline at periodic intervals and/or before retiring/decommissioning the major codeline. This helps avoid the "continuing cascade problem" where each release-line branches of from its predecessor release, and the predecessor has to propagate its changes to its successor, resulting in a very deep and wide propagation of changes from release-line to release-line with no end in sight.

Using a mainline causes all child codelines to regularly merge back to their common parent codeline, especially before branching a new codeline off from the mainline. This reduces the breadth of the version tree, and keeps the level of cascading down to a bare minimum, which in turn decreases the number of transitive levels of change-propagation that are necessary.

Stable Mainline

A Stable Mainline is a mainline that is used solely as a stable-receiving line to which other stable baselines and codelines are integrated. Development never takes place on the mainline, and only stable baselines and/or stable codelines are ever merged to main. Stable Mainlines are often used in conjunction with Early Branching.

LAG Mainline

A LAG Mainline s a mainline that is used for the latest and greatest (LAG) development of the system or project. The most recent work for the very latest release/project takes place on the mainline. Work that is no longer the latest and greatest, and is not needed in the new latest efforts is branched off into its own codeline at that time for release-engineering and/or maintenance. LAG Mainlines are often used in conjunction with Deferred Branching.

Sync Mainline before Branching

Before branching a new codeline off of the mainline, some shops will insist that the mainline be "synchronized" (or "refreshed") by first integrating any outstanding codelines to mainline before spawning the new codeline's branch.

A select few shops will actually label the baseline before mainlining the release, and will then move/replace the baseline label after it has been mainlined (renaming the old baseline label before redefining the new one).

Time-Shared Mainline

Some shops employ time-sharing on the mainline. Various teams for the various releases are working in parallel on their own codeline. When it comes time for a group to merge their codeline to the mainline, that group has exclusive ownership of the mainline for the duration of the integration to main, and no other groups may checkin to the mainline at that time.

Sometimes this time-sharing takes place before the given codeline is completely stable or baselined. Intead of (or perhaps in addition to) merging the latest changes from the mainline into their codeline, they will merge their changes to the mainline for integration before baseline and release, and do their build and integration work on the mainline. This encourages a kind of "hit and run" strategy where "tiger teams" or "SWAT teams" quickly pounce on the mainline taking it over, quickly do what they need to do, and then quickly get out.

Multiple Mainlines (Alternate Mainlines)

If there is more than one variant configuration development path (either for platform-specific development paths, or for functional variants) then Multiple Mainlines (a.k.a. Alternate Mainlines) may be used. Each platform-variant or functional-variant is assigned its own mainline and serves as the "mother of all codelines" within its own particular variant.

Sometimes when several component-lines are used, the integration-line for the component or subsystem is viewed as a component-mainline within the scope of the component. But if there is a system-wide integration line that all the components eventually merge into, then the system integration line typically serves as the "mainline" from a whole-systems perspective.


Labels

Mainline Baseline

A baseline label that is applied after the corresponding versions have all been merged back to the "mainline."

Release-Line Baseline

A baseline label that is applied after the corresponding versions have integrated into the "release-line" but before any merges from the release-line to the mainline.

Change-Package or Change-Set Label

A label applied to the final set of versions checked-in for a change-task.

Task Checkpoint

A label applied to an intermediate state of the versions in a change-set or change-package. Subsequent versions may be checked-in before the change-task is complete, and the checkpoint may be used to recall a previous configuration of the task if desired.

Configuration (Config) Checkpoint

Like a "task checkpoint" only the versions needed for the developers configuration are labeled, and not just the working-set of versions being modified in the view. The config-checkpoint may take a lot longer to create. It also captures versions of elements that may have been integrated into the view, but which the developer didn't modify as part of the change-task.

Baseline VOB in View/Cspec

A baseline label that is created by applying the label to all versions in the VOB(s) that are selected in the build/integration view's config-spec. Labeling all the versions in the VOB(s) includes directory versions (or even Makefile versions) that a config-rec might (or clearmake) typically miss. It may also label versions that didn't necessarily participate in the build.

Baseline Config-Rec

A baseline label based applied to the versions indicated by the configuration-record(s) (config-recs) of the build.

Component Baseline

A Component Baseline is a baseline label created for a component or subsystem (or some other architectural subset) of the overall system or product.

Feature-Set Baseline

A Feature-Set Baseline is a baseline label created for a cohesively related set of system features or requirements (or some other functional subset) of the overall product.

Baselevel or Build-Label

A Baselevel or Build-Label is a kind of internal-use-only baseline. It corresponds to a label that is used to represent a consistent/stable configuration of the codeline, but which is not officially delivered or released or otherwise "published" outside the product development group.

Floating-Baselevel or Floating-Label

Typically, when a baseline label is created, its definition (the set of versions it labels) almost never changes once the baseline is "published" and made available to other users or developers.

A Floating-Label is a label whose definition is periodically updated. A Floating-Baselevel is a baselevel-label that is regularly updated to correspond to the most recently integrated stable state of the codeline. Its not quite as dynamic as .../LATEST, but its more dynamic than a static label definition that never changes. Some of the dynamic-update capability of the "LATEST" label is traded-off to ensure that the resulting labeled configuration is always a consistent one, but it still tries to be as dynamic as possible within that constraint.

Incremental Baselevels

In contrast to a "floating baselevel", an Incremental Baselevel does not keep the same name between baselevel definitions. Whenever the integration and build process creates a stable and consistent configuration for the codeline, a baselevel-label is created with some indication that it is the next label in a linear progression that includes its predecssors and successors (typically by some extra numeric-field at the end of the label).

It is extremely common to see "floating baselevels" used in conjunction with incremental baselevels. In this case the floating label always corresponds to the same set of versions as the most recent incremental baselevel, and the incremental baselevels record the sequence and content of stable configurations of the codeline. Sometimes the floating-label is always a separate label from the latest incremental label. And sometimes a floating label is renamed to correspond to the previous baselevel just before the floating label name is applied to the newest baselevel.

Promotion Labels

Sometimes various "promotion levels" are defined along with the linear progression from one promotion level to the next. These promotion levels may correspond to levels of testing or SQA (e.g., inspected, unit-tested, intg-tested, sys-tested, ...), or to levels of scope/scale (unit, component, subsystem, system, ...), or to levels of authority/responsibility.

One way of using promotion levels is to use a separate label per promotion level for each release or each mainline. When a version is is ready to be promoted from one level to the next, the new promotion label is applied to the version. Sometimes only one promotion-label may be on a version at a time (per release/mainline) and sometimes a version keeps all its previous promotion labels when it gets a new one (like wearing merit badges).

Label Promotion (Promoted Labels)

Promotion Labels are when there is a label for each promotion level per release/mainline. Label Promotion is when the labels get promoted, rather than the versions. Instead of having a label-per-level, a single label has a "level" or state associated with it that indicates the current promotion level of all versions referred to by that label. (One typically uses an attribute on the lbtype to indicate the promotion level, and hyperlinks might even be used to indicate predecessor and successor levels) When the versions on a codeline are deemed stable and ready to proceed to the next level, the level is associated with the label, and the label itself is what gets promoted (instead of copymerging all the versions to another label).


Configuration Records

ClearCase configuration records capture and record the set of file versions that went into a build target, including any derived objects that were generated and the build script or "recipe" used to generate each derived object and target.

Config-Rec as BOM

Some groups use config-recs primarily to serve as a bill of materials for what went into the build (kind of like a what(1) command is used to spew out SCCS or RCS versions strings in an object file). This means that the configuration-record is somehow preserved and checked-in to ClearCase (will have a baseline label applied to it when a baseline is created).

Config-Rec in Config-Spec

Some groups may also use config-recs in the config-spec of a view to reproduce the configuration of all the versions used as part of a build. This doesn't always catch the necessary versions of directories or Makefiles.

Config-Rec Comparison

Some groups use config-recs but don't necessarily version or label them. They have config-recs that are referenced by a unique-name for each build performed in the view (often with the timestamp as part of the unique-name) and use the config-recs primarily so they can execute the "diffcr" command to tell the differences between the configurations of any two builds.


Attributes

Request-ID on Checkout

An attribute corresponding to the the ID of a record in a change/defect tracking system that is applied to a version when it is checked-out.

Request-ID on Checkin

An attribute corresponding the the ID of a record in a change/defect tracking system that is applied to a version when it is checked-in.

Request-ID on Task

An attribute corresponding the the ID of a record in a change/defect tracking system that is applied to a change-task (which may be represented by a branch or a label).

Version State

An attribute indicating the state or promotion level of a version.

Branch State

An attribute indicating the state or promotion level of a branch.

Label State

An attribute indicating the state or promotion level of a label.

Change-Set Membership

An attribute indicating the name/id of the change-set (change-package) to which this element-version belongs.

Component Membership

An attribute indicating the name of the component or subsystem to which an element belongs.

Feature-Set Membership

An attribute indicating the name of the component or subsystem to which an element belongs.


Hyperlinks

Transfer Link

A hyperlink from a migration/transfer task (branch or label type) to the original task being transfered

Propagation Link

A hyperlink from a codeline to one or more codelines to propagate changes to.

Promotion Link

A hyperlink from a label or a branch to the predecessor or successor label or branch that corresponds to the next state or promotion level in a linear progression.

Task Baseline Link

A hyperlink from a change-task branch/label-type to the baseline label-type used for its development.

Task Target Baseline Link

A hyperlink from a change-task branch/label-type to the target release/baseline label-type that the change is expected to be integrated and delivered in.

Task Codeline Link

A hyperlink from a change-task branch/label-type to the codeline branch-type used for its development.

Task Target Codeline Link

A hyperlink from a change-task branch/label-type, to the target release/codeline lbtype or brtype that the change is expected to be integrated into.

Task Dependency Link

A hyperlink from a change-task branch/label-type to one or more other change-tasks upon which it depends (maybe it merged them in, or maybe it simply needed to refer to them in its config-spec).

Codeline-Baseline Link

A hyperlink between a branch-type for a codeline, and the label-type that will be applied once everything has been integrated into that codeline and the codeline is "retired."

Codeline-Mainline Link

A hyperlink from a codeline branch-type to the branch-type that serves as it's "mainline."


Triggers

pre-checkout

pre-checkout request-ID validation

pre-checkout element access verification

pre-checkout codeline access verification

pre-checkout comment verification

post-checkout

post-checkout notify

pre-checkin

pre-checkin request-ID validation

pre-checkin element access verification

pre-checkin codeline access verification

pre-checkin comment verification

post-checkin

post-checkin notify

pre-unco

pre-unco request-ID validation

pre-unco element access verification

pre-unco codeline access verification

post-unco

post-unco notification

remove /0 version on unco

remove /0 version and branch on unco .../branch/1 version

remove /0 version and element on unco of /main/1 version

pre-rmver

prevent version removal by ordinary users

pre-rmname

prevent element entry removal from directories by ordinary users

pre-rmbranch

prevent branch removal by ordinary users

pre-rmtype

prevent type (lbtype, brtype, etc.) removal by ordinary users

pre-rmelem

prevent element removal by ordinary users

pre-mkelem

prevent parallel creation of different files with the same name in the same directory

post-mkelem

modify the protections of newly created elements to give them the appropriate owner and group and read/write access permissions.

pre-mkbrtype

prevent branch-type creation by ordinary users

enforce branch-naming conventions

require comment on branch-creation

post-mkbrtype

attach branch-type attrs/hlinks on creation

pre-mklbtype

prevent label-type creation by ordinary users

enforce label-naming conventions

require comment on label-creation

post-mklbtype

attach label-type attrs/hlinks on creation

pre-mklabel

prevent labeling by ordinary users

pre-mktrtype

prevent trigger creation by ordinary users

pre-mkattype

limit attribute-type creation by ordinary users

pre-mkattr

limit attribute value assigment by ordinary users

post-mkattr

notification of attribute value changes

pre-submit (simulated)

simulate a pre-op trigger for completion/submission of a change-task as a single logical change-set.

post-submit (simulated)

simulate a post-op trigger for completion/submission of a change-task as a single logical change-set.

pre-mkview (simulated)

simulate a pre-op trigger for view creation

post-mkview (simulated)

simulate a post-op trigger for view creation

pre-rmview (simulated)

simulate a pre-op trigger for view removal

post-rmview (simulated)

simulate a post-op trigger for view removal

cmd-trigger (simulated)

simulate pre-op/post-op triggers for entire commands (rather than individual events)


Locks

task-lock

lock task branch against changes by non-owner

lock task branch/label type against changes after completed submission

integration/merge lock

lock integration lines against checkin by non-integrators

mainline lock

lock mainline against checkin by ordinary users

baselevel lock

lock baseline label definitions after baselining

floating label lock

lock floating labels against change by ordinary users

metadata lock

lock metadata (attributes and hyperlinks) against changes by ordinary users (unless performed automatically by triggers)

element lock

lock elements against modification by unauthorized users

component lock

lock "components" or "subsystems" against modification by unauthorized users

VOB lock

lock entire VOBs against access by unauthorized users


Multi-Site


Tool-Supported Roles/States

branch roles

branch states

component/subsystem roles

component/subsystem states

integration roles

integration states

build roles

build states

release roles

release states

administration roles

administration states


VOB Management

VOB naming conventions

Use of Admin VOBs

VOB per group

VOB per product

Multiple VOBs per product

VOBs shared by multiple products

VOBs shared by multiple groups

Separate VOB for documents

Separate VOB for externally supplied files

Separate VOB for tools and libraries


View Management

view naming conventions

users create their own views

tool creates user's views

users decide where to store their views

tool decides where to store user views

policies specifying viewstorage usage/locations

users can chmod/chgrp/chown their views

shared views (multiple developers in same view)

one developer per view

dedicated integration/build views

dedicated release views

view per task

view per developer

viewpool or upperbound on number of active views

view seeding

View seeding is a way of "pre-populating" a view with the needed derived object to speedup subsequent builds and winkins.


Config-Spec Management & Version Selection

users create their own initial cspecs

tool creates initial cspecs

users modify their own cspecs

tools modify user's cspecs

dynamic version selection

Some shops have developer's config-specs select the /LATEST versions on the codeline. As soon as they are checked in to the codeline, the developers may see them in their views. This can be more problematic if online development is permitted than if all work is done on task-branches.

static version selection

Some shops expressly do not select the /LATEST versions on the codeline. Instead, the select only the most recently labeled baselevel of the codeline.

static file versions but dynamic directories

Some shops will use static version selection for files, selecting the versions on a labeled baselevel, but use dynamic selection for directories (using a '-directory' rule to select the /LATEST versions on the codeline for directory elements). This lets developers always see the latest version of a directory in the codeline, and avoids collisions resulting from creating files by the same name on different branches. If a new file has been created by someone else, they will see the new file in their view, but not necessarily its contents.

selection of /main/0

Some groups (especially those that dont work directly on /main) will always insert a rule at the end of a config-spec that selects the /main/0 version of any file or directory not yet selected. This lets them see files and directories created in some other branch so they dont create colliding file or directory elements.


Version Management

of source code

of auto-generated source code

of derived object files

of built executables

of built libraries

of environment/options settings

of documents

of program data inputs/outputs

of test cases, test vectors, or test results

of build tools (compilers, linkers, debuggers)

of externally supplied libraries

of externally supplied and system header files

of externally supplied source code

of externally supplied binaries/images


Integration with Tracking System

on element creation

on version checkout

on version checkin

on uncheckout

on branch-type creation

on branch creation

on label-type creation

on label-creation

performer-verification

Verify that a particular ClearCase action (e.g., checkin/checkout or creation of a branch-type or label-type) is performed only by the user that is assigned or authorized to perform that action as declared in the corresponding change-request record.

on record state transitions

ClearCase data obtained from issue/task record

Target-Release defines Config-Spec

The target-release specified for a record in the tracking system is used to define or enforce the codeline and/or baseline (branch and/or label) used for development in the view's config-spec.

ClearCase data logged to issue/task record

Separate record-type for defects

Separate record-type for feature requests/development

Separate record-type for build/integration requests

Separate record-type for inspections/reviews

Separate record types for document changes


Document Management

Document naming conventions

Document ID naming conventions

Document location conventions

Concurrent Development for documents


Release Management

Release naming conventions

Release numbering conventions

Target-Release per Change/Feature

Every record for every change-request, bugfix, or feature/enhancement request is required to estimate an intended target release for the proposed change.

Integration approval per Request/Feature

Some shops require CCB approval before allowing integration of a requested feature, fix, or enhancement into a release-codeline. Approval is mode at the level of a given feature or function to decide not only if it should be integrated, but more importantly which release codeline/baseline it should be integrated into (possibly changing previous plans for the targeted baseline/release).

Integration approval per Change-Task

Some shops require CCB approval before allowing integration of any completed change-task into a release-codeline. Approval is mode at the level of a given task or subtask to decide not only if it should be integrated, but more importantly which release codeline/baseline it should be integrated into (possibly changing previous plans for the targeted baseline/release).


Access Control/Restrictions

Restrictive Code-Ownership

Subsystems and/or Modules of code are assigned a single owner responsible for their integrity, and no one but the code-owner is allowed to checkout (and/or checkin) a piece of code. This actually applies to other artifacts besides source-code, including documents and tests.

Relaxed Code-Ownership

Subsystems and/or Modules of code are assigned a single owner responsible for their integrity, and developers other than the code-owner are permitted to checkout (and/or checkin) a piece of code provided that they have permission from the code-owner. This actually applies to other artifacts besides source-code, including documents and tests.

Restrictive Codeline-Ownership

Individual Codelines are assigned to a single owner responsible for its integrity and no one but the codeline-owner is allowed to checkout from (and/or checkin to) the codeline.

Relaxed Codeline-Ownership

Individual Codelines are assigned to a single owner responsible for its integrity anddevelopers other than the codeline-owner are permitted to checkout from (and/or checkin to) the codeline provided that they have permission from the codeline-owner


Change Control Boards

CCB per component/team

Product-wide Software CCB

System-level CCB (includes both hardware and software)

Business-level CCB

Work approval per Request/Feature

Some shops require CCB approval for a request feature, fix, or enhancement before effort has been made to breakdown the proposed work into tasks and subtasks. Approval is mode at the level of a given feature or function. Subsequent approval of the constituent tasks needed to implement the functionality may or may not take place, and rejection of a task or subtask may change the current accept/reject status of the corresponding feature or fix.

Work approval per Change-Task

Many shops require a proposed change to obtain CCB approval before any development work can begin on that change. This is often done an a per-task basis, requiring approval for each planned development task (possibly including subtasks) for a given feature or request.


back to the ACME Home Page