This chapter shows one way in which ClearCase can be used to organize development work, including both creation of a new release and concurrent maintenance of the previous release.
The approach taken in this chapter is by no means the only one that ClearCase supports. We believe that it addresses typical organizational needs in a straightforward, sensible way.
Release 2.0 development of the monet project is to include several kinds of work:
patches — a small number of high-priority bugfixes to Release 1.0
minor enhancements — some commands need new options; some option names need to be shortened ( –recursive becomes - r); some algorithms need performance work
major new features — graphical user interface; many new commands; internationalization support
These three development streams can proceed largely in parallel (Figure 21-1), but major dependencies and milestone dates must be considered:
Several Release 1 patch releases will ship before Release 2.0 is complete.
The new features will take longer to complete than the minor enhancements.
Certain new features depend on the minor enhancements.
The overall plan adopts a baselevel-plus-changes approach. Periodically, developers stop writing new code, and spend some time integrating their work, building, and testing. The result is a baselevel: a stable, working version of the application. ClearCase makes it easy to integrate product enhancements, incrementally and frequently. The more frequent the baselevels, the easier the tasks of merging parallel development work and testing the results.
After a baselevel is produced, “real” work resumes; any new development efforts begin with the set of source versions that went into the baselevel build.
With ClearCase, a baselevel can be defined by assigning the same version label (for example, R2_BL1 for “Release 2, Baselevel 1”) to all the versions that go into, or are produced by, the baselevel build.
![]() | Note: The development staff will be divided into three teams, each working on a different development stream: the MAJ team (major enhancements), the MIN team (minor enhancements) and the FIX team (Release 1 bugfixes and patches).Some developers might belong to multiple teams. Such developers would switch views, depending on their current task |
Figure 21-2 shows the development area for the monet project. At the beginning of Release 2 development, the most recent versions on the main branch are all labeled R1.0.
This section discusses the ClearCase-related issues to be resolved before development begins.
In most development efforts, the project leader and the system administrator are different people. The leader of this project will be a user named meister. The administrator will be the vobadm user, introduced in earlier chapters as the creator and owner of the monet and libpub VOBs.
In general, different kinds of work should be performed on different branches. High-priority Release 1 bugfixing, for example, should take place on its own branch. This isolates it from new development. It also enables creation of bugfix (“patch”) releases that do not include any of the Release 2 enhancements — and incompatibilities.
Since the MIN team will produce the first baselevel release essentially on its own, the project leader decides to give the main branch to this team. The MAJ team will develop major enhancements on a subbranch, and will not be ready to integrate for a while; the FIX team will perform Release 1 bugfixing on another subbranch, and can integrate its bugfix changes at any time.
![]() | Note: The project leader has arranged matters so that the first baselevel will be created from versions on the main branches of their elements. This is not a requirement, however — you can create a release that uses versions on any branch, or combination of branches. |
Figure 21-3 shows the evolution of a typical element during Release 2 development, and indicates correspondences to the overall project plan (Figure 21-1).
Each developer will work in his or her own view, editing programs, building software, testing, and so on. Though the views are separate, they will all be configured with the same config spec. This produces a development environment in which developers on the same team:
“see” the development tree in the same way
are totally isolated from work performed on other branches
are isolated from each other when they checkout elements and make changes to them
share each others' source code, as versions are checked in on their common branch
share each others' derived objects (through clearmake's wink-in capability), when appropriate
The MAJ team will work on a branch named major, and will use this config spec:
element * CHECKEDOUT (1) element * .../major/LATEST (2) element * R1.0 -mkbranch major (3) element * /main/LATEST -mkbranch major (4) |
The MIN team will work on the main branch, and so can use the default config spec:
element * CHECKEDOUT (1) element * /main/LATEST (2) |
The FIX team will work on a branch named r1_fix, and will use this config spec:
element * CHECKEDOUT (1) element * .../r1_fix/LATEST (2) element * R1.0 -mkbranch r1_fix (3) element * /main/LATEST -mkbranch r1_fix (4) |
For the MAJ and FIX teams, use of the auto-make-branch facility in Rules 3 and 4 enforces consistent use of subbranches. It also relieves developers of having to create branches explicitly, and ensures that all branches are created at the version labeled R1.0.
The project leader creates the major and r1_fix branch types required for the config specs listed above:
% cleartool mkbrtype -vob /proj/monet r1_fix major Comments for "r1_fix": development branch for monet R1 bugfixes . Created branch type "r1_fix". Comments for "major": development branch for monet R2 major enhancements . Created branch type "major". % cleartool mkbrtype -vob /proj/libpub r1_fix m (same interaction as above) |
To ensure that all developers in a team configure their views the same way, the project leader creates files containing standard config specs:
/public/config_specs/MAJ contains the MAJ team's config spec
/public/config_specs/FIX contains the FIX team's config spec.
(These standard config spec files are stored in a standard UNIX directory, so that there is no possibility of users getting different versions of them.)
Each developer creates a view under his or her home directory. For example, developer allison enters these commands:
% mkdir $HOME/view_store % cleartool mkview -tag allison_major $HOME/view_store/arbmaj.vws View /net/phobos/usr/people/arb/view_store/arbmaj.vws created It has the following rights: User : allison : rwx Group: mon : rwx Other: : rwx |
A new view has the default config spec. Thus, developers on the MAJ and FIX teams must reconfigure their views, using the standard file for their team. For example:
% cleartool setcs -tag allison_major /public/config_specs/MAJ |
If the project leader changes the standard file, developers can pick up the changes by entering this command again.
To begin the project, a developer sets his or her properly-configured view, checks out one or more elements, and gets to work. For example, developer david on the MAJ team enters:
% cleartool setview david_major % cd /proj/monet/src % cleartool checkout -nc opt.c prs.c Created branch "major" from "opt.c" version "/main/6". Checked out "opt.c" from version "/main/major/0". Created branch "major" from "prs.c" version "/main/7". Checked out "prs.c" from version "/main/major/0". |
The auto-make-branch facility causes each element to be checked out on the major branch (see Rule 4 in the MAJ team's config spec, on page 329). If a developer on the MIN team enters this command, the elements are checked out on the main branch, with no conflict.
ClearCase is fully compatible with standard UNIX development tools and practices. Thus, developers use their familiar editing, compilation, and debugging tools (including personal scripts and aliases) while working in their views.
Developers use checkin periodically to make their work automatically visible to other developers on the same team (that is, others whose views select the most recent version on the team's branch). This allows intra-team integration and testing to proceed throughout the development period.
Although this chapter is intended to illustrate a single approach to organizing development, we briefly note here some techniques that individual developers might use to isolate themselves from changes made by other members of their team.
Time rules — If another team member checks in an incompatible change, a developer can “turn back the clock” to a time before those changes were made.
Further subbranching — A developer can create a private subbranch in one or more elements (for example, /main/major/jackson_wk) to isolate herself from other team members' new versions of those elements. This requires a config spec change, to “prefer” versions on the /main/major/jackson_wk branch to versions on the /main/major branch.
Viewing only one's own revisions — A developer can use a ClearCase query to configure a view which sees only her own revisions to the source tree.
The MIN team has implemented and tested the first group of minor enhancements, and the FIX team has produced a patch release, whose versions are labeled R1.0.1. It is time to combine these efforts, to produce Baselevel 1 of Release 2.0 (Figure 21-4).
The project leader asks the MIN developers to merge the R1.0.1 changes from the r1_fix branch into their own branch (main). All the changes can be merged with a single invocation of findmerge:
% cleartool findmerge /proj/libpub /proj/monet/src \
-fversion .../r1_fix/LATEST -merge -xmerge
.
. <lots of output>
.
|
After all merges have been performed, the /main/LATEST versions of certain elements represent a combination of the efforts of the MIN and FIX teams. Members of the MIN team now compile and test the monet application to find and fix incompatibilities in the two teams' work.
The developers on the MIN team choose to perform the integration in a single, shared view. The project leader creates the view storage area in a location that is NFS-accessible to all developers' hosts:
% umask 2 % mkdir /netwide/public % cleartool mkview /netwide/public/integrate.vws View /netwide/public/integrate.vws created It has the following rights: User : meister : rwx Group: mon : rwx Other: : r-x |
The umask value of 2 allows all members of the mon group to use the view. Each developer registers this view on his or her host, under the name base1_vu. For example, suppose that sol:/netwide/public is mounted at /public on all user's workstations:
% cleartool mktag /public/integrate.vws base1_vu |
Since all integration work takes place on the main branch, there is no need to change the configuration of the new view from the ClearCase default. MIN team developers set this view (cleartool setview base1_vu) and coordinate builds and tests of the monet application. Since the developers are sharing a single view, they are careful not to “clobber” each other's view-private files. Any new versions created to fix inconsistencies (and other bugs) go onto the main branch.
The monet application's minor enhancement work and bugfix work are now integrated, and a clean build has been performed in view base1_vu. To create the baselevel, the project leader assigns the same version label, R2_BL1, to the /main/LATEST versions of all source elements. He begins by creating an appropriate label type:
% cleartool mklbtype -vob /proj/monet -c "Release 2, \
Baselevel 1" R2_BL1
Created label type "R2_BL1".
|
![]() | Note: Also creates and locks label type in libpub VOB. |
For security, he locks the label type, preventing all developers (except himself) from using it:
% cleartool lock -nusers meister -vob /proj/monet -lbtype \
R2_BL1
Locked label type "R2_BL1".
|
![]() | Note: Also creates and locks label type in libpub VOB. |
Before applying labels, he verifies that all elements are checked in on the main branch (checkouts on other branches are still permitted):
% cleartool lscheckout -avobs | egrep '(monet|libpub)' |
Null output indicates that all elements for the monet project are checked in. Now, the project leader attaches the R2_BL1 label to the currently-selected version (/main/LATEST) of every element in the two VOBs:
% cleartool mklabel -recurse R2_BL1 /proj/monet /proj/libpub Created label "R2_BL1" on "/proj/monet" version "/main/1". Created label "R2_BL1" on "/proj/monet/src" version "/main/3". <many more label messages> |
The MAJ team has been working undisturbed throughout the Baselevel 1 integration period. At some point following this milestone, the MAJ team pauses to merge the Baselevel 1 changes into its work (Figure 21-5). This provides access to the minor enhancements that the MAJ team needs for further development. It also provides an early opportunity for MAJ team members to determine whether they have made any incompatible changes.
Accordingly, the project leader declares a freeze of major enhancements development. MAJ team members checkin all elements, and verify that the monet application builds and runs, making small source changes as necessary. When all such changes have been checked in, the team has a consistent set of /main/major/LATEST versions.
The project leader makes sure that no element is checked out on the major branch:
% cleartool lscheckout -avobs | egrep \
'(monet|libpub).*/major/'
|
![]() | Note: Any MAJ team members who wish to continue with non-merge work can create a subbranch at the “frozen” version (or work with a version that is checked out unreserved). |
The project leader determines which elements need to be merged:
% cleartool setview major_vu (use any MAJ team view)
% cleartool findmerge /proj/monet /proj/libpub -version \
/main/LATEST -print
.
. <lots of output>
.
A 'findmerge' log has been written to
"findmerge.log.04-Feb-94.10:01:23"
|
The findmerge log file is in the form of a shell script: it contains a series cleartool findmerge commands, each of which will actually perform the required merge for one element:
% cat findmerge.log.04-Feb-94.10:01:23 cleartool findmerge -dir /proj/monet/src@@/main/major/3 -fver /main/LATEST -merge cleartool findmerge /proj/monet/src/opt.c@@/main/major/1 -fver /main/LATEST -merge cleartool findmerge /proj/monet/src/prs.c@@/main/major/3 -fver /main/LATEST -merge . . cleartool findmerge -dir /proj/lubpub/src@@/main/major/1 -fver /main/LATEST -merge cleartool findmerge /proj/libpub/src/dcanon.c@@/main/major/3 -fver /main/LATEST -merge cleartool findmerge /proj/libpub/src/lineseq.c@@/main/major/10 -fver /main/LATEST -merge |
Assigning merge tasks to individual developers amounts to parceling out the contents of this log file.
The project leader then locks the major branch, allowing it to be used only by the developers who will be performing merges:
% cleartool lock -nusers meister,allison,david,sakai \
-brt major
Locked branch type "major".
|
![]() | Note: Also locks branch type in libpub VOB. |
Since the MAJ team is not immediately heading for a baselevel, it is not essential that all merges be performed (and the results tested) in a shared view. Each MAJ developer can continue working in his regular view.
Periodically, the project leader sends an excerpt from the findmerge log to an individual developer, who executes the commands and monitors the results. (The developer can sends the resulting log files back to the project leader, as confirmation of the merge activity.)
A merged version of an element will include changes from three development streams: Release 1 bugfixing, minor enhancements, and major enhancements (Figure 21-6).
The project leader verifies that no more merges need to be performed, by entering a findmerge command with the - whynot option:
% cleartool findmerge /proj/monet /proj/libpub -version \
/main/LATEST -whynot -print
.
.
No merge "/proj/monet/src" [/main/major/4 already merged from /main/3]
No merge "/proj/monet/src/opt.c" [/main/major/2 already merged from /main/12]
..
|
He ends the merge period by removing the lock on the major branch:
% cleartool unlock -brtype major Unlocked branch type "major". |
![]() | Note: Also locks branch type in libpub VOB. |
The MIN team has reached its second development freeze, and the MAJ team will do so shortly (Figure 21-7). Baselevel 2 will integrate all three development streams, thus requiring two sets of merges:
Bugfix changes from the most recent patch release (versions labeled R1.0.2) are to be merged to the main branch.
Major enhancements are to be merged from the major branch to the main branch. (This is the opposite direction from the merges described in “Synchronizing Ongoing Development”.)
ClearCase supports multi-way merges, so both the bugfix changes and the major enhancements could be merged into the main branch at the same time. In general, though, it is easier to verify the results of two-way merges.
The first set of merges is virtually identical to those described in “Merging of Data on Two Branches”. Thus, we omit the details here.
After the integration of the r1_fix branch is completed, the project leader gets ready to manage the merges from the major branch. These merges will be performed in a tightly-controlled environment, because of the approaching Baselevel 2 milestone, and because the major branch is to be abandoned.
The project leader verifies that everything is checked in on both the main branch and major branches:
% cleartool lscheckout -recurse /proj/monet \
/proj/libpub | grep -v 'r1_fix'
%
|
This command filters out checkouts on the r1_fix branch, which are still permitted. Thus, null output from this command indicates that no element is checked-out on either its main branch or its major branch.
Next, the project leader determines which elements require merges:
% cleartool setview minor_vu (use any MIN team view)
% cleartool findmerge /proj/monet /proj/libpub \
-version .../major/LATEST -print
.
. <lots of output>
.
A 'findmerge' log has been written to
"findmerge.log.26-Feb-94.19:18:14"
|
All development on the major branch is to cease after this baselevel. Thus, the project leader locks the major branch to all users, except those who will be performing the merges; this will allow ClearCase to record the merges with a hyperlink of type Merge:
% cleartool lock -brtype -nusers allison,david major Locked branch type "major". |
![]() | Note: Also locks branch type in libpub VOB. |
The main branch will be used for Baselevel 2 integration by a small group of developers. Accordingly, the project leader had vobadm lock the main branch to everyone else:
% cleartool lock -nusers meister,allison,david,sakai \
-brtype main
Locked branch type "main".
|
![]() | Note: Also locks branch type in libpub VOB. |
(Only the VOB owner or root can lock the main branch.)
Since the main branch is the destination of the merges, developers work in a view with the default config spec. The situation is similar to that on described in <Emphasis>Preparing to Merge; this time, the merges are to take place in the opposite direction: from the major branch to the main branch. Accordingly, the findmerge command is very similar:
% cleartool findmerge /proj/monet /proj/libpub
-version /main/major/LATEST -print
.
. <lots of output>
.
A 'findmerge' log has been written to
"findmerge.log.23-Mar-94.14:11:53"
|
After checkin, a typical merged element appears as in Figure 21-8.
After all data has been merged to the main branch, no further development is to take place on the major branch. At that time, the project leader enforces this policy by obsoleting the major branch:
% cleartool unlock -brtype major Unlocked branch type "major". % cleartool lock -obsolete -brtype major Locked branch type "major". |
![]() | Note: Also locks branch type in libpub VOB. |
Structurally, the Baselevel 2 integration-and-test phase is identical to the one for Baselevel 1 (see “Integration and Test”). At the end of the integration period, the project leader attaches version label R2_BL2 to the /main/LATEST version of each element in the monet and libpub VOBs (the Baselevel 1 version label was R2_BL1).
Baselevel 2 has been released internally, and further testing has flushed out only minor bugs. These bugs have been fixed by creating new versions on the main branch (Figure 21-9).
Prior to customer shipment, the monet application will go through a tightly-controlled validation phase:
All editing, building, and testing will be restricted to a single, shared view.
All builds will be performed from sources with a particular version label (R2.0), and only the project leader will have permission to make changes involving that label.
Only high-priority bugs will be fixed, using this procedure:
The project leader authorizes a particular developer to fix the bug, by granting her permission to create new versions (on the main branch).
The developer's checkin activity is automatically tracked by a ClearCase trigger.
After the bug is fixed, the project leader moves the R2.0 version label to the fixed version, and revokes the developer's permission to create new versions.
The project leader labels the /main/LATEST versions throughout the entire monet development tree:
% cleartool setview meister_vu
(set a view with default config spec)
% cleartool mklbtype -c "Release 2.0" R2.0
(create a label type)
% cleartool lock -nusers meister -lbtype R2.0
(restrict usage of label type)
Locked label type "R2.0".
(label the entire development tree)
% cleartool mklabel -recurse R2.0 /proj/monet
<many label messages>
|
![]() | Note: Also locks branch type and labels versions in libpub VOB. |
During the final test phase, he will move the label forward, using mklabel –replace, if any new versions are created.
At this point, use of the main branch is restricted to a few users: those who performed the merges and integration leading up to Baselevel 2 (see page 340). Now, the project leader has vobadm close down the main branch to everyone except himself, meister:
% cleartool unlock -brtype main Unlocked branch type "main". % cleartool lock -brtype -nusers meister main Locked branch type "main". |
The main branch will be opened only for last-minute bugfixes (see “Implementing a Final Bugfix”.)
The project leader creates a new shared view, r2_vu, and gives it a special, one-rule config spec:
% umask 2 % cleartool mkview -tag r2_vu /public/integrate_r2.vws % cleartool edcs -tag r2_vu <edit config spec to contain ... > element * R2.0 (1) |
This config spec guarantees that only properly-labeled versions will be included in final-validation builds.
Then, he has vobadm create a global element trigger type in the monet and libpub VOBs, specifying the script as the trigger action:
% cleartool mktrtype -nc -vob /proj/monet -element -global \
-postop checkin -brtype main \
-exec '/public/ccase_triggers/notify_leader' r2_checkin
Created trigger type "r2_checkin".
|
![]() | Note: Also creates trigger type in libpub VOB. |
(Only the VOB owner or root can create trigger types.)
This section demonstrates the final validation environment in action. Developer allison discovers a serious bug, and requests permission to fix it. The project leader grants her permission to create new versions on the main branch, by having vobadm enter these commands.
% cleartool unlock -brtype main Unlocked branch type "main". % cleartool lock -nusers allison,meister -brtype main Locked branch type "main". |
The developer fixes the bug in a view with the default config spec, and tests the fix there. This involves creation of two new versions of element prs.c and one new version of element opt.c. On each checkin, the r2_checkin trigger automatically sends mail to the project leader. For example:
Subject: Checkin /proj/monet/src/opt.c by allison /proj/monet/src/opt.c@@/main/9 Checked in by allison. Comments: fixed bug #459: made buffer larger |
When regression tests verify that the bug has been fixed, the project leader revokes allison's permission to create new versions. Once again, the commands are executed by vobadm:
% cleartool unlock -brtype main Unlocked branch type "main". % cleartool lock -brtype -nusers meister main Locked branch type "main". |
Then, the project leader moves the version labels to the new versions of prs.c and opt.c, as indicated in the mail messages. For example:
% cleartool mklabel -replace R2.0 \
/proj/monet/src/opt.c@@/main/9
Moved label "R2.0" on "prs.c" from version "/main/8" to "/main/9".
|
After the labels have been moved, developers rebuild the monet application once again, to prove that a good build can be performed using only those versions labeled R2.0.
When the final build in the r2_vu passes the final test, Release 2.0 of monet is ready to ship. After the distribution medium has been created, from derived objects in the r2_vu, the project leader has vobadm clean up and get ready for the next release: