A Comparison of /BriefCase(tm) vs. CVS
January, 1999
by: David M. Knight
1. A Comparison of /BriefCase(tm) vs. CVS
While CVS and /BriefCase(tm) are both built upon the same file
revision control platform (RCS), their philosophy, approach
and command structures differ dramatically. As I am not a
CVS "expert", I encourage those readers who may be more
familiar with CVS to "keep me honest" with constructive
feedback!
1.1 What Are CVS and /BriefCase?
Both the CVS and /BriefCase packages enhance the
functionality and usefulness of RCS-5.7, an industry-
standard revision control control package by implementing:
o a central, client/server repository
o full directory tree support, including subdirectory
recursion and automatic mapping of the current working
directory to its corresponding repository directory
o the notion of a project, consisting of a collection of
files in an arbitrarily complex directory tree
1.2 Availability and Licensing
Like RCS, both the CVS and /BriefCase packages are available
free of charge, under the terms of the GPL and may be
downloaded from one or more Internet/web sites. There are
no licensing charges for either package.
1.3 Support
Technical support for both packages is available, for a fee,
from two or more consulting organizations. In addition, the
source code included in the CVS and /BriefCase downloads may
be maintained, enhanced and/or redistributed by end users,
according to the terms of the GPL.
1.4 Major Similarities
Both CVS and /BriefCase build upon the file-oriented
capabilities of the RCS Revision Control System with
additional commands and paradigms including:
1. a local/remote repository implementation with
client/server-style access
2. Unlike basic RCS, the check-in operations of both CVS
and /BriefCase do not remove the local copy of the
checked-in file. Because of differing philosophies
about locking, /BriefCase check-in makes the local
copy read-only, CVS commit (check-in) does not.
3. after check-in, both CVS and /BriefCase may
automatically update working files, based upon the
setting of their RCS -k parameter or, with /BriefCase,
if the filename is recognized as belonging to a class
of files configured for automatic "ident line"
maintenance (see "Advanced Features" section for more
on this). This ensures that RCS keywords (and
especially any "ident lines") contained in the working
files will reflect the newly checked-in revision(s).
4. "logical" removal of files which become obsolete
during project evolution - CVS hides them in the
"Attic" and /BriefCase "zaps" them to achieve the same
result: obsolete files are invisible for ongoing
development but automatically available during
checkout of older releases in which they were used,
e.g. for bug fixes and maintenance releases.
Unfortunately, the CVS User manual does not mention
this feature.
5. client/server access to a local or remote central
source code repository using the standard TCP/IP rsh
command protocol:
o /BriefCase client scripts run their server-side
counterparts with rsh and use a combination of
pipes and an NFS mounted (rw) staging area
(/Stage) to move information between the client
and server hosts.
o CVS uses rsh to start a CVS server process to
access the repository and transfers the
information between client and server hosts via a
TCP/IP socket.
If the "tcpwrappers" (tcpd) security package is
installed, NFS exports may be further secured by
restricting access to the server's portmap (TCP)
service with appropriate entries in the
/etc/hosts.deny and /etc/hosts.allow files.
An alternate CVS configuration requires installation
of:
o the CVS server program as an suid-root binary - a
dubious prospect for some security-conscious
sites
o entries to the /etc/services and /etc/inetd.conf
files to invoke the CVS server
Like the portmap service, the CVS server installation
can be made more secure with tcpd.
/BriefCase does not currently provide a socket-based
client/server implementation preferring, instead, to
build on the benefits of its shell-script
implementation.
Both CVS and /BriefCase protect their central
repository filesystems behind their respective
client/server mechanisms.
To ensure the integrity of the client/server software
versions, the /BriefCase client scripts and CVS
executables are NFS exported (readonly) by the server,
mounted by each client host and secured through
export/share directives limiting access to the
/BriefCase or CVS to their client hosts.
The rsh protocol requires several server-side host
access configurations (/etc/hosts.equiv and/or
/.rhosts files) to be set up for the client hosts and
client/server synchronization of uid/gid numbers such
that a CVS or /BriefCase user on a client host can
successfully execute an rsh command like:
rsh server_name date
where server_name is the /BriefCase or CVS repository
server host. Line the portmap service, the rsh
service can be made more secure with tcpd.
Uid and gid number synchronization is most easily
maintained where both client and server hosts'
/etc/passwd and /etc/group files are maintained within
an NIS or NIS+ domain. Like NFS mounts, use of rsh
can be further secured, with appropriate entries in
the /etc/hosts.deny and /etc/hosts.allow files if tcpd
is installed.
6. control of RCS keyword substitutions: CVS requires you
to specify a -k flag at
import/add/checkout/diff/update time for files which
are to have "non-default" keyword expansion. When the
-k flag is specified on add, the attribute is saved in
the RCS repository and becomes the default property
for that file. When -k is specified for any other
operation, it is remembered ("sticky") for you but is
not permanent unless you also use cvs admin to modify
the file in the repository. When a -k attribute is
specified for a CVS "import" that attribute apparently
applies to all files imported; which may not be
appropriate for trees that contain a combination of
files that need expansion and files that do not. For
example, importing a tree that contains both source
files (which need keyword expansion) and third-party
(.so or .a) libraries (which must not have keyword
expansion) one would need to manually adjust one set
or the other, regardless of the -k specified for the
import.
/BriefCase uses a project-specific configuration file
to recognize which files should have keyword expansion
and define a source-language-dependent identification
string to be maintained for each type of file.
Unrecognized file types are checked in with the "no
keyword expansion" attribute.
7. Unix file ownership and group permissions control
access to repository files and directories
8. /BriefCase and CVS are both mature, well tested and
robust packages, available since the late 1980's.
Both CVS and /BriefCase have proven track records at
Fortune 500 companies for a variety of small to very
large projects.
1.5 Major Differences
1.5.1 Documentation /BriefCase comes with a complete 170+
page, indexed Reference and User's Guide, in PostScript (for
printing or online viewing), PCL and ASCII text formats.
1.5.2 Philosophy By default, CVS operates in the
"unreserved checkout" mode and, at commit (check-in) time,
detects merge conflicts when changes in your file(s) are in
direct conflict with changes committed by other users since
your revisions were checked out. For example, if your
changes are made to revision 1.12 and another user committed
revision 1.13 with his/her own changes to one or more of the
same lines changed in your file. Developers must manually
resolve any "merge conflicts" before a commit can succeed.
Configuring CVS to use reserved (locked) checkouts may help
with these concerns, but obviates several CVS commands and
those portions of the current CVS user manual dealing with
unreserved checkout issues.
With /BriefCase, developers can checkout a read-only copy of
any revision of any file at any time. When a developer
intends to modify a revision of a file, he/she tries to
check-out and lock it. If the lock succeeds, then no one
else has locked that revision intending to change it. It
the lock fails, the developer can:
1. coordinate with the owner of the existing lock
2. start a branch revision to contain his/her revisions
(a "parallel development path") until such time as a
merge may be appropriate
3. in an emergency, break the lock (a "reason" is
required). The event is logged and email, indicating
both the breaker's userid and the reason, is sent to
the user whose lock was broken. The user whose lock
was broken then has the option of starting a new
branch revision for his/her changes or merge with the
new tip revision and check in the result as a new tip
revision.
Advance notice of potential code conflicts tends to increase
inter-developer communication and minimize the number and
complexity of conflicts that need to be resolved during a
merge.
Branch revisions simplify development and maintenance of
"temporary fixes" which may never be merged with the main
trunk and allow multiple concurrent development paths which
proceed through multiple stages (revisions) to be checked in
without impacting each other or the main "trunk" development
path. If a change checked in as part of a branch is "bad"
(won't compile or worse), its only impact is upon that
specific branch and will not disturb another developer
checking out tip revisions or working on another branch.
As changes to a locked revision may only be checked in by
the owner of the lock, it is unlikely that anyone could
irreparably "step on" someone else's changes by "mistake"
because it is always possible to either revert to the
previous revision and/or merge the "mistake" as if it had
been a branch revision. Furthermore, as /BriefCase
implements "strict" locking, a developer can only check in
changes to files which are actually locked. This greatly
reduces the likelihood that one could accidentally check in
changes that were coincidental to the intended fix or
enhancement. For example, imagine that you are working on a
particularly hard to reproduce bug and, in the process of
developing and testing a fix, you have made hard-coded,
temporary changes to 7 sources in 4 directories (to simplify
the reproducing the problem and testing the fix) and the
actual fix required changes to 5 sources in 3 directories.
With the CVS "unreserved checkout" approach, if you did a
commit in a top-level directory, without specifically
articulating the pathnames of the files you wanted to check
in, it would commit the the 7 files with the hard-coded
changes, or the one you forgot to revert to the proper
revision, (which should not be checked in) along with the 5
fixed files. With /BriefCase strict locking (assuming that
you did not lock the files in which the temporary changes
were made) a top-level, recursive check in would only check
in those files which were changed and locked.
1.5.3 Focus The main focus of /BriefCase is to simplify
and support the "project tree" and "named/tagged release"
abstractions as well as to keep the revision control
operations and the user interface as easy to use as possible
for arbitrarily large directory trees. Specifically,
/BriefCase commands are designed to:
o make repository operations as transparent and intuitive
as possible; common operations are accomplished with
single commands, e.g. nci checks in one or more new
files (as compared to the separate "add" and "commit"
commands required by CVS)
o minimize the number of commands and options required to
accomplish a given task, especially common tasks
o minimize the amount of filename/pathname typing
required
o minimize the effort required to maintain the integrity
of a source code revisions and directory tree
o minimize the potential for user errors when migrating
files between the repository and the user's working
directory
o support release management operations with advanced tag
management and presentation-quality reports of tagged
release content and differences
1.5.4 Advanced Features In addition, /BriefCase provides
some advanced, developer and release-manager-friendly
features which CVS does not:
1. Project Workarea Replication - users can have multiple
project work areas in which to work on different
releases and/or aspects (bug-fixes, enhancements) of a
single project. /BriefCase project Workarea replicas
provide full revision lock integrity across replicas
and across client hosts. Locks made from one replica
are not confused with locks made from another replica
or even from the same replica on another client host.
2. Private Tags - allow users to assign and manipulate
their own private set of tags (a tag is a symbolic
name associated with specific file revision).
Administrative tags are still only available only to
users in the BCadmin group (i.e. /BriefCase
administrators).
3. Import/Conversion tools - simplify moving SCM archives
into /BriefCase from SCCS, CVS, RCS and PVCS.
4. /BriefCase configuration allows classes of files which
can be recognized with a regular expression match of a
filename "extension" ("*.c", "*.pl", etc.) or portion
of their filename ("*akefile", APP_*, etc.) to
automatically ensure that files in each class contain
a file-specific "ident line" at check-in time.
Typically, ident lines are of the greatest value with
source code languages that support a mechanism which
passes the "ident" info into the executable (binary?)
files, thus providing the means to determine precisely
which source files revisions were used to build a
library file or a binary executable.
Note that /BriefCase also uses these classes to
determine the default -k flag when a file is first
checked in. Files belonging to one of the defined
classes are checked in with -kv and an ident line of
the configured type appended at the end, unless the
file already contains an ident line of the proper
format elsewhere in the file. File not belonging to
any of the configured classes will be checked in with
the -ko flag, which preserves any RCS keywords and
ident line information from the original file and
prevents re-expansion on checkout. Should this
default be incorrect for any given file, the nkw_exp
command can be used to reset the -k flag
appropriately.
While CVS does not come with a feature to manage ident
lines or choose a default -k flag based on classes of
filenames, I suspect that something similar could be
built using the more generalized "cvswrappers"
facility.
5. Release Management Reports - /BriefCase also provides
commands to produce presentation-quality (typeset or
HTML) reports about the exact content (a manifest) of
a tagged release (ntag_report), the exact differences
between tagged releases or a tagged release and the
tip revisions (ntag_diffs) - with optional reports of
the revision history (remarks entered by the
developers) and/or the actual lines of code which
changed.
6. a build subsystem interface which supports
configuration of host-specific and project-specific
environment variable settings to be used for a build;
the supplied build interface is for make but the same
mechanism can be used to custom-fit other command-line
build tools which derive their operating
characteristics from the environment, command-line
arguments or flags, local control files or a
combination thereof
7. a basic, project-oriented Bug Tracking subsystem which
includes commands to open, close, defer, kill, reopen,
take/assign, update bug reports and enhancement
requests as well as a command to generate a variety of
reports
8. a basic runtime packaging scheme which produces a
"package" consisting of a README file for installation
instructions, an install script and an install archive
(tar or cpio)
9. a basic runtime deployment/promotion mechanism to
manage deployment of runtime packages through the
DEVpkg, TESTpkg and PRODpkg pseudo-projects in the
/BriefCase repository. Unix groups "develop",
"qatest" and "ProdCtl" can be used to secure and
isolate access for these organizations, if desired.
Ideally, only runtime files (no source) would be
deployed from development to QA and from QA to
Production. QA and Production staff should not be
able to make changes to development sources and
developers should not be able to change a runtime
package once it has been "promoted" to QA. The names
and number of promotion groups can be customized with
shell script changes.
While QA and Production platforms may access the
/BriefCase repository (via a LAN) to obtain a runtime
package for installation, any other distribution
method may be used.
Like other /BriefCase commands, these advanced features and
basic facilities are implemented as shell scripts and are
intended to be modified or enhanced, as desired, by end
users.
1.5.5 Directory Tree Operations Most /BriefCase commands
map the user's current working directory to a corresponding
repository directory and operate only on files therein,
possibly/optionally recursing into subdirectories.
1.5.6 Modules Files To reduce the need to specify long
pathnames on CVS commands and to encapsulate groups of files
and associate them with a symbolic name. /BriefCase
dynamically determines file organizations directly from the
repository and does not currently provide a "modules"
equivalent.
1.5.7 Project Initialization and Initial Source File Check-
in CVS allows (any?) users to import or add a new project
directory tree to the repository.
/BriefCase projects must be initialized by a user in the
"BCadmin" group, after which developers in the appropriate
(Unix) group can check in an entire directory tree, a
portion thereof or individual files at any time, with a
single command.
1.5.8 Recursive Behavior Generally, /BriefCase commands
usually only on files in the current directory and
recursively only when the "-R" flag is specified. CVS
commands typically work recursively and can sometimes be
limited to the current directory files in with a "-l" flag.
1.5.9 Vendor Branches CVS supports "Vendor Branches",
which are intended to simplify maintaining local changes to
a body of code which originated from and is periodically
updated by a third party, by "reserving" branch 1.1.1 for
the vendors parallel development path. Each new release of
vendor source is checked in to branch 1.1.1 and changed
files become new leaf revisions on that branch. Local
changes can be merged into the new vendor release with the
cvs update command.
/BriefCase has no formal "vendor branches", but the same
task can be accomplished using the somewhat more generalized
/BriefCase bciR and nupdate commands.
Merging the new vendor release into the main "trunk"
development path is mechanically the same as merging any
other parallel development path. If local changes conflict
with changes in the vendor's code, they must be resolved
before the vendor branch merge can be completed.
1.5.10 History and Logging CVS supports several history
and logging options and maintains data files in addition to
the RCS revision history. /BriefCase does not maintain
ancillary logs or databases but provides report commands
which list the all information available directly from the
RCS repository archives.
1.5.11 Working Directories To aid with CVS administration
and, possibly, performance, CVS creates and maintains a
"CVS" directory in each working directory and states that
"you should not modify or remove any of the files in it".
/BriefCase does not create or depend on any special files or
extra directories in the user's working directories.
1.5.12 Checkout, Locking Merging Strategies /BriefCase
supports a checkout-and-lock strategy which causes
developers to be notified up-front if someone else is
working on (i.e. has locked) the file revision they want to
modify. Checkout and lock of any non-tip or non-leaf
revision will automatically start a new branch at check-in
time. Branches may be merged into the main trunk as
necessary; temporary fixes may never need to be merged.
This strategy is particularly well suited to an organization
with several developers working to enhance and/or support
multiple releases of a software product because:
1. developers know, in advance, with whom they need to
coordinate parallel development efforts and have an
opportunity to eliminate redundant effort and discuss
designs. As the CVS User manual correctly points out
neither CVS or any other Software Configuration
Management (SCM) system "is not a substitute for
management ... [or] developer communication"
2. parallel developments checked-in as different branch
revisions can be tested and released without impacting
each other
3. once a branch of code achieves stability, it can be
merged into the main trunk of the revision tree.
CVS uses "unreserved checkout" and may require the developer
to do a merge (if another developer's changes were checked
in since his revision of the file was checked out) before
the "commit" (check-in) will work. This strategy causes a
number of problems which do not occur with a "checkout-and-
lock" strategy:
1. you don't know about conflicts until you try to commit
your changes
2. every time you check in, you may need to update and/or
merge your changes with the repository and
recompile/retest everything before the commit will
succeed - and, if more changes are checked in while
you're testing, you may have to do it all again...
3. committing partial or less-than-perfect changes may
seriously impact the efforts of other developers -
potentially making it impossible for them to compile
their code. This aspect of CVS would seem to limit
the extent to which it could be used by developers to
checkpoint their work during long or nontrivial
implementations.
and results in a plethora of additional CVS "tools" to
figure out those things that are more or less implicit with
a checkout-and-lock strategy:
1. cvs status - tells if/why you need to run a cvs
update command
2. cvs update - merges new repository versions with your
local changes - you need to resolve conflicts at this
point and recompile/test everything before your
changes can be committed
3. cvs watch {on|off} files - enable|disable
notification of [other's] work on files, provided they
use the cvs edit command to checkout their work files
(which sets a pseudo-lock in CVS, not RCS)
4. cvs watch {add|remove} ... - add current user to list
of users to be notified
5. cvs edit - notifies "watch" users that you are about
to edit file (via email?)
6. cvs unedit - notifies "watch" users that you are
abandoning a file edit
7. cvs watchers - lists users who are watching files
8. cvs editor - lists users currently working on files
CVS "branch tags" may help, but I cannot say for sure
because of the apparently local/private nature of "sticky
tags" and their possible relation to branch tags.
Curiously, these CVS features seem to operate only at the
file level, not the revision level. /BriefCase provides
revision level granularity so that if user Joe has locked
revision 2.5 of file foobar and user Mary needs to change
revision 1.7 (e.g. to fix a bug in a prior release), Mary is
not (nor should she be) informed of Joe's lock on revision
2.5 when she checks out and locks foobar rev 1.7.
Furthermore, Joe's changes will be checked in a rev 2.6 (as
one would expect) and Mary's changes will automatically be
checked in as the start of a new branch revision (e.g.
1.7.2.1).
The CVS User manual mentions a checkout-and-lock strategy
and proceeds to dismiss it as "counter productive" because
they feel it somehow prevents parallel development -
apparently ignorant of the fact that branch revisions were
designed to do just that! The CVS User manual talks about
"branch tags" (a combination of a tag and an initial branch
revision) and further confuses things with "sticky" tags and
dates that "apply to subsequent commands in this directory",
until you do a cvs update -A (??) which appears to remove
(all?) sticky tags.
Given this arcane aggregation of tags and branches, it would
seem that the authors of CVS did not understand how the
author of RCS (Walter Tichey) intended branch revisions to
be used (clearly documented in the RCS documentation).
1.5.13 Security Both CVS and /BriefCase use Unix file and
directory permissions to isolate projects by groupid. For
example, if there were three development groups working of
separate "projects", each group would have its own Unix
groups (i.e. their own groupids in /etc/group) for their
developers and, possibly, their own QA and ProdCtl staffs.
/BriefCase, in addition, uses a special groupid (BCadmin) to
restrict release management operations which may impact
tagged release integrity, file revision history, new project
initiation, build environment configuration and dev/qa/prod
promotions.
1.5.14 History File Integrity Some simplistic remote
repository implementations (e.g. PVCS) ignore the potential
for history file corruption by using whatever version of
their revision control software is installed on the client
to manipulate shared history files on the server.
Both /BriefCase and CVS perform history file updates using
only server-side software. Repository corruption due to
incompatible versions of the revision control software are,
therefore, eliminated.
1.5.15 Ongoing Development /BriefCase is currently
maintained by the author with new releases made available
for download at their web site (http://applied-cs-
inc.com/BriefCase/download). The current production release
is 2.4b and the latest alpha release is 3.0. CVS has had
numerous authors and contributors and has seemed to
stabilize at at release 1.9 or 1.10.
1.5.16 Other /BriefCase Features with no CVS Analogs
1. certain /BriefCase commands are restricted to users in
the BCadmin group, e.g. project initiation, release
tag management, obsolete a revision or logically
remove (nzap) a file
2. Automatic maintenance of a customizable "#ident"
string for classes of filenames (based on filename or
extension recognition with a reg. expression)
3. comprehensive tag management and reporting features
for both user-assigned tags and BCadmin-assigned
release management tags
4. make interface to set up compile-host-specific and
project-specific "build" environment - suitable for
multi-platform and multi-target projects
5. simple runtime packaging scripts and deployment
strategy
6. simple Project BugReport/EnhancementRequest tracking
system
7. advanced, presentation-quality (typeset or HTML
format) reports detailing tagged release contents and
differences between tagged releases
8. detailed reports of revision activity
9. comprehensive change report enumerating differences
between the current working directory tree and a
corresponding tagged release or tip revisions in the
repository
10. numerous simple report commands which extract and
display useful information about files, revisions,
history, tags, etc., from the repository
1.5.17 CVS Features with no /Briefcase Analogs
1. modules file - allows arbitrary aggregation of files
within a project
2. commit wrappers - allow custom processing at commit
time
1.6 Miscellaneous Considerations
o CVS operations depend upon the existence of a CVS
subdirectory in every working project directory and
cautions users not to modify or delete any files
contained therein.
o Some CVS operations seem somewhat disjoint. For
example, to obsolete or logically remove source files
under CVS control, a developer must:
1. rm -f files... # erase the local files to be
removed
2. cvs remove file... # prepare to logically remove
repository files
3. cvs commit # actually move repository files "to
the Attic"
In /BriefCase, the "nzap files..." command does steps 2
and 3 and does not require step 1. A subsequent check-
out of any release after the file gets "zapped" will
remove the local file, if necessary.
To add a new file or directory tree to an existing CVS
project, one apparently needs to do a "cvs add" and a
"cvs commit" to get the job done. With /BriefCase, the
command "nci files..." or "nciR dirname" does it all.
/BriefCase commands are "self-contained" in that they
do not set-up for or depend upon some other command(s),
e.g. cvs add sets up for cvs commit (check-in).
In general, /BriefCase commands tend to be more concise
and have fewer options than their CVS counterparts and,
thus, may be easier to learn and use. The CVS command
syntax, for example sports two sets of option flags:
cvs [cvs options] cvs-command [command options] [args]
where the cvs options (bTdefHlnQqrstvwxz) and command
options (DfHklmnPpWr) overlap and some of the
overlapping flags (lnr) cause radically different
results if placed in the wrong order.
o /BriefCase developers can check-in (commit) their
changes, whenever they want to save a
checkpoint/milestone in their code, without impacting
developers or maintainers working on other changes to
the same sources. This promotes use as a tool to
manage multiple phases of a work in progress - one of
the most valuable features of RCS.
The CVS concept of "commit" mandates that only
complete, "working" code should be committed and limits
its use as a tool to manage concurrent, parallel
development paths as works-in-progress.
o CVS combines the concepts of tags and branch revisions
in such a way that it complicates the use of branch
revisions to manage concurrent, parallel development
paths.
o CVS is written in the C language. /BriefCase client
and server side code is implemented entirely as shell
scripts with a few awk scripts and, thus, may be easier
for many end-users to maintain and/or enhance.
o The default recursion (through subdirectories) may make
CVS more difficult to use and recovery from a "mistake"
that commits too much may be more difficult.
/BriefCase commands which change the repository tend to
be conservative in their default behaviors.
o CVS operation can be "customized" through a number of
optional, ancillary files that live in the
$CVSROOT/CVSROOT directory.