ClearCase Objects

ClearCase provides a wide variety of ways to mark elements and the various versions of elements. The choice can be overwhelming, and many times, there are more than one way to use these objects. Some ClearCase Objects can even have other ClearCase objects attached to them. In fact, this is used to implement Global Object definitions. The following are the ClearCase Objects discussed in this section:

  1. Label Types
  2. Attribute Types
  3. Hyperlink Types
  4. Element Types
  5. Branch Types

Using Objects

For a ClearCase Object to be used, it must first be created. The mk**type command creates the object. The Object type must be created in each VOB that you will use the object in. Before ClearCase 3.x, this was done manually. With ClearCase 3.x, you can now specify a "Global" type that will allow you to automatically define the ClearCase Object Type in the VOB when you first use the instance of that Object Type. Once that Object Type is created, you then attach the object type by using the mk<object> command. For example, "mkhlink", "mkbranch", "mklabel", etc. Below is a table of showing the Make Object Type command and the command to attach the object to a ClearCase element, version, or object.

ClearCase Object Commands
Make Object Type Command
Attach Object
Mklbtype Mklabel Labels can only be attached to an element version, and by default, only one instance of a label type may be attached to any version of an element tree. However, you can define a label type so that one instance of a label type can appear once on each branch of a tree. This is definitely not recommended.
Mkattype Maattr Attributes are the most flexible of all object types. An attribute can be attached to an element, a version of an element, a label, a hyperlink, on even upon another attribute. When you attach an attribute, you also give a value to that you want to attach. Multiple instances of an attribute can appear in an element tree, but only one instance of that attribute can be attached to a version.
Mkhltype Mkhlink Hyperlinks are the most unusual type of object. Hyperlinks point from one version of an element to another version, which may be in a different tree. When a new version of an element is created, that version inherits any previous hyperlinks. Multiple instances of the same hyperlink can be pointing to and from the same version of an object. Also, almost any ClearCase type can have a hyperlink attached to it.
Mkeltype Mkelem/chtype When you make a new element, you automatically must create an element type. Element types are a bit confusing because the various element types can be based upon the ClearCase magic file. Only a single instance of an element type can be attached to an element.
Mkbrtype Mkbranch Branches are attached to the version of an element to create a branch off of the version. Branches can have branches, of course. Only a single instance of a branch type can be attached to a particular branch (including /main).

As you can see from this table, object types don't only have to be attached to element versions, but can be attached to other object types themseleves. ClearCase uses this mechanism to attach "from" and "to" text labels on hyperlinks, and to mark which object types are global.

Unfortunately, ClearCase's query mechanism doesn't easily query object types. For example, you might want to create an attribute (one type of ClearCase object) that will help you classify the various labels (another ClearCase object) you've used. Some labels might be for development releases while other labels might be for QC or production versions. You can use the cleartool describe command to get the attribute and value attached to a label, but you couldn't ask ClearCase to show you all the labels where the attribute "LABEL_TYPE" is equal to "PRODUCTION". The only way to get such a list is to use the cleartool lstype -kind lbtype to list each label, then to query each label with the cleartool describe command to see what the attribute is on each label.

Label Types

Label types are the most common object type used. In fact, there is not a ClearCase site that doesn't use labels. Labels are very understandable and the concept of labels can be found in other version control systems. Label types can be easily queried by ether the cleartool find command or by the ConfigSpec:

element * REL_1.0

Notice that the above ConfgSpec will find this label no matter which branch that label is on.

Obviously, labels are very useful in tracking which version of an element goes with other versions of different elements. However, most ClearCase sites overuse labels. This is understandable since labels are easy to comprehend and the concept of labels exists in other Version Control systems. However, labels do have their limits. For example, many sites use labels to show which version of an element is ready for the next build by defining a label type of "BLESSED". Programmers attach this label to the version of an element they want to include in the next build. Then all the Build Manager has to do is create a one line ConfigSpec to find all BLESSED versions. This seems like a good idea, but this type of system runs into several problems.

Labels work best as a snapshot of your system. For example, if I release a particular build, labels can help mark my release. Labels should be more or less static in nature. Once attached to a particular object, they should not be moved.

Attribute Types

Attributes are the most powerful of all ClearCase types, but the least used. Many sites, in fact, don't even use attributes. This is a pity because of their power. Imagine you have a project where some files are only installed on client systems, other files are only installed on server systems, and some files are installed on both client and server systems. Using attributes to mark which elements are for client systems and which elements are for server systems can make releases a bit easier.

ClearCase uses attributes without most people knowing it. When you define the "to" and "from" text of a hyperlink, ClearCase automatically uses attributes attached to the hyperlink with the "to" and "from" text. The real power of Attributes can be shown as a substitute for the "BLESSED" label problem.

Using Attributes for Tracking Software Quality

Instead of using a Label Type of "BLESSED" to mark which version of a file is ready for a build, let's use an attribute called "STATE" to do the same thing. The STATE, can have several values as shown below:

Using Attributes for Defining Build Versions
Attribute Value
BLESSED This version of the element is ready for the next big build.
QC This version of the element has been approved for use by the QC department.
ILAB This version of the element has been approved for use by the Integration lab.
FAILED Version has failed testing, and will be sent back to the programmer to be fixed.
APPROVED Version has been approved for release and will now be labeled as a release.

The Build Manager can now do the build using this ConfigSpec:

element * /main/{STATE=="BLESSED"}

Okay, it doesn't look too different from before. A bit more complex than using a label, so what's the big advantage?

element * /main/mybranch/LATEST
element * /main/{STATE=="BLESSED"} -time Monday -mkbranch mybranch

When a new version of the element is "BLESSED", the programmer's environment is not affected. The codebase doesn't change from out underneath the programmer. By using attributes instead of labels, you solve many of the problems you had with labels.

So, I lied!

The above isn't entirely true. The way I defined the attributes can land me in a lot of trouble. For example, I use a single attribute to define the various states of an element version. What would happen if last week's version of a file went from being merely "BLESSED" to being approved for use in the QC lab? Suppose that the current "BLESSED" version fails, and I want to return to the previously "BLESSED" version. Instead of going to the previously "BLESSED" version (which now has the attribute of "QC"), ClearCase will select an older version of the file. In fact, if my BLESSED versions are approved for QC, who knows how old a version of the element will be found!

So, using attributes in the way described above will land you in hot water. However, the whole exercise was to demonstrate how Attributes could be used. You can use attributes in the above situation, but not really as shown. One way to handle this problem is to use Integer value for Attributes:

Using Attributes for Defining Build Versions
Attribute Value
Integer Value
FAILED 0 Version has failed testing, and will be sent back to the programmer to be fixed.
BLESSED 1 This version of the element is ready for the next big build.
QC 2 This version of the element has been approved for use by the QC department.
ILAB 3 This version of the element has been approved for use by the Integration lab.
APPROVED 4 Version has been approved for release and will now be labeled as a release.

Now, the Build Manager can do the build using the following ConfigSpec:

element * /main/{STATE>=1}

This assumes that anything already approved for QC, the Integration Lab, or for actual release is okay to build with if it is the latest revision off of the main branch (Which is a darn good assumption).

A couple of people have told me that they prefer not to use integer attributes because in certain cases it can cause a developer's environment to change or to pull up a wrong version if you use the -time specification. Instead of using a single numeric attribute called STATE, they define several STATE attributes, and then put the attribute onto the version. So, one version might have the attribute BLESSED, QC, and ILAB on it. Using this method, the value of the attribute doesn't really matter, all you are looking for is that there is an attribute of that type on it. In this case, the configspec will look something like this:

element * /main/attype(BLESSED>

Personally, I don't think it has the elegance that the numeric STATE attribute has. (The idea that if a version is approved for QC, and it is a later version that whatever is blessed, then use the QC version). However, it does what it is suppose to do, and that is more than I can say about a lot of things in the computer world. Actually, if your STATES are not sequencial, using separate attributes for the various states is probably a better idea anyway.

Hyperlink Types

Hyperlinks are the stangest of the Object types. Using Hyperlinks, you can link one version of an element to another. Not only that, but you can use hyperlinks to point from almost any object type to another. ClearCase uses Hyperlinks to track Globally defined types. First of all, to even use Global definitions of Object Types, you create a hyperlink AdminVOB from one VOB to the Administration VOB where the Global definitions live. Then when you actually invoke a Global definition, ClearCase links the Globally defined Object Type to the locally defined object type with the GlobalDefinition Hyperlink. A pretty neat trick.

The classic use of Hyperlinks is to point from one version of an element to the supporting documentation. If someone checks out a library definition, then the trigger could also force a checkout of the corresponding documentation, and refuse to check in the library definition until the corresponding documentation has been updated.

One site used Hyperlinks to keep a rolling set of Release Notes. All files point to their release notes. When someone checks in a file, the check in description was automatically added to the Release Notes.

However, Hyperlinks can do more than just link files to documentation. ClearCase on Unix has a hard time with hard links. So much so, that most sites refuse to support them (using only symbolic links instead). The hard link count in a VOB is always "1" even if there are multiple hardlinks. Also, hardlinks have some very strange side effects. When a hardlink is checked out, the other hard links simply disappear. Not having any way to document hardlinks can make things difficult.

However, sometimes you must use hardlinks because of the way the underlying software works. In this case, you can use a hyperlinks to point to all the various hardlinks. A cleartool find will document all hardlinks, and a cleartool describe will show which files are hardlinked together. Word of warning though: if you use this method, you should use the "from" and "to" text to place the name of the hard link in the hyperlink because the cleartool describe command confuses the names of the hardlinks.

Server, Client files

Above, I talked about how Attributes can be used to find which files belong in a server release, which files belong in a client release, and which files belong in both types of releases. Attributes have a limit on being able to do this, though. You do this by placing the attribute "ReleaseType" on the element (and not a version). This allows you to use the cleartool find command to pull up all elements where ReleaseType == "Client". However, you cannot pull up this information using the ConfigSpec. To get around this problem, I used a check in trigger that would copy the attribute from the element to the version. Then I could do something like this:

element * /main/{RelType=="CLIENT"}

Someone on the ClearCase International Users Group wrote back and asked me why not simply use hyperlinks? In this case, you would define two hyperlinks. Call one ClientRel and another ServerRel. Place the hyperlinks on the version to be released. Make sure that these hyperlinks point to something, even if it is a circular link back to itself. When a new version of the element is made, the hyperlink is automatically inherited by the new version, and there is no need to define a trigger to do this task like I did with attributes.

Element Types

I have visited many ClearCase sites. Some are quite sophisticated with dozens of defined triggers, attributes, processes, etc. However, most of these sites simply don't define their own Element Types. This is a pity because Element Types work so well with triggers. By defining various element types, you can then hone your triggers to only fire on certain element types. For example, C and C++ header files should contain some fairly simple code to make sure that they aren't included more than once in a program. If you knew which files were C and C++ header files, you could enforce this provision via a trigger.

When you create an element using the mkelem command, ClearCase examines the ClearCase magic file to see if it can automatically guess the element type. I prefer to copyt the ccmagic file to the ClearCase Administrator's $HOME/magic directory and change the $MAGIC_PATH environmental variable to point to my copy. That way, you can modify the ccmagic file without worrying whether a new version of ClearCase will erase your work. Look through the ccmagic file, and get an idea of what element types you want to define based upon your SCM rules. The more you define, the finer control you have with your SCM rules, but the harder it is to maintain.

Also add to the ccmagic file any file suffixes that you use. For example, if your configuration text files all end in *.cf, then at least define *.cf to be an element type text_file. If you use Perl, add in Perl file definitions. Once you've defined what you've want, start defining some element types to help you group your triggers.

Once you have done that, a user should be able to use the mkelem command without the -eltype parameter. IMPORTANT: since element types now figure heavily in your use of triggers, it is possible that users can get around the trigger by changing element types. To plug this security hole, I recommend that you place a trigger on the mkelem command and the chtype command. I usually have a mail sent to me whenever someone does a mkelem or a chtype command.

Branch Types

Branch Types were discussed in the Branching Strategy section of this Web page, so there is not really a need to go into great detail about branching here. However, I do want to mention a few things:

Should I use Globally Defined Object Types?

Each VOB in ClearCase uses it's own database of the various defined types. Before ClearCase 3.0, you had to define each type you want to use in each VOB. Most sites used custom shell scripts to do this task. Under ClearCase 3.0, however, all object types can be either Global or Local. If you use Globally defined object types, all types are defined in an AdminVOB. If you attempt to attach an instance of an undefined type, ClearCase looks at the AdminVOB link to see where the AdminVOB of the current VOB is located. If there is an AdminVOB associated for that VOB, ClearCase checks to see if the type is already defined in the AdminVOB, if it is, ClearCase copies the definition to the current VOB and adds a GlobalDefinition hyperlink back to the original definition.

Because of the way Global Defined Object Types are defined, there are certain restrictions that ClearCase places on manipulating them. The biggest is the inability to rename them. A script called rename_type exists to handle this task, but .