[comp.unix.programmer] CVS-RCS

phjm@fairfax.fairfax.com (Phillip Merrick) (06/05/91)

In article <1991May23.201749.20336@dds4.uucp> wolfe@dds4.uucp (Peter Wolfe) writes:
>This is a topic worth doing some surveys on.  Come on folks - how do you
>take care of multiple derviations of common source using CVS/RCS/SCCS (I
>know that you can throw money at Configuration Management vendors to do
>this).

[I am cross-posting this to comp.unix.programmer and comp.unix.misc since
I have noticed some related questions on multiple derivations there 
recently also. Disclaimer: I know little about CVS - it may be that
CVS can do all the stuff I'm describing already.]

For several years now I have been handling multiple versions/releases of
source files with the following configuration management model imposed
over RCS. With some help from colleagues, I originally put this in place
on a moderately large (~ 650 KLOC) project at the point at which we made
our first release (where new development and release maintenance diverge).
The model and the tools supporting it have been deployed on several
other projects since then.

The primary aim of the model is to support this (very common) scenario:

	- Version X has been released
	- New development proceeds
	- We need to fix version X, and re-release it
	- We want to merge the fix forward into development

The basis of the model is the use of an RCS branch for each version of the
software in question, and the replication of the same branching structure
across all the project RCS files. Establishing new branches uniformly across
files is achieved with 'bogus' check-ins. These bogus check-ins are assigned
revision numbers ending in '.0' to distinguish them from real revisions to
the source file.

An RCS symbolic name (the version name) is assigned to each branch, in every
file. By assigning symbolic names to entire branches (e.g. VER1 --> 1.0.0) it
becomes very easy to access the most recent revision along a particular
branch (e.g. co -rVER1). An 'rlog -rVER1' will show only revisions made
to that branch.

The trunk is where new development takes place. When it comes time to make
a new major release, we check out the latest trunk revisions and check them
in on a new branch, to which we assign a suitable RCS symbolic name.

The RCS files conceptually look something like this:

0.0--0.X-->1.0------1.X---> "DEV"- - - - - - - --->2.0--------2.X-----> "DEV"
            |                                       |
            |                                       |
          1.0.0.0---1.0.0.X--> "VER1"            2.0.0.0------2.0.0.X--> "VER2"

This shows two major releases ("VER1" and "VER2"), with new development
continuing along "DEV". Note that the files are intially created at "0.0" -
purely to free up "1.0" as a suitable branch point for the first major
release. Note also that further derivations from (say) 1.0 are possible,
and would be represented as additional branches numbered 1.0.1.X, etc.

Now, assume that a bug occurs in VER2. The programmer checks out the most
recent revision to VER2, makes the fix, and checks it back into VER2.
The programmer then locks DEV, does an rcsmerge of the fix from VER2,
and (after conflict resolution and verification) checks back into DEV.
Of course, the bug could easily have been detected and fixed in VER1, then
merged forward into VER2 and DEV. This becomes particularly convenient
when a fix spans several files.

Minor 'maintenance' releases of bug fixes are made by taking a snapshot
of the version in question. For the RCS files, this just entails tagging
the most recent revision (e.g. 1.0.1.5) with an appropriate RCS symbolic
name (eg. "VER1.a").

This model is used in conjunction with parallel directory trees of checked
out source files. The RCS files live in their own tree, with checked out
source files in parallel source trees. In the filesystem, it looks
something like this:

			     projdir
				|
	  +---------------+--------------+---------------+
	  |               |              |               |
	VER1		VER2		DEV		RCS
       /  |  \         /  |  \         / | \             |
    src  bin  lib   src  bin  lib   src  bin  lib       src

The src subdirectory can be an arbitrarily deep directory hierarchy. It is
consistent across each version tree. Each branch in the RCS files "feeds"
the src subdirectory of the corresponding version tree. Each version tree
holds the most current source for that version. Past maintenance releases
(or 'snapshots') can also be checked out into their own parallel tree,
when necessary,

Programmer's work directories can be organised along similar lines to
the version trees (but generally will be a subdirectory of src). 

This model is basically derived from ideas gleaned from Andy Glew's excellent 
"Boxes, Links and Parallel Trees" paper in the proceedings of the April
'89 Usenix Software Management Workshop.

Needless to say, managing all of the above requires a fairly high degree of
automation. Hence I have developed my own obligatory 'wrappers over RCS'.
These wrappers have gradually evolved into something approaching a full
configuration management toolset (written in C and shell scripts). It 
bears the name 'FCMtools' and in addition to implementing the
model described above can also provide:

	+ Management reporting: e.g. tell me all the changes to
	  version X since 1/6/91; show me the configuration for
	  release M.n. The reports include the obvious things plus
	  the RCS log comments entered at check-in time. Another report
	  makes it easy to track down who has what files locked.

	+ Name lookup: an RCS file locator mechanism allows the user
	  to simply provide enough of the pathname to uniquely identify
	  a source file. (eg. fcmout file.c, or fcmout dir/file.c).
	  This works in conjunction with an environment variable that
	  specifies a target hierarchy for the checked out file.
	  Name transformation is almost mandatory given the parallel
	  trees layout, unless you like typing long pathnames. 

	+ Tools to manage the parallel version trees. A tool named
	  'fcmcollect' can update a version tree with all the changed
	  revisions from the corresponding RCS branch. This allows
	  easy integration with make (just run fcmcollect as the first
	  step in the build). 'fcmcollect' only checks-out new revisions:
	  it doesn't get triggered by changes in the modification date
	  or by RCS lock operations. 'fcmcollect' also knows how to
	  mirror the RCS hierarchy by creating new directories as they
	  appear, deleting obsoleted files, etc.

	+ Ability to setup a programmer's work area (usually some subtree
	  of the whole src hierarchy) with one command (fcmcollect, again).

	+ Simplified merging. Amongst other things, overlaps can be flagged
	  with the version names (instead of the revision numbers).

	+ Administrator functions: versions can be individually protected
	  against one or more of check-in, check-out with lock, or selection
	  for a merge operation. This helps during release preparation.
	  A per-project setup file is used for specifying file location,
	  RCS file structure and characteristics of the various source file
	  types.

	+ An RCS file creation utility. You can use it to install
	  new files into one or more versions - it will set up the
	  branches and symbolic names as necessary. It keys
	  into the setup file on the source file suffix to
	  determine how to initialise the RCS file.  Also, it will
	  insert a predefined file header (can vary by file type)
	  containing a standard set of comments (e.g. copyright notices)
	  and RCS macros ($Date$, $Revision$, $Log$, etc.)


If you have persisted this far, you might be wondering if I'm planning on
making FCMtools generally available. The package needs a minor clean-up and
(more importantly) improved documentation. I also need to get a hold
of RCS 5.5 and verify that it all still works! When I get that done  - I'm
guessing 4-5  weeks from now, real work permitting -  I'll post to alt.sources. 
If you are really eager, send me email and we can take it from there. Oh,
it currently runs on several Sys V.3 boxes - but it started life on a BSD
based system and has acquired only a couple of Sys-Visms along the way.

Hope this helps somebody!

-- 
Phillip Merrick				| Domain:    pmerrick@fairfax.com
Fairfax Software Corp., Fairfax VA	| UUCP:	     uunet!fairfax!pmerrick