|
Using ClearCase
ClearCase lingo demystified
Print Version
General Considerations on ClearCase terminology
ClearCase is a tool for controlling versions of software and document
files ( http://en.wikipedia.org/wiki/Rational_ClearCase).
There are many such tools, some open source and free, but
ClearCase has a special advantage of using a proprietary file system
for storage and maintenance of files and associated meta data.
On the surface, when you work in ClearCase, your Unix
commands and applications work the same as if you worked on the native
file system. Actually almost the same... Some applications that
use kernel low level file operations may have problems, similar to the
problems of working on the remote file systems, like NFS.
A practical example comes from Apache Web Server. When you are
serving documents/images from the directory under ClearCase
view you need to set the EnableSendFile to Off to
disable an efficient but raw file access. However, situations like
that are very rare, and traditional libc based file access
works fine.
This write-up assumes Base ClearCase on Unix/Linux. I do not discuss
anything about other OSes that ClearCase runs on. This is written for
people who use ClearCase now, but they do not know what they are doing
and they are tired of this feeling. It is not a tutorial on ClearCase.
If you know what you are doing, read no more and do not waste time...
I will also not deal here with UCM (Unified Change Management),
the derived objects
(i.e., using the UNIX-type make in the ClearCase), with
distributed ClearCase installations (i.e., when files reside
on different machines that may or may not be on-line all the time)
and with snapshot views. This will not teach you much
if you do not already use the ClearCase. There are books, read them to
get the knowledge. My goal here is to explain the basic terms
used in ClearCase that represent simple concepts but are so overblown
with a mystique of ClearCase (which is: the greatest thing
since sliced bread, obviously) that they prevent a rational person
to understand what is happening.
Note, I really dislike ClearCase since it wasted a lot of my time.
The terminology is not intuitive and
it is confusing. They tried to create newspeak for secretaries or
lawyers who will keep versions of their memos under ClearCase. They forgot
that ClearCase is primarily used by programmers, forced to use it by
corporate policies. These folks are usually familiar
with object oriented technologies and had to write a few topology routines
to get a passing grade for Computer Science 101. I am not sure what
they were thinking creating this lingo.
Probably they wanted to convince us that they created something so new
that no other mortal had ever come close to thinking about -- a version
control. The terms like Mastership of the label type
(i.e., who owns and can change the label) just make you wonder...
Since ClearCase also runs on Windoz, maybe they wanted to use the
successful marketing policies... You get stuck...
Set PATH to ClearCase commands
Before you can use ClearCase, you need to set your PATH
environment variable to contain the directories where the ClearCase
commands and macros reside. This is installation dependent, though
a default directory where the ClearCase commands reside is usually
/usr/atria/bin. So you should have something like:
PATH=/usr/atria/bin:${PATH}
export PATH
in your ~/.bashrc (if you are using bash shell) or
in your ~/bin/kshinit (if you are Korn shell aficionado) or
something like:
set path = ( /usr/atria/bin $path )
in your ~/.cshrc file if you are too lazy to learn a decent
shell and you are still using the C shell.
There may be more directories to place in the PATH that
contain additional utilities, scripts or macros. Some of them may be
actually placed under the /vobs directory to make them available
only when you are in the ClearCase view. Your ClearCase
administrator should tell you all about it, and also add you to the
ClearCase Unix group(s) to allow you to access files. You will also be
most likely asked to put some aliases into your UNIX rc
files, like:
alias ct="cleartool"
to type something like: ct command rather than
cleartool command .
Reading the ClearCase man pages (i.e., using
ct man command_name command) is actually waste of time if you
do not know the confusing terminology. To understand ClearCase better
you may refer to some links that I found quite useful:
http://clearcase.weintraubworld.net/,
http://acme.bradapp.net/,
and
http://www.samecs.com/how_do_i/ClearCase_VOBs/
ClearCase%20VOBs%20how%20do%20I.htm#_Scripts_and_utilities. I could list here a few
pointers to the the IBM site, and there are some very useful documents there,
but they use this lingo of theirs and before you go there, you need to know
what they mean. But stay with me for a while before you start clicking
and googling...
You will need to make at least two iterations when reading this brain dump,
since the terms are so interdependent that I could not find a way to
do it the A -> B -> C... way. Sorry...
I will use some typical abbreviations below. For example, the
ClearCase commands are usually executed by typing:
cleartool some_command. I usually abbreviate it as
ct some_command since I have the alias ct="cleartool"
in my .bashrc to save on typing. Most users of ClearCase
have the same alias set for them.
What is Type (what is hype?)
The popular task in ClearCase is first to make a type
of something and then to use the something. Luckily some
basic element types are already pre-made in ClearCase.
But other objects require you to make types first.
For example,
you first create a label type and then assign the label
to the element version. I think that what the creators of the
newspeak did here is renamed terms from object oriented
design. The type of something is a Class, i.e., the
prescription of how to construct something, while
something is an Object constructed from the Class. In this
context, the label type will be the Class describing how
to construct the label, while label is an object
created from the Class label type. Similarly a
branch type is a Class, that is a construction blueprint for
a branch, while branch is just an instance of
the given branch type (i.e., an Object). Of course, IMHO, all this is
pure hype and even using Object Oriented Programming terms is not
needed. A label is just a string that you associate
with the element version and a branch is a
directory (or a link to it) on the VOB where you put subsequent
element versions. And the element is just a file
or directory. They just created
Abstract Universe and a new New Paradigm out of
the Scrapbook. The learning curve is steep for no good reason.
There is a nice write-up on the types in
http://clearcase.weintraubworld.net/cc.objects.html
from where I borrowed the table below and replaced English with my own rendition
of it. Basically, for most types you have a mk*type command
and a corresponding command that attaches it to some other object:
Make Type
Command
|
Attach
Command
|
Comment |
mklbtype |
mklabel |
Labels are used to mark a particular version of the
element (e.g., file or directory). The most common use for
them is to mark a set of particular versions
of files and directories that represent a snapshot of a project
at some milestone (e.g., a release). Since you are not
allowed to assign the same label to two different versions
of the same element, labels ensure that creation
of new versions of elements in the future does not
affect the set of versions marked with a label.
|
|
mkattype |
mkattr |
Attributes are the name/value pairs. The value can be of different types
(e.g., an integer, a string of characters or a boolean value TRUE/FALSE).
When you create an attribute type with a mkattype
command you need to specify what the values can be.
The attributes are very flexible and you can attach
them to essentially any object on the VOB,
i.e., to an element, to a particular element version,
to a branch, etc. You can use them to add some notes or assign
some property to the VOB object. You can use the
ClearCase ct find ... command and find the elements
that have certain attribute values. To tell you the truth,
I never used attributes directly.
|
|
mkhltype |
mkhlink |
Hyperlinks connect a VOB object to another
object. Obviously the two objects have to be of the
same kind before they can be hyperlinked. The merge
arrow is an example of the hyperlink of type Merge that
comes predefined with ClearCase. The hyperlinks
are logical associations. For example, you can link an element
version to a file that describes what has been done.
|
|
mkeltype |
mkelem or
chtype |
The element type represents a type of file that is created.
ClearCase comes with some eltypes predefined, like text_file
or directory. The element type is usually assigned to
the element automatically based on the magic file
that associates extensions of files with the type.
|
|
mkbrtype |
mkbranch |
The branch is a VOB object that collects
consecutive versions of the element. The main
branch is predefined in ClearCase. However, if you want to
create a new sub-branch, you need to first create it with the
mkbrtype command. This is done usually when you create a view
which will be placing new element versions on a specific
branch according to the rules in the
config spec file. Then the config spec file instructs
the ClearCase to use mkbranch command to assign the branch
to a version of an element. Now you see what I am talking
about... The lingo... This is double Dutch (sorry folks from The
Netherlands... I did not come up with this on my own...).
|
Basic Terms
I think that before you do anything with ClearCase you have to know
exactly what certain terms mean. This may help you to read
the man pages where these terms are used in a more or less
inconsistent way. I try to explain in plain language some of terms
below:
- object -- anything that is created and maintained
via ClearCase on its special file system called VOB.
- element -- ClearCase object that keeps track of
versions. There are several types of elements,
for example:
- file element -- a regular file, like a source code,
html page, zip file, etc.
- directory element -- a directory (or a folder in MS
newspeak).
There is no really symbolic link element, but there are
two kinds of symbolic links:
- private view storage links -- links that you created
with a plain Unix ln command. These do not require you
to check out the directory in which they are created but they
are private and will not be propagated to the release view and
will not be visible outside your view.
- ClearCase links -- that you create with the
ClearCase ct ln ... old_entry link_name command.
Before you create a ClearCase link you will need to
check out the directory in which the link is being
created. Such links are part of the directory
element type and once the directory is checked in
they are visible outside your view, i.e., they are no
longer view private. However, the ClearCase links
are not elements. They cannot have labels attached
and cannot be modified. If you need to modify the
ClearCase link, you need to check out the
directory, remove the link ( ct rmname ... link_name ),
create a new link
( ct ln ... some_entry link_name )
and check in the directory.
The ClearCase hyperlinks are no links... They are more like
annotations of other objects.
Of course, element is an instance of an element type.
Luckily, the element type (eltype) is usually set
automatically when you make an element with a
ct mkelem ... or ct mkdir ... commands, since
ClearCase comes with a set of popular element types.
When you create an element (i.e., create an empty file or
an empty directory) the ClearCase puts it on the main
branch. Only after an empty element is created
(made), i.e., only after a mechanics for keeping
versions is in place, you can start putting stuff
into elements. By putting stuff I mean, putting text
into an empty file or adding files/links to a directory.
Moreover, you can specify the eltype when using the mkelem
command with an option: ct mkelem -eltype your_type ... somename
if you do not like the automatic assignments. You can also change
the eltype after the element was created with
a ct chtype ... command if you discovered with the
ct describe somename command that the automatic assignment
is not adequate.
A file element can be a simple text file
(eltype="text_file") or a directory
(eltype="directory"). There are more eltypes:
eltype="binary_delta_file",
eltype="compressed_file",
eltype="html",
eltype="ms_word" and
eltype="xml" that come with the ClearCase. Moreover,
you can create your own, if you are a brave type.
What types are available on your system
can be listed with a ct lstype -kind eltype command
(as you can see, they also have kinds of types).
The eltypes are important if you create derived objects and
use clearmake
(e.g., for compiling a source code and creating executables or libraries).
The elements can have many versions. They are stored
on a special file system called VOB. Not all files and
directories that you see in the ClearCase view
need to be elements
You can create files and directories that are not elements
and whose versions are not tracked. To make something an element,
you have to create it first with a specific ClearCase command
(e.g.: ct mkelem ... somefile or ct mkdir ... somedir).
You are free to create files and directories on the VOB file system
under ClearCase with standard UNIX commands without making them
elements,
but they will not be easily accessible to other users of the system and
will not have their version maintained. These are called
private view storage and are accessible only through the
view in which they were created. Moreover, these
non-element entries will not be copied to the release
branch when you are merging.
Consider them your private, scratch objects that
are supposed to go away and you do not intend to share them with
others (like editor backup files or object files before you put them into
a library). You can convert the view private file to
an element by using the
ct mkelem -ci existing_private_file provided that you
are creating a new element. However, you cannot use
this approach with the view private directory. The easy
way is just to rename the view private directory to
something else with the plain Unix mv thisdir newdir
then create ClearCase directory element (ct mkdir thisdir),
and then, if the view private directory contained files,
copy them to the thisdir (i.e.: cp newdir/* thisdir),
and finally create elements from these files with mkelem
as described above. Of course, you can do a one-liner out of this
using find, but I do not want to brag about my shell skills.
- version -- an object that keeps information
about a particular revision of an element.
A version of the element is not just
a file with a specific revision of the content of the element
(like file with data, a source code, file names in the directory, etc.),
but it is a list of differences against a previous version
of the element. All element versions form
a topological
tree (version tree) and contain information from subsequent
checkout and checkin operations.
For this reason, removing an element
version is not a straightforward task (imagine breaking a
branch of a tree that can affect other smaller
branches that grow out of it), and you need to understand
the difference between removing a version of an element,
and removing an element (i.e., all versions). You actually
should avoid removing the element or its version
unless you do it immediately after creating it (i.e., when they
have no children). Again, imagine what would happen if you removed
some far ancestor from your family tree though removing a newborn
is not a big deal. [ So you know that I know: A family tree
is not really a topological tree
since there are two roots and there may be cycles
through incest -- some linguist or artist
must have come up with the name ]. If you want to change the name
of the element, rename it (i.e., ct mv ... ... )
rather than remove (i.e., ct rmelem ... ).
But I prefer to use the remove name command
(ct rmname) which is safe and can be undone.
More about it later. When you use the ct mkelem
command, you create an element that is empty. This is
version 0. The ct mkelem also automatically
checks out the element so you can edit it (or copy some
file into it). Then you checkin the element and create
version 1. There are options to ct mkelem command
that let you automatically put stuff into it and check in.
RTFM, or ct man mkelem...
When you checked out a file and edited
it, you did not actually modified the version
of the element but you worked on a temporary file (that was
created in the private view storage). This temporary
file was initially just a copy of the element
version (usually the last version).
Then, when you check in the element
(i.e., create a version n+1)
you are not saving the temporary file, but save the differences
between the temporary file and the parent version n.
This diff representation of element
versions was done (most likely) to conserve
the disk space and allow for fast comparison between versions.
I personally believe that it may have been a good idea
when the ClearCase was conceived in 1992, but it is a bad idea now, since
it unnecessarily complicates the operations and it is a legacy
ballast. But what do I know? Maybe it is better and faster than the
brute force. Sorry if I kicked the sacred cow...
These element versions
are saved on branches in the VOB which is
discussed next.
- branch and branch type -- I have seen most
ridiculous definitions of this term. The official one is:
branch is an object that specifies
a linear sequence of versions of an element.
In my opinion a branch should have been named
path (which has a well defined meaning in topology and would
associated with directory path)
and since branch has a name, it should be called
a named path.
With time passing and work progressing, an element has a number of
versions. Each version (beside the version 0)
has a parent and
only one parent. Even if you merge two (or more)
versions
of an element, you use the target version
as a parent and create differences with the
other versions, and save these differences
as a LATEST version, i.e., child
(actually this is more involved
and will be described under merging).
Hence, versions of each element
form a topological tree. There is only one topological path
that connects any two versions of the element even
if they are very far apart in the tree.
The element versions are nodes on this tree.
These nodes (or vertices of the graph)
are connected with edges. The path (i.e., branch
in the ClearCase newspeak) is a continuous trace through the
neighboring nodes (versions
of the element) of the graph.
What is most confusing in the ClearCase diagrams is that this
special type of graph called a tree is drawn
upside-down. Its root node is drawn at the top
rather than at the bottom of the tree. In topology
the root of the tree is drawn at the bottom of
the picture since this is where the roots of real trees usually
are.
In case of ClearCase the element version
tree starts with an empty root element
that starts the main trunk.
This is version 0 on the main branch.
Customary, in graph theory such node of the tree
is drawn at the bottom (like in a real tree).
From the main trunk
(main branch in ClearCase speak) we can grow additional
branches. Note that there are many possible choices
for the path that we can call a trunk but in our
ClearCase case, the main branch (i.e., trunk)
is main because this is a default name that ClearCase
chooses for it.
On the pic above you see branches as blue vertical lines,
element version is given as a number in a circle,
the event of the creation of the new branch is depicted
as a rusty arrow, and the directory names on the VOB
that correspond to branches are written vertically, parallel
to branches.
Each element version (beside version 0)
has only one parent on the branch, it
can have one child on this branch
unless it is the LATEST version on this branch.
Numbering of versions starts from version 0.
That is, the non-root element version (a node) on the
main branch will have one parent, but
may have zero or more children. However, out of the
children only one can be on the same branch with
the parent and other children have to be on other
branches.
Some children may be created via branching and
start a new sub-branch. The particular version
can only have one or zero children that are on the
same branch ( the LATEST version on the given
branch has no children unless we branched from
it). While these lengthy
considerations of the obvious seem to be an overkill here, I noticed
that many people did not give these things enough thought.
So, by branch I understand a named history of the
particular element, on this branch.
It is a list that starts at the version 0 of the element
when the branch was created
and ends with the latest version of the element.
The branches are named (and saved) in the UNIX like directories
so there is no confusion here. You can look at branches
like they were
directories where the consecutive versions are stored.
They will be seen as files: 0, 1, 2, ... LATEST.
As an exercise, assume that you are a user jkl and you are in
some view (in this case jkl_koolapp_3.0.2
of some application that we call here koolapp,
and you want to do listing of a file conf_ap.pl
ls -l conf_app.pl
-r-xr-xr-x 1 jkl ccusrs 23696 Jun 23 10:17 conf_app.pl
Which version of the file is actually shown to you or the Unix
applications is hard to say from this line, since we do not know the
config spec for the jkl_koolapp_3.0.2 view.
There is a clue, however, that this file is a checked in
element, since it is read only.
Now, still using the plain UNIX ls command,
one can list the labels and branches for this file by
using the extended ClearCase file naming. Let us start from
ls -l conf_app.pl@@/. # ls -l conf_app.pl@@ would print the same
total 52
-r-xr-xr-x 1 jkl ccusrs 124 Dec 10 2008 KOOLAPP_3.0.0
-r-xr-xr-x 1 jkl ccusrs 23696 Jun 23 10:17 KOOLAPP_3.0.1
dr-xr-xr-x 8 jkl ccusrs 0 Nov 4 2008 main
You see that there are versions of this file that have
labels attached (labels are by convention UPPERCASE
but can be anything if you choose so, but they cannot conflict
with branch names).
There is also a directory that corresponds to the
branch main.
Let us see what is under main branch:
ls -l conf_app.pl@@/main
total 147
-r-xr-xr-x 1 jkl ccusrs 0 Nov 4 2008 0
-r-xr-xr-x 1 jkl ccusrs 124 Dec 10 2008 1
-r-xr-xr-x 1 jkl ccusrs 23696 Jun 23 10:17 2
-r-xr-xr-x 1 jkl ccusrs 23696 Jun 23 10:17 LATEST
-r-xr-xr-x 1 jkl ccusrs 124 Dec 10 2008 KOOLAPP_3.0.0
-r-xr-xr-x 1 jkl ccusrs 23696 Jun 23 10:17 KOOLAPP_3.0.1
dr-xr-xr-x 2 jkl ccusrs 0 Nov 4 2008 jkl_koolapp_2.2.5
dr-xr-xr-x 2 jkl ccusrs 0 Apr 15 14:22 jkl_koolapp_3.0.1
dr-xr-xr-x 2 jkl ccusrs 0 Nov 14 2008 koolapp_2.2.4
dr-xr-xr-x 2 jkl ccusrs 0 Nov 14 2008 koolapp_2.2.6
dr-xr-xr-x 2 jkl ccusrs 0 Apr 21 16:31 koolapp_3.0.1
There are 4 versions of this file under main branch:
0, 1, 2, and LATEST. The LATEST
corresponds to the latest version, i.e., 2.
The zero length version (version 0)
was the 1st empty version of the file. It was
created with a ct mkelem ... conf_app.pl command.
Then there is a very
short version 1 (only 124 bytes long).
There is a version 2
created on June 23 that is 23696 bytes long. The
version 2 is also the LATEST version on the
main branch. The directories represent
sub-branches under main branch.
For a given element, only these branches are
listed that are associated with this element.
The 1st sub-branch for element conf_app.pl
was created on Nov 4 2008. This was most likely the view
in which the ct mkelem ... conf_app.pl was issued
since by convention sub-branch names are often the same as
private view names of developers. Why not check?
ls -l conf_app.pl@@/main/jkl_koolapp_2.2.5
total 2
-r-xr-xr-x 1 jkl ccusrs 0 Nov 4 2008 0
-r-xr-xr-x 1 jkl ccusrs 124 Nov 14 2008 1
-r-xr-xr-x 1 jkl ccusrs 124 Nov 14 2008 LATEST
Seems that this is a case. Remember also that we are in the
jkl_koolapp_3.0.2 view and the sub-branch
main/koolapp_3.0.2 is not present. One may infer that
there were no changes (no check outs and check ins) of
this file in this view. At the same time, it is interesting
to look under the last branch that the element is
listed, to see some history:
ls -l conf_app.pl@@/main/koolapp_3.0.1
total 303
-r-xr-xr-x 1 jkl ccusrs 124 Apr 21 16:31 0
-r-xr-xr-x 1 jkl ccusrs 16181 Apr 21 16:33 1
-r-xr-xr-x 1 jkl ccusrs 18426 Apr 23 14:48 2
-r-xr-xr-x 1 jkl ccusrs 23532 Apr 27 13:28 3
-r-xr-xr-x 1 jkl ccusrs 23597 Apr 27 16:55 4
-r-xr-xr-x 1 jkl ccusrs 23596 May 6 15:02 5
-r-xr-xr-x 1 jkl ccusrs 23696 Jun 9 16:37 6
-r-xr-xr-x 1 jkl ccusrs 23696 Jun 9 16:37 LATEST
Hopefully by now we know and understand the ClearCase extended notation. For
example
- conf_app.pl@@/KOOLAPP_3.0.0 -- refers to the version
that was labeled with KOOLAPP_3.0.0 (now you see why
labels cannot be the same as branch names),
- conf_app.pl@@/main/2 -- a 2nd version on the
main branch,
- conf_app.pl@@/main/jkl_koolapp_3.0.1/LATEST -- the last
version (i.e., here, version 6) that was created on
the /main/jkl_koolapp_3.0.1 sub-branch,
Note that above we used a plain Unix ls command with
these extended names. We could also use other Unix commands with them,
say:
diff conf_app.pl@@/main/koolapp_3.0.1/3 conf_app.pl@@KOOLAPP_3.0.0
to find differences between version 3 on the
koolapp_3.0.1 sub-branch and the version
with a label KOOLAPP_3.0.0.
Of course, you could get all this information and much more if you
just ran the ClearCase lshistory command on this element,
say: ct lshistory conf_ap.pl. It would show you when this thing was
created and merged with many, many lines like:
...
--05-06T15:02 jkl create version "conf_ap.pl@@/main/koolapp_3.0.1/5"
...
--11-04T13:21 jkl create version "conf_ap.pl@@/main/0"
--11-04T13:21 jkl create branch "conf_ap.pl@@/main"
...
together with the comments that were entered when the file was
checked in (i.e., when the new version was created).
The strange thing in the first column is date/time. Normally it would be:
YYYY-MM-DDTHH:MM:SS but to make is shorter we can skip
things. If the date refers to time less than a year, we can put a hyphen
for a year (i.e.: -). Often, for date/time more than a year in
the past, we just use YYYY-MM-DD, that is skip the time.
The ClearCase command ct ls -l conf_apache.pl will tell you
how the element was selected and which config spec
rule was used to show this particular version:
ct ls -l conf_ap.pl
version conf_ap.pl@@/main/2
Rule: element * /main/LATEST -mkbranch jkl_koolapp_3.0.2
After this exercise, you will notice that branches could
also be represented as a tree
(like a directory tree in the textbooks on UNIX).
Each branch has only one parent, except the main
branch that does not have a parent, i.e., is
a root of the tree.
The term sub-branch is again a ClearCase newspeak. It is just
a sub-path.
The sub-branch is a branch that is created
in the process of branching. It starts at some particular
version of the element on the parent
branch. The sub-branch will
also start from the version 0 that will be nothing else but
a copy of the element version on the parent
branch where the branching occurred.
The best definition of the branch that I found is
[ Here ], namely:
Rational ClearCase uses branches to organize the different versions
of files, directories and objects that are placed under version control.
A branch is an object that specifies a linear sequence of versions of
an element.
The entire set of an element's versions is called a version tree.
By default, Rational ClearCase provides for every single element in
a VOB one principal branch, called the main branch. This main branch
may also have sub-branches.
A branch type is a type object that is used to identify a parallel
line of development for an element. Each branch in an element's
version tree is an instance of a branch type that exists in that
element's VOB.
Unfortunately, we are not yet over with these trivia. What about
naming of branches? The main branch of the
element is just called main by ClearCase. If you start a
sub-branch by branching at some version of the
element you can call it jan_sub_branch_a. The full name
of this sub-branch will be /main/jan_sub_branch_a.
Can you create another sub-branch with this particular
name that starts at some other version of
the element on the main branch?.
No, you cannot!!! The full name of each
branch for a given element has to be unique.
Not only this, but the name of each branch has to be
also unique (actually it does not, and you can use option pbranch
with the mkbrtype ClearCase command, but you usually should not...)
You cannot have /main/main branch since the ellipses
( ... ) in config spec would be
confused.
You cannot have two /main/jan_sub_branch_a branches
for the given element. Last, you cannot have
the /main/jan_sub_branch_a and the
/main/jan_sub_branch_a/jan_sub_branch_a branches.
since the ellipses ( ... ) in
config spec would be confused. But if you have several
elements (say, source files)? Can you assign the same
branch names to them? Sure, you can!!! Not only
that you can, but this is the blood of ClearCase! You do want to keep the
branch names for related elements (e.g., elements
that comprise a development project) the same, so you can preserve
your sanity. By using this convention, you can keep versions
of related elements together via their branch
naming. Later you can choose to look only on the elements
whose versions reside on a specific branch name.
- VOB -- Versioned Object Base. Maybe it is called this
way since the database is involved.
I would just call it a VOFS, a Versioned
Object File System, but then it would loose its mystique.
In my opinion the VOB is a special file
system suitable for storing element versions,
branch information, the data
about relations between versions, their history, labels,
and annotations/meta-data (added automatically or created by the user).
In fact, the VOB stores other things too. The VOB supports
selection of particular versions of elements
via a mechanism of view. The view is a filtering
mechanism that shows particular versions based on the
rules provided in the config spec file.
- view -- what you see... -- a selection of specific
versions
of elements done according to a set of rules.
When you are in a view you see a regular
UNIX file system, with regular file names. Yet, while there may be
ten different versions of the file myprogram.c in the
VOB, you will only see one file.
The view is a ClearCase object since it requires
that the ClearCase finds the rules that are associated with the
view. You cannot have two different views with the
same name within a VOB. Since the names for views
have to be unique they have to be rational and logical, otherwise
you will wear yourself quickly.
The view usually contains many files, directories, and links.
The view name is often called a view tag.
What is shown to UNIX commands within a view depends on
rules.
For example, the view may represent a collection
of latest versions of the elements or the
last versions of elements
that were created on or before a given date. It can also be a
set of element versions that are associated with
a specific label. Last but not least, the elements
can have attributes (name/value pairs) assigned
and you may want to see only these elements whose
attributes satisfy certain condition.
The view is a collection of
particular revisions of the elements and it feels like
a regular UNIX file system. You just see individual files and
directories. However, you are actually looking at specific
versions of each element without a clutter of
version numbers, branches, element
labels, annotations and attributes
(meta data).
But ClearCase let you see these things if you need them and has
commands to list them either via commandline or
by using ClearCase GUI interface.
The selection of versions that you see is based on a set of
rules that are collected in a config spec file.
When you create a view, you are actually creating
a config spec file and you are associating it with your
view tag. Moreover, you can edit/change
the config spec file for the given view (that you
created -- only owner can change the config spec file)
and your view will change, even if you did not change
any elements -- you are just seeing different versions
of elements. Note: I saw a lot of pictures that represent some
projections and screens, transparent planes and dashed lines, the
arrows straight and broken and objects and so on...
These figures are usually highly confusing and probably they convey
some information for managers since it is often an impressive
art work and looks very complicated. For a programmer, you need
to know that a view is a selection of specific versions
of elements (one version per element) that is done
according to rules that you set. Looking at these overstuffed pictures
will only confuse you, so you pay for training where they tell you
in plain language what it really is. However, I like this figure:
that represents a view that is composed of latest
versions
of four elements: start.c, utillib.h,
utillib.c and errmsg.lst on their branches
called main. It shows four branches
associated with these elements and the versions
available. You see labels (V1.0.1 and V1.0.2)
attached to versions of the elements and the
version numbers in circles. The thick dotted line connects
last versions of these elements: 4, 3, 2
and 4; respectively. You often hear the statement:
"the LATEST versions
of elements on a branch main".
Again this is a wrongly worded but popular statement. Wrong, because
branch belongs to the element, not the other way
around. However, since we assign the same name to the branches
collecting versions of related elements, this is
a convenient shortcut.
The picture below represents a view
of the elements versions that were marked with
a specific label, namely V1.0.1.
You can indeed mark specific element versions with
a specific label and then refer to these versions
by using a label. While the development continues, new
versions are being created, but the label stays
attached to the version to which it was originally applied.
The thick line connecting these element
versions is often called baseline. The picture below
shows a view in which the elements shown are those
marked with a label V1.0.2. Note that "a given version
of an element may have many different labels attached
but there may not be two different versions of an
element that are marked with the same label".
When you are in the view, you need to change directory to be
under Clear Case VOB mount point. The VOB
is usually mounted as /vobs and under this top directory
there are subdirectories representing projects or development areas.
For example, a top directory of your project could be something like:
/vobs/interfaces/user_form. The files/directories that you see
under this directory are the ones that were selected by the rules
for your current view. You can also look at the files that
are selected by some other view by using the view
extended pathname. The top directory for views
is usually /view. You would find the files for a given view
under: /view/view_name/vobs/interfaces/user_form. For
example, if view name (or tag in ClearCase
speak) was form_v.2.3.5, the files selected
by this view would reside under:
/view/form_v.2.3.5/vobs/interfaces/user_form.
View Private Storage:.
The stuff that the view shows is not only the
ClearCase elements but also regular files, directories or links
that are not elements, i.e. those that were not created
with the ct mkelem ..., ct mkdir or
ct ln ... commands, but with the regular UNIX commands like
vi ..., mkdir ... or ln ....
These are files, directories and links in the
view private storage. These private things will
be seen only when someone is in the view (i.e.,
used the ct setview view_name command) or lists
the file as ls -l /view/some_view_name/vobs/....
You will not be able to access these private files via the
branch and version location, like:
ls -l my_private_file@@/main/3 since they do not have
a branch and version associated. The files that
are CHECKEDOUT are also within the view private storage
but you can actually see them associated with the branch if you
do something like:
ls -l utilitylib.c@@/main/jkl_koolapp_3.0.2/CHECKEDOUT
(i.e., when you give the CHECKEDOUT as a
version number). For a file in view private storage
you cannot use the @@/ ClearCase extended file naming.
For example, if you have a private file called junk,
the
ls -l junk
-rw-rw-r-- 1 jkl deptXXX 134 Jun 25 08:18 junk
but
ls -l junk@@
junk@@: No such file or directory
- checkout -- an act of preparing element for revision.
The specific element version that is stored
on the VOB is read-only. You cannot change the
specific version of the element. However,
you can create a new version. To do this, you
checkout an element version (i.e., create
a temporary copy of it in the view private storage), edit it
and then assign a next version number to it by a process called
checkin. Depending on your ClearCase environment and
configuration, other people may or may not be able to work
on the version of the element that you
checkedout until
you perform a checkin. In our environment, we usually work
in our private development branches and we do not interfere
with other people private development branches.
We cannot, however, checkout the
given element version twice.
- checkin -- an act of assigning a version number
to the checked out version of the element
and making this version of the element readonly.
After you checked out a version of the element
(most likely the LATEST one), and edited it, you need to assign
a new version number to this element's revision.
Therefore checkin consists of saving the revised element
on the VOB as a read-only object,
assigning a specific version to it (usually just
a next version number), making an annotation
(the user is asked to enter comments,
or default comments are created) and making this element
viewable by other users via a ClearCase branch name, say
HelloWorld.c@@/main/john_fix_5/3.
- version label and label type
-- a particular version of an
element may have (but does not have to have) one or
more labels attached. The labels are used to mark
specific versions of elements. You should use
easy to remember name for a label and have some policy on
what the label represents. Before you can assign
a label to a version you need to create (make)
the label type with a ct mklbtype ... command.
Then you can attach the label to an element
version with a ct mklabel ... command.
The labels are
most often used to mark a specific set of elements
versions, e.g., to create a snapshot of the latest
revisions in the view. The labels
are rarely used for marking just a single element version.
You can use attribute for this.
For example, we can use a label like VER 1.2 to mark
a set of elements versions that corresponds
to some major issue of the software, here the release 1.2.
Since you cannot modify the specific version of the
element (you can only create a new version)
the set of element versions that was assigned
a specific label is guaranteed not to change (unless,
of course, you use the low-level ClearCase commands to reassign
or change the labels but under normal circumstances
this would be considered cheating).
When some time later you create a next version of
the labeled element version,
the version with a
given label does not change. You cannot assign the same
label to different versions of the
element. Remember: a given element version
may have many different labels attached, but no two
element versions may have the same label
attached. Yes... different views may share a number
of identical versions of elements, namely,
those that were fine and did not need any modifications.
For this reason the most popular use for labels
is to mark releases, i.e., sets of elements
with specific versions.
Note: label cannot have the same name as
a branch name. You should also avoid using
an existing view name for the label, since
branch and view names are most often the same.
This would lead to ambiguities when rules in config spec
are interpreted, since in the selection rules, the text after
element specification is a branch or a label,
and there is no easy way to specify that it is one or the other.
There is a very useful suggestion to use consistently UPPERCASE
letters in the label NAMES and lowercase letters
for view and branch names. Making an easy
rule for label name (naming convention)
is critical to their utility. For example, if you used a popular practice
to make label name an UPPERCASE of the name of the
view that represents a release, for the
view named koolapp_3.0.1 the element
versions visible via this view should be
labeled as KOOLAPP_3.0.1.
- release -- a snapshot of a project at a given
stage of development. It is usually a view that
selects the set of elements versions
that represent a stable product.
Often the term baseline is used to
describe the release concept. In the figures above, the
dotted line was connecting the labeled element versions. This is
probably where the name came from. At some point
you want to take a set of particular versions of all
elements in your project
and create a view that represents some milestone
in development or an event (like something that has been
released to the customer or public, or something that underwent
QA testing). You want to make sure that this collection of elements
versions will not change even when new versions
of elements are created in the future.
This is usually done by assigning a unique label
to the respective versions of the elements
and then recalling these element versions by
their particular label and changing the config spec
appropriately. To preserve the view in its original shape,
you also prevent check outs in this release view
by editing a config spec file for this view.
For example, you may have the following lines in your
config spec for your release view:
element * KOOLAPP_3.0.1 -nocheckout
element * /main/LATEST -nocheckout
The first rule will pick up all elements with
a label KOOKAPP_3.0.2, but will prevent
check outs, while the
second rule will pick up LATEST elements on the
main branch that do not have a KOOKAPP_3.0.2
label attached (they most likely did not exist when this
view was labeled).
- main branch (sometimes called a
project branch) is often used as a definite term
but what it actually means and what versions are
associated with the main branch depends to a great extent on the
rules that are specified in the config spec file
for the views. In the config spec file
you can request that the particular branch is created
for the element when it is checked out.
Usually the branch name to be created on
check out is the same as a view name
to keep us sane.
On the other hand, when a new element
is created (with a ct mkelem ...
or ct mkdir ... command) the ClearCase by default creates
an empty element with the main branch
attached. If you create a new view, with a command like:
ct mkview -tag my_new_view /some/path/to/view/storage
the default config spec that is created is:
element * CHECKEDOUT
element * /main/LATEST
For most purposes, this default config spec is inadequate
for team work and is usually modified. It would be OK if you were
the only user of ClearCase. However, whatever the config spec
is, when you make a new element (i.e., run
ct mkelem ... or ct mkdir ...) in any
view, the empty element version 0
is always created with the default main branch
and automatically checked out.
You usually put something into this empty element and
do a check in and create version 1.
If the 1st rule above was not present,
you would not be able to edit the empty element since you
would not see it (the checked out elements would not
be visible). If the 2nd rule was not present, you
would not be able to edit the empty element,
since, again, you would not see the LATEST versions
of elements.
Even if the config spec provides for creating a new
branch at element check out, the
version 0 (i.e., empty version) is always
present on the main branch as a result of
the ct mkelem/mkdir commands.
This is necessary, since sub-branches for a given element
form a topological tree and the main branch is a root of this
tree. However, depending on details/rules
in config spec file,
new element versions may or may not be
automatically saved in the main branch. If several
developers work on the same project, the standard policy is to
have them create new versions of elements in their
private views on their private branches.
Only after they tested/reviewed their private versions,
they should merge them to the main view.
You often see the following rule in the config spec:
element * /main/LATEST
Some purists prefer (and there are good reasons for this sometimes):
element * /main/0
But in most cases the main
branch is used as a consensus branch,
i.e., it holds the LATEST (and greatest)
versions. This is also
a branch that by default provides a seed for all
sub-branches (i.e., private branches)
when the element does not have yet a sub-branch
associated and a developer checks out the element
on a given view for the first time. So for a private
view named jkl_koolapp_2.4.3 you may see in the
config spec rules like:
#-- Rule 0 unwritten: show regular files/dirs # Rule 0
element * CHECKEDOUT # Rule 1
element * .../jkl_koolapp_2.4.3/LATEST # Rule 2
element * /main/LATEST -mkbranch .../jkl_koolapp_2.4.3 # Rule 3
Note, these rules are filters applied to any file
and directory that you want to access with some UNIX command.
They are interpreted from top to bottom and the first matching rule
is executed.:
- Rule 0: -- if there is a file or directory in the
view private storage (i.e., a file or directory that is
not an element), show it. Note, this may lead to
masking out the elements that have the same name,
but it normally should not happen, unless you do some trickery
with the
config spec file assigned to your view.
- Rule 1: -- if there are any checked out
elements, show them before any others.
- Rule 2: -- if an element is not checked out
and has an associated
branch named jkl_koolapp_2.4.3 show the LATEST
version on this branch and do not even look at
the main branch. If the user checks out this
version of the element, do the following:
- create CHECKEDOUT copy of this version
in the view private storage,
- once it is edited and checked in assign
a version number: (LATEST + 1) to it,
- place this version on jkl_koolapp_2.4.3
branch.
- Rule 3 -- if an element is not checked out
(#1) and does not have a branch
jkl_koolapp_2.4.3 (#2) show the LATEST
version that is available on the main branch.
When a user checks out this LATEST main
version, perform branching operation, i.e.,
create a branch jkl_koolapp_2.4.3, place the copy
of the LATEST main version on the
jkl_koolapp_2.4.3 branch and mark it as
version 0 and then create a CHECKEDOUT copy
in the view private storage. Once user checks in the
edited version of the element save it as
version 1 on the branch jkl_koolapp_2.4.3.
What if this is a new file or directory element? Think about
it... You need to make them first, i.e., use a ct mkelem or
ct mkdir command. And what they do? They create an empty
version 0 on the main branch. And this
empty version 0 is your LATEST version
on the main branch.
Note: the above config spec DOES NOT CHANGE THE
main branch!!!. In this approach, the
work is done on developers' private branches and the
work is then
mergeed to the main branch manually,
once it was tested and judged to be ready for prime time.
The elements empty versions are always created on
the main branch when you use ct mkelem ... or
ct mkdir ... commands.
- merging -- a process of taking two or more versions
of a given element (contributors) and
creating a new version on some existing branch
(the branch that has a target contributor).
There are many options and modes of the ct merge ...
command, but you need to understand what is happening before you
can use them.
It is, in a sense, an opposite of branching (in branching
we place a copy of the version of an element from one
branch on some new sub-branch as version 0).
The ClearCase offers very nice facilities for merging and
they are very important in the situation when several people work
on the same project.
It often happens that two developers are working on the same
element in their own private views and then
they need to create a consensus version
of this element. The merging in ClearCase is
often done via macros/scripts written by the gurus that
work on a set of elements, e.g., two views,
a target view (say, a release) and
a private developer view, but you have to
realize that underneath this operation are merge
operations for each partaking element. There is also
a GUI Merge Manager (in Graphical ClearCase,
i.e., xclearcase) that will merge many elements.
Each merge
operation takes a number of versions, but typically two:
target contributor and a other contributor
and creates a new, consensus version of this element that
is placed on the branch where the target contributor
version resides. There are options that allow you to send
the merge results to a private file without creating a new
element version. However, in most cases
there is also a third, silent contributor called
a base contributor. The ClearCase will pick one
for you, though you can specify it explicitly via the command line option.
The base contributor is usually chosen by ClearCase
as a closest ancestor of the versions that are
merged. If the element versions do not
have a common ancestor (e.g., when you merge an
element that you created on your private branch
that has the same UNIX name/path as an element on the
main branch) you would have to approve all differences
between the merged contributors manually.
The actual algorithm for merging is quite
involved and described in the IBM manuals (e.g.,
Working in Base ClearCase) but for two files
being merged and with defaults taken, it looks like:
- check out the element version on the branch
that you want to have a merged result saved. This is
your target contributor.
- provide the target contributor to a merge
command with the -to command line option.
You need to provide the target contributor explicitly.
- specify other contributor (you can actually have up
to 15 contributors) as arguments to the merge
command (arguments follow the options).
The other contributors should be all
checked in.
- The ClearCase figures out what is the base
contributor. It is usually a closest common ancestor
of element version being merged.
You can also choose the base contributor via
-base command line option, provided that you know what
you are doing.
- The ClearCase reads the line from the base contributor
and compares it with the corresponding lines of the
contributors that you specified. The following cases can
happen:
- All three lines (i.e., line in the base,
target and the other contributors)
are the same and the line is copied to the
results of the merge,
- A line of one contributor is different than the line
in the base contributor. Lines in other
contributors are the same as the line in
the base contributor. This different line is
copied to the results of the merge,
- Lines of the target contributor and the
other contributors are all the same, but
different from the line of the base contributor.
The contributors line is copied to the merge
results, unless you requested to specifically ask for confirmation
of any changes to be done on the base contributor.
- Lines of target contributor and
other contributors are different (and may also
be different from the base contributor line).
The merge command asks you which line you want to
sent to the merge results.
- merge results replace the CHECKEDOUT version
of the target contributor, unless you specified
some other file for results with the -out option.
Of course, the details of the algorithm are more complex. But
the process is similar to the workings of the UNIX diff and
patch commands. Naturally, it is not done a line at a time
but the neighboring lines (a context) are also being checked.
The simple, but popular situation of merging from some
private developer's branch to the main
branch is depicted with the following pic:
On the picture, a user is merging changes made on the
sub-branch koolapp_2.3.5 with the LATEST
version of the myprog.c element (looks
like some C program source). On the picture the koolapp_2.3.5
branch for the element myprog.c was seeded
with the version 2 of the
main branch. Then the user was working hard on it
and created version 4. It seems that other people were working
on the myprog.c also, and they were merging their
changes to the main branch. The version 9 was the
LATEST version on the main branch.
User (or a script that was created for the user by the ClearCase
gurus) checks out the LATEST version
on main branch and wants to create a consensus
version and place it on the main branch as the
next good version. The base contributor
(usually a closest common ancestor,
whatever it means) in this case, is automatically determined by ClearCase
as a version 2 on the main branch, i.e., the
branching version for the sub-branch.
The results of merge
are saved as version 10 on the main branch and
becomes the LATEST version on this branch.
Note that the sub-branch koolapp_2.3.5 is not changed
after this particular merge action.
Please do not be mislead by the merge process. Even if it
completes without asking you a question, it does not mean that it
produced a sensible result. The decision which lines to sent
to the merge results is purely lexical. What these lines
actually do is not analyzed by ClearCase in any way. For example,
someone could have produced a lengthy fragment to find out what
is the latest address of Elvis and then, some other developer,
may have inserted 10 lines later a statement like:
Elvis_Address = "unknown";
and obliterate the precious code.
- config spec (cs) file -- an object associated with
a specific view that provides rules for selecting
element versions to be shown in this view.
Note: The config spec is only applied to elements,
i.e., things that have versions. The files and
directories in view private storage that are not elements
are always shown. The rules have a quite convoluted syntax
and learning them is a process.
Initially, you will rely on the default config spec file that
is created by macros provided by ClearCase gurus or a
default config spec file that is created by ClearCase itself
when you create a new view.
You can view the config spec file with a ct catcs
command. You can edit it by ct edcs command. Note, the
ct edcs command will use some default editor. If you want to
use a particular editor, you need to set your UNIX environment, for
example, in your .bashrc add:
VISUAL=vi
EXPORT VISUAL
EDITOR=vi
EXPORT EDITOR
to set your default editor to vi (quite frankly I would put there
an emacs).
Do yourself a favor and do not edit the cs file if you do not
know what you are doing (i.e., before you read this missive), or
at least save the previous content of this file somewhere. It is
so easy to make a typo in this file.
You can also create a new config spec file in some local
directory with an editor (e.g., on temporary storage as
/tmp/myspec.txt) and then replace a config spec file
in your current view with a command:
ct setcs /tmp/myspec.txt.
So how the config spec works? Say, you want to view a file
myprog.c. The ClearCase has to decide which version
of myprog.c to show you, and most likely there are several
versions of it. The config spec file consists
of rules, one per line, that are interpreted from top to bottom.
ClearCase looks into the config spec and matches the rules
to the element that you want to access. Then it checks if the
version selector field matches. If it finds the
rule that matches a version of your element
it selects this version, and skips the rest of the rules
in the file. So the order of rules is important. It is
now the time to look at some rules that I was listing earlier
in this write-up. In most cases you will see the rules like:
scope pattern version-selector [additional-options]
The scope is usually a keyword element that
tells ClearCase
that this rule is used for selecting elements. Then,
the pattern
is listed. In most cases you will see there just * that means
any element. But you can of course specify a particular
element or a specific pattern. For example:
myprog.c@@/main/5 (the 5th version of
element myprog.c on the main branch)
or *.c (the C programs), or even
/vob/the_big_project/gui_piece/... (elements under a
subdirectory gui_piece). Be careful since element
means file or directory, and if you had a directory called c.c
then the *.c glob will pick this directory too. Of course,
there is an option to distinguish between files and directories. If you
want only files, you can say: element -file *.c ... and if
you want only directories, say element -directory * ....
Then, after glob for element selection there is
version-selector that lists either the branch
or the label. You will see often something like the ....
These are ellipses and usually mean: anything before
or after in the directory path. Be careful with
wildcards (*) and ellipses (...) since the rule
has to be constructed in such a way that only one version
may be picked up. If the given rule fits more than one
version
of the particular element the ClearCase reports an error
and chokes on it. For this reason, you
rarely see the rules that use wildcards in the
version-selector but you often see ellipses in the
branch selection. As you recall, no two
sub-branches of the version tree can have the same
name (oh well, if you did not use pbranch option, but you did
not, since you are reading this elementary text), so there is no way
that you can have two sub-branches like
/main/version1.1/bug_fix and /main/version1.2/bug_fix.
The additional-options usually have to do with
branch creation or time based version selection.
In most installation, the config spec rules
can only be modified by the owner (i.e., the UNIX user) of
the view (of course, the root can do anything...).
While anyone in the UNIX group that
owns the files can go to your view and even modify the files,
usually only the owner of the view can modify the
config spec.
When you create a view with a ct mkview command and the
ClearCase admin did not create a customized default config spec,
the ClearCase will take the following default:
element * CHECKEDOUT
element * /main/LATEST
that was described before in this write-up.
The 1st rule shows that any CHECKEDOUT elements
should be shown before any other version. The 1st
rule also allows
the check outs. ClearCase will not let you to
check out an element if you cannot see what you
had checked out. If the element is not checked out
(and in most cases, the elements are not checked out)
then the second rule will apply and it will show you the
LATEST version of the element
available on the main branch.
With this basic config spec all work would be done on the
main branch. If more than one person works on
the project, such environment would not be productive.
A view named jkl_koolapp_2.4.3 that
uses a private branches for a developer (jkl)
with a config spec like:
element * CHECKEDOUT #1
element * .../jkl_koolapp_2.4.3/LATEST #2
element * /main/LATEST -mkbranch jkl_koolapp_2.4.3 #3
would do the job. Note the * in the 2nd column of each
rule.
They just say that the rules apply to any element
be it a file or directory, that you want to see.
The first rule gives priority
to checked out elements. For elements that
are not checked out rule #2 will show the
LATEST version of the element on the
private development sub-branch jkl_koolapp_2.4.3.
But, in most cases, there will be no versions on this
private branch, especially, when the view was
just created. Then the rule #3 kicks in and shows
the LATEST version of the element on
the main branch. Assuming that developers are
merging their good versions to main
branch often (as they should), it is a pretty good
config spec. But the rule #3 has
additional options: -mkbranch jkl_koolapp_2.4.3.
Remember that rule #3 applies only to an element
version that was selected by this rule. In this case,
it means that the LATEST element version was
picked up from the main branch since neither the
rule #1, nor #2 was satisfied:
the element is not checked out and it does
not have yet any versions on the jkl_koolapp_2.4.3
sub-branch.
This additional option tells ClearCase that when you
decide to check out this element version
the ClearCase will create a new branch for the element
and seed it with the LATEST version from the main
branch. Namely, on check out it will
create the version: somefile@@/main/jkl_koolapp_2.4.3/0.
The somefile@@/main/jkl_koolapp_2.4.3/0 will be just a copy of
somefile@@/main/LATEST. When you do your editing, and then
check in the element, it will be saved on
the jkl_koolapp_2.4.3 sub-branch as:
somefile@@/main/jkl_koolapp_2.4.3/1. At this point you will
be picking up this new version of the element
via rule #2.
The rules can also be used to select versions
by using a label. For example, if you want to pick up
a released versions for the view as
a starting point, you could modify the above config spec
as:
element * CHECKEDOUT #1
element * .../jkl_koolapp_2.4.3/LATEST #2
element * KOOLAPP_2.4.2 -mkbranch jkl_koolapp_2.4.3 #3
element * /main/LATEST -mkbranch jkl_koolapp_2.4.3 #4
Assuming that the latest release was marked with a
label KOOLAPP_2.4.2, the additional rule
#3 will select the element version that
went to the latest release before checking if the
element version is available on the main
branch.
You can also use the time stamp or version with the rules.
The popular use for the rules involving time
is to protect your view from picking up changes that were merged
to the main branch by other developers. For example, if
your version of myprog.c depends on the particular
version of the include file utils.h that was
fine last year (2008 as of this writing), and people were making changes
to the utils.h recently (but you did not create a new
version of this file on your
branch jkl_koolapp_2.4.3), you can either use
the particular version of this file
(here version 3 on the main branch)
like:
element * CHECKEDOUT #1
element * .../jkl_koolapp_2.4.3/LATEST #2
element /vobs/koolapp/utils.h /main/3 #3
element * /main/LATEST -mkbranch jkl_koolapp_2.4.3 #4
or use the time rule like:
element * CHECKEDOUT #1
element * .../jkl_koolapp_2.4.3/LATEST #2
element /vobs/koolapp/utils.h /main/LATEST -time 31-Dec-2008.23:59:59 #3
element * /main/LATEST -mkbranch jkl_koolapp_2.4.3 #4
Be warned, however, that the example rules above are deficient
if you wanted to actually check out and edit the utils.h.
You would have to add additional mkbranch option.
There are many more options and a lot of subtle issues with
the config spec file. I only scratched the surface here.
Moreover, the element rules are only one of several
kinds of rules that can go into config spec. Another
popular rule is include that just includes a content
of the specified file into the config spec. It is often used
in the team environment to make sure that all developers share some
specific rules (or the whole config spec, for that
matter). The ct man config_spec will provide you with the
precise syntax and kinds of rules, but the examples given
there could be better. So read the excellent examples at:
http://www.philforhumanity.com/ClearCase_Support_17.html.
ClearCase commands and scripts
This would probably be a good place to list popular ClearCase commands.
I will not do it, since the thick book would have to follow.
One thing to be on alert is that the ClearCase commands are often
the same as UNIX commands and many command line options are identical.
For example:
% ct setview jkl_koolapp_2.4.3 # set your view. You are still under UNIX shell
% cd /vobs/koolapp # use UNIX 'cd' to go to your project directory
% ls -l # regular UNIX directory listing command
% ct ls -l # ClearCase directory listing command
Moreover, when you are in the view you can enter
a ClearCase shell and you will only be able to use the ClearCase commands
at this stage. In the example below the % denotes the UNIX
shell prompt, while cleartool> is the ClearCase shell
prompt:
% ct pwv -short # which view is selected ?
** NONE **
% ct # switching to ClearCase shell
cleartool> setview jkl_koolapp_2.4.3 # set your view under ClearCase
cleartool> cd /vobs/koolapp # this is ClearCase 'cd' not Unix 'cd'
cleartool> ls -l # this is ClearCase 'ls' not Unix 'ls'
# ... ClearCase style directory listing
cleartool> exit # back to UNIX with no view selected
%
Note, in the example above the ct is an alias for
cleartool. I personally never switch to ClearCase shell
since my fingers would get confused. But some people do switch between
UNIX and ClearCase shells and like it. For example, when you use a GUI
version of ClearCase (xclearcase) you are automatically in the
ClearCase shell, but you can also run a regular shell commands in
a window that pops when you click a button.
There are two basic modes to run ClearCase: command line and
graphical. Examples above all used the command line since
this is how I prefer to use ClearCase (I am an old man). But young folks
may like the graphical GUI of ClearCase. Note, that most often, you
work on your desktop computer and develop the software on some remote
host, e.g., by logging to it via rsh or ssh. If you have
X-Window server on your desktop, you need to let the remote host know
where to display the widgets. Most often you just need to set the
DISPLAY environment variable on the remote host with
your desktop computer IP address and the display.screen number
information. Assuming that the IP address of your desktop computer
is: 101.102.103.104 and your display.screen numbers
are the default (i.e., 0.0) you would type something
like this in your xterm where you are logged in to the
remote host:
DISPLAY=101.102.103.104:0.0
export DISPLAY
On the local desktop host, you will need to allow the remote
host to access your X-Window display. You need to know the name or
IP address of the remote computer. Assuming that your remote host
IP address is: 101.102.203.204 you would run something like this
on your local desktop computer:
xhost +101.102.203.204
or just authorize the remote access when you are prompted for it
on first attempt. To open ClearCase GUI, you would just type:
xclearcase &
in the xterm where you are logged in to remote computer.
You can also run some commands of ClearCase
with the -graphical command line option. For example, to run the
ClearCase diff utility in a graphical mode, you would type:
ct diff -graphical file1.txt file2.txt &
that will display the files side by side and highlight differences.
I signaled some basic commands as examples above. You can get the list
of individual commands with a ct man command.
The page is quite deficient
since it lists the commands but does not provide one-line explanations
for the most popular commands.
However, there is a nice Web page:
http://www.yolinux.com/TUTORIALS/ClearcaseCommands.html
that provides examples of popular actions with succinct comments what
they do. You can easily search it for keywords with the browser's
find facility under browser's Edit menu.
I would like, however, to explicitly address the issue of removing
elements. My approach is (and I follow the steps of those
who really know the ClearCase): not to remove. There is a
better way not to carry the unnecessary pieces of software or files or
even directories to new views or releases.
How? Just do not list them in the directory elements, i.e., remove
references to these things from the directories where they reside.
They will still be on the VOB under the version of the
directory where they were last modified (i.e., in the old view),
but they will not be referenced in the
new versions of their parent directory (i.e., not seen in the
new views). Since you will not normally see them,
you will not be able to check them out from now on. However,
after you did it, you need to merge your directory element
changes to the main branch. This way you will not
break any relations between elements and their versions
and yet you can get to the obsolete element via
a ClearCase @@ path, if you ever needed. Say, you decided that
the element: change_db.pl is no longer needed and even
harmful and misleading for the new release, since it was superseded by the
new configure_db.pl element. Assuming that the
element resides under /vobs/koolapp/conf directory
and you are currently in the jkl_koolapp_2.4.5 view (your
view name is the same as the name of your development
branch) do the following:
cd /vobs/koolapp/conf # go to the directory with the element
ct checkin change_db.pl # element has to be checked in
ct checkout . # directory has to be checked out
ct rmname change_db.pl # remove element entry in the directory
ct checkin . # check in the directory were element was
# -- the following can be easier done via GUI
# -- e.g., with xclearcase or merge -graphical
# -- or in-house "guru" provided merging script,
#
# -- merge the LATEST version of . (current dir) in your branch to the main
# -- branch. The .@@/main/CHECKEDOUT is the target contributor while
# -- .@@/main/jkl_koolapp_2.4.5/LATEST is the "other" contributor
ct checkout .@@/main/LATEST # check out the LATEST version of . on main
ct merge -to .@@/main/CHECKEDOUT .@@/main/jkl_koolapp_2.4.5/LATEST
ct checkin .@@/main/CHECKEDOUT # checkin the version of . on main branch
# Check things out if stuff worked...
ls -l .@@/main/
...
drwxrwxr-x 2 jkl ccusrs 40 Jan 21 2007 5
drwxrwxr-x 2 jkl ccusrs 73 Jul 10 13:21 6
drwxrwxr-x 2 jkl ccusrs 73 Jul 10 13:21 LATEST
ls -l .@@/main/LATEST # the file change_db.pl is gone
ls -l .@@/main/6 # the file change_db.pl is gone
ls -l .@@/main/5 # the file change_db.pl is there
ls -l .@@/main/jkl_koolapp_2.4.5
drwxrwxr-x 2 jkl ccusrs 775 Jul 10 13:19 0
drwxrwxr-x 2 jkl ccusrs 696 Jul 10 13:21 1
drwxrwxr-x 2 jkl ccusrs 696 Jul 10 13:21 LATEST
ls -l .@@/main/jkl_koolapp_2.4.5/LATEST # the file change_db.pl is gone
ls -l .@@/main/jkl_koolapp_2.4.5/1 # the file change_db.pl is gone
ls -l .@@/main/jkl_koolapp_2.4.5/0 # the file change_db.pl is there
ct lshistory | more
# you will see a record of your deeds here...
Of course, the actual merge would be easier done if you used the
xclearcase GUI or ran a customized merging script
provided by your ClearCase guru/admin. But I wanted to show the
mechanics of it and make you wonder what is going on.
You can restore the element that was removed from the
directory. Check the:
http://www-01.ibm.com/support/docview.wss?rcss=faqtt_2Q09&uid=swg21149206
If you have a good ClearCase admin, you will most likely have a number
of helper scripts that automatize creation of
views, config spec rules and
merging, labeling, copying elements from
views, etc. These are usually perl or shell scripts that
use a UNIX/ClearCase find command(s) and/or UNIX
grep/sed/awk commands and process config spec files
and elements in your view. These scripts are
very dependent on the location of your VOB mount points, your
project names, labeling policies and policies related to testing and
releases. There are usually not that complicated to write, but there is
no one size fits all. If you do not have these things written,
have a meeting, establish the rules for development procedures, and have
these scripts written and produce document like this:
http://tgill.us/resume/samples/ClearCase-FAQ.pdf
but add your scripts description and examples. Check the
Brad Appleton page:
http://acme.bradapp.net/,
his ClearCase page:
http://acme.bradapp.net/clearcase/
and his zipped PowerPoint slides:
http://acme.bradapp.net/clearcase/RUC2003_SCMA34.zip
http://acme.bradapp.net/clearcase/ccm02.zip.
This is a condition to make ClearCase a workable
and efficient tool for those who are not experts in ClearCase use. It will
also protect you from disasters (Mom... Woops... I deleted all the latest
versions...) and it will make the development process easier to track and
will improve collaboration between team members. Unfortunately, there are
only few examples of scripts on the Web, but check:
http://www.ibm.com/developerworks/rational/library/4687.html,
http://www.philforhumanity.com/ClearCase_Support_40.html,
and
http://www.evanchu.com/ware/clearcase.
Another way to improve productivity with ClearCase is to create
a handful of UNIX aliases for popular operations. Some aliases that
I have in my .bashrc file follow:
alias ct="cleartool" # cleartool -> ct
alias cv="cleartool pwv -short" # tells me which view I am in
alias ctco="cleartool checkout -nc" # checks out a file or dir w/o comment
alias ctci="cleartool checkin -nc" # checks in a file or dir w/o comment
alias ctchmod="cleartool protect -chmod " # change CC default protection
When you try to write your own ClearCase scripts, make sure that you
pay attention to the UNIX exec varieties. The SHLVL
environment variable or a ps shell utility that you will run in
another xterm,
may help. There are also UNIX commands like ptree or
pstree that can help you to traverse UNIX process tree visually.
This is important, since some ClearCase commands return to the original
shell and some spawn a subshell and return only when you type exit
or hit CTRL/D. For example, when your default UNIX shell
on login is ksh, and you type bash at your prompt,
you created a child process whose parent is a ksh. The child
will run a bash shell until you exit it and return to the
parent ksh. To visualize this you can use a simple perl script
my_pstree.pl. Read the comments
there. Put it in your HOME directory and remember to do:
chmod 755 my_pstree.pl. Log in to a UNIX server and
have two xterms open. In one xterm
type: ~/my_pstree.pl.
Assuming that your default login shell is ksh and your user name
was jkl you would see something like this:
# ~/my_pstree.pl
Process tree for user jkl:
|___. USER PID PPID ...
...
|___. jkl 31276 31274 ... -ksh
|___. jkl 31737 31276 ... /usr/bin/perl /home/jkl/my_pstree.pl
|___. jkl 31745 31737 ... /bin/ps -ef
...
|___. jkl 31305 31303 ... -ksh
...
#
The eclipses (...) may represent some other processes and things
that we are not interested in at this moment.
You can see your processes there:
- 31276 -- this is the process id (PID) of the
ksh process in which you ran the
script (its parent process id, PPID, is 31274, but since it
is owned by root, it is not shown here).
- 31737 -- the perl interpreter for the script that you just ran.
It is a child of 31276 process, i.e., the ksh
from above.
- 31745 -- this is a process that runs a UNIX ps -ef
command that is executed by your my_pstree.pl script.
It is a child of your perl interpreter that runs your script.
- 31305 -- this is the idle ksh in your other
xterm window, where you do not have anything running
at this time. Its parent is 31303 but since parent is running
as root we do not see it here.
Create a simple script, say myshell and place it
in your HOME directory:
#!/bin/bash
bash
echo "This will only be printed after you type exit or hit CTRL/D"
Make sure that you did: chmod 755 myshell to make it
executable. Then run it in one of the xterms as ~/myshell.
You may see that your UNIX prompt changed but not much more than that.
In the other xterm run the script ~/my_pstree.pl again.
Your output should look something like:
# ~/my_pstree.pl
Process tree for user jkl:
|___. USER PID PPID ...
...
|___. jkl 63966 63964 ... -ksh
|___. jkl 92013 63966 ... /bin/bash ./myshell
|___. jkl 92014 92013 ... bash
...
|___. jkl 64064 64062 ... -ksh
|___. jkl 93879 64064 ... /usr/bin/perl /home/jkl/my_pstree.pl
|___. jkl 93880 93879 ... /bin/ps -ef
So what happened here?
- 64064 -- is a PID of the grandparent of the ps -ef
command (PID=93880) that was ran from within a perl
process (PID=93879). It is similar as before. The PIDs
and PPIDs changed (note that I ran this from the new set of
two xterms).
- 63966 -- PID of the ksh process that
runs the ~/myshell script.
- 92013 -- PID of the bash shell that
runs the myshell script (note, we put the #!/bin/bash
as a top line of the script).
- 92014 -- PID of the bash shell that is
currently running in your xterm (where the prompt may have
changed).
Now, type exit in an xterm when you ran the
myshell script:
% exit
exit
This will only be printed after you type exit or hit CTRL/D
an if you run the ~/my_pstree.pl script in the other window again
you will get something like this:
# ~/my_pstree.pl
Process tree for user jkl:
|___. USER PID PPID ...
|___. jkl 63966 63964 ... -ksh
|___. jkl 64064 64062 ... -ksh
|___. jkl 75624 64064 ... /usr/bin/perl /home/jkl/my_pstree.pl
|___. jkl 75625 75624 ... /bin/ps -ef
i.e., the xterm that had two nested bash shell
processes is back to ksh. Did you notice what happened when
you typed exit in the bash xterm?
Now, let us repeat the exercise but run the myshell in a
different way, as: source ~/myshell (or if it does not like it,
type . for source, that is: . ~/myshell).
The visual result will be the same, just a possible UNIX prompt change.
Again, in the other window type ~/my_pstree.pl and see
something like this:
# ~/my_pstree.pl
Process tree for user jkl:
|___. USER PID PPID ...
|___. jkl 63966 63964 ... -ksh
|___. jkl 81036 63966 ... bash
|___. jkl 64064 64062 0 14:44 pts/29 00:00:00 -ksh
|___. jkl 81140 64064 ... /usr/bin/perl /home/jkl/my_pstree.pl
|___. jkl 81141 81140 ... /bin/ps -ef
The my_pstree.pl output is similar (the PIDs of
descendants of 64064 ksh process changed since those
are new processes). However, the bash shell process with
PID 81036 is no longer doubly nested. But still no message
that follows the bash command in the myshell script
is printed. Why the change? Since source (or .)
command does not spawn a new shell to run the script, but runs the
commands inside the existing shell. But since bash process
started inside the script waits for your input, nothing that follows
it will be executed until you type exit. And when you type it,
you will get:
% exit
exit
This will only be printed after you type exit or hit CTRL/D
and running ~/my_pstree.pl in the other xterm
afterward will show the picture that we have see before:
# ~/my_pstree.pl
Process tree for user jkl:
|___. USER PID PPID ...
|___. jkl 63966 63964 ... -ksh
|___. jkl 64064 64062 ... -ksh
|___. jkl 96729 64064 ... /usr/bin/perl /home/jkl/my_pstree.pl
|___. jkl 96730 96729 ... /bin/ps -ef
Now, assuming that you have a view in the ClearCase called
jkl_koolapp_2.4.1 create a script in your HOME directory
and call it check_if_view_set(and remember
to chmod):
#!/bin/bash
cleartool setview jkl_koolapp_2.4.1
cleartool pwv -short
echo == Sorry no go with: 'cleartool pwv -short'
echo == This will not be executed until you exit from a shell that was
echo == spawn by ClearCase, and when you exit, you will exit also
echo == jkl_koolapp_2.4.1 view. And when you exit the view,
echo == you will have no view and you are FUBAR.
and run it as ~/check_if_view_set. Even the prompt will not
change. Running the ~/my_pstree.pl in the other xterm
reveals what just happened:
# ~/my_pstree.pl
Process tree for user jkl:
|___. USER PID PPID ...
|___. jkl 63966 63964 ... -ksh
|___. jkl 22089 63966 ... /bin/bash /home/jkl/check_if_view_set
|___. jkl 22090 22089 ... ksh
|___. jkl 64064 64062 ... -ksh
|___. jkl 25013 64064 ... /usr/bin/perl /home/jkl/my_pstree.pl
|___. jkl 25014 25013 ... /bin/ps -ef
#
Now type the cleartool pwv -short in the xterm
where you ran your /check_if_view_set:
# cleartool pwv -short
jkl_koolapp_2.4.1
#
Well... You are in the view (i.e., the
command in the script: cleartool setview jkl_koolapp_2.4.1 worked
fine, but nothing was done afterward inside the script
check_if_view_set. When you type exit
in the same xterm you will get:
# exit
** NONE **
== Sorry no go with: cleartool pwv -short
== This will not be executed until you exit from a shell that was
== spawn by ClearCase, and when you exit, you will exit also
== jkl_koolapp_2.4.1 view. And when you exit the view,
== you will have no view and you are FUBAR.
And if you ran your faithful companion my_pstree in the
other xterm you would see that you are back to two plain shells:
# ~/my_pstree.pl
Process tree for user jkl:
|___. USER PID PPID ...
|___. jkl 63966 63964 ... -ksh
|___. jkl 64064 64062 ... -ksh
|___. jkl 37832 64064 ... /usr/bin/perl /home/jkl/my_pstree.pl
|___. jkl 37833 37832 ... /bin/ps -ef
What is the conclusion? RTFM. You need to read the ClearCase
man pages. You also need to try, use some toy commands and
toy views so you do not mess up anything. For example, for
testing, if there is a remote possibility that you can rename 100
important elements, you list the elements to be renamed first,
an only when you are ABSOLUTELY SURE that the right elements
will be renamed, you put the dangerous command in, i.e.,
you do it on live body with a real scalpel. Test, test, test...
There is a lot of things that man pages will not tell you.
If you wrote a toy script like:
#!/bin/bash
cat > /tmp/temp_cc_$$ <<EOF
echo == I am inside the view:
cleartool pwv -short
cd /vobs/www/patentviewer/
echo == I changed to the top directory of my project:
echo Unix directory listing
ls -l
echo ClearCase directory listing
cleartool ls -l
EOF
chmod 755 /tmp/temp_cc_$$
cleartool setview -exec /tmp/temp_cc_$$ jkl_koolapp_3.2.10
You would get something like:
# ~/check_if_view_set_good
== I am inside the view:
jkl_koolapp_3.2.10
== I changed to the top directory of my project:
Unix directory listing
total 18
drwxrwxr-x 2 jkl ccusr 1591 Jul 28 12:27 bin
drwxrwxr-x 3 jkl ccusr 99 Jun 23 10:14 conf
drwxrwxr-x 2 jkl ccusr 0 Jan 21 2007 lib
drwxrwxr-x 5 jkl ccusr 285 Jul 28 16:59 www
ClearCase directory listing
directory version bin@@/main/jkl_koolapp_3.2.10/1\
Rule: element * .../jkl_koolapp_3.2.10/LATEST
directory version conf@@/main/8\
Rule: element * /main/LATEST -mkbranch jkl_koolapp_3.2.10
directory version lib@@/main/3\
Rule: element * /main/LATEST -mkbranch jkl_koolapp_3.2.10
directory version www@@/main/1\
Rule: element * /main/LATEST -mkbranch jkl_koolapp_3.2.10
#
and feel the force. Your script would execute and you would
get back to the original ksh in which you executed it (you can
verify it with the my_pstree.pl as usual).
Do not be too happy though. This one was an easy toy script... The real
scripts are harder to make and require a lot of testing and foresight.
I cannot give you my actual scripts that I use, since they include
the work of others.
But I will give a taste of it, by showing you a script that I wrote for
myself from scratch to create a view. You can use it as a start
up example and create a better one. The script assumes that team members
work on their private branches in their private views.
Also, the views have the same names as branches
and their names have to be composed from the user name, project name,
and iteration version, for example: jbl_koolapp_3.1.2.
The script tries to enforce the naming, who is allowed to do things, etc.
Again... To even try it in your environment, you will have to carefully go
through the source, and modify the bogus names there. But maybe, you will
find there some ideas that will be helpful. Good luck. The bash
script example is here: mk_usr_koolapp_view. Frankly, I would write it in
perl and made it much shorter, but it is an example. As you can see,
even this small script depends very tightly on policies and local environment.
For this reason, it would be very hard (at least for me) to cook up something
generic, but I tried to make it "adaptive". Enjoy, and write
more scripts and share... I will be grateful for corrections, since,
as you can see, I am a ClearCase beginner and use it since I had been told
to do so...
Disclaimer:
All the stuff written above is most likely nonsense.
If you believed any of this, it is your problem. Do not sue me... You have been
warned!
P.S. Sorry very much...
Me speaks English very small and them thinks me is dummied person
and pays me little... If me speaks good, them think me is the genius
and them pay big salary to me... You learn speak very big and wise and
you not need work hard and only talk much... Join the Republicano-Democratic
Party and become a rich politician and crook...
Jan Labanowski
jkl at ccl dot net
Greg's Law of Evolution: Only tasty animals and plants have a chance for
survival.
Jan's extension: They also have to be helpless and easy to prepare...
|