The interaction model is straightforward. For each working file, you initialize its RCS file once, then enter a cycle of checkout, modification, and checkin operations. Along the way, you can tweak some of the RCS file’s metadata, as well. All of this is done through RCS commands; you need not modify the RCS file directly (and in fact you should probably avoid doing so lest RCS become confused). This model is somewhat analogous to using a library (of books). With a library, you sign up for a library card (initialize), then enter a cycle of taking a book home (checkout), enjoying it (NB: without modification, one hopes), and returning it to the library (checkin).
Furthermore, you can compare revisions in the RCS file against each other, examine the user- (hopefully high) quality descriptions of the changes each revision embodies, merge selected revisions, and so forth.
RCS commands operate on one pair of files at a time. The working file is what you normally view and edit (e.g., a file of C programming language source code named a.c). Because the working file’s contents can be extracted from the RCS file (called instantiating a working file), it can be safely deleted to regain some disk space.
The RCS file is a separate file, conventionally placed in the subdirectory RCS, wherein RCS commands organize the initial and subsequent revisions of the working file, associating with each revision a unique revision number along with the remembered particulars of the checkin that produced it. It also contains a description of the working file and various other metadata, described below.
The RCS file is also known (colloquially) as the “comma-v file”, due to its name often ending in ,v (e.g., a.c,v).
A revision number is a branch number followed by a dot followed by an integer, and a branch number is an odd number of integers separated by dot. A revision number with one dot (implying a branch number without any dots) is said to be on the trunk. All integers are positive. For example:
1.1 -- revision number for initial checkin (typically); branch number: 1 188.8.131.52 -- more complicated (perhaps after much gnarly hacking); branch number: 9.4.1 333.333.333 -- not a valid revision number; however, a perfectly valid branch number
The branch point of a non-trunk branch is the revision number formed by removing the branch’s trailing integer. To compute the next higher branch or revision number, add one to the trailing integer. The highest-numbered revision on a branch is called the tip of the branch (or branch tip). Continuing the example:
1.1 -- on trunk; no branch point; next higher branch number: 2 next higher revision number: 1.2
184.108.40.206 -- not on trunk; branch point: 9.4 next higher branch number: 9.4.2 next higher revision number: 220.127.116.11
333.333.333 -- not on trunk; branch point: 333.333 next higher branch number: 333.333.334 next higher revision number: 333.333.333.1
In addition to this “tree” of thus-linked revisions, the RCS file keeps track of the default branch, i.e., the branch whose tip corresponds to the most recent checkin; as well as the symbolic names, a list of associations between a user-supplied (and presumably meaningful) symbol and an underlying branch or revision number.
The RCS file contains two pieces of information used to implement its
access control policy. The first is a list of usernames. If
non-empty, only those users listed can modify the RCS file (via RCS
commands). The second is a list of locks, i.e., association
between a username and a revision number. If a lock
username:revno exists, that means only username
may modify revno (that is, do a checkin operation to deposit the
next higher revision, or a higher revision number on the same branch as
The checkin operation records the contents of the working file in the RCS file, assigning it a new (normally the next higher) revision number and recording the username, timestamp, state (a short symbol), and user-supplied log message (a textual description of the changes leading to that revision). It uses diff to find the differences between the tip of the default branch and the working file, thereby writing the minimal amount of information needed to be able to recreate the contents of the previous tip.
The checkout operation identifies a specific revision from the RCS file and either displays the content to standard output or instantiates a working file, overwriting any current instantiation with the selected revision. In either case, the content may undergo keyword expansion, which replaces text of the form ‘$Keyword$’ with (possibly) different text comprising the keyword and its value, depending on the current keyword expansion mode (see Substitution mode option).
The keywords and their values are:
The login name of the user who checked in the revision.
The date and time the revision was checked in. May include an appended timezone offset.
A standard header containing the absolute RCS filename, the revision number, the date and time, the author, the state, and the locker (if locked). May include an appended timezone offset.
Same as ‘Header’, except that only the basename appears (no directory components).
The login name of the user who locked the revision (empty if not locked).
The log message supplied during checkin, preceded by a header containing the RCS filename, the revision number, the author, and the date and time. May include an appended timezone offset.
Existing log messages are not replaced. Instead, the new log message is inserted after ‘$Log:...$’. This is useful for accumulating a complete change log in a source file.
Each inserted line is prefixed by the string that prefixes the ‘$Log$’ line. For example, if the ‘$Log$’ line is
// $Log: tan.cc $
then RCS prefixes each line of the log with ‘// ’ (slash, slash, space). This is useful for languages with comments that go to the end of the line.
The convention for other languages is to use a ‘ * ’ (space, asterisk, space) prefix inside a multiline comment. For example, the initial log comment of a C program conventionally is of the following form:
/* * $Log$ */
For backwards compatibility with older versions of RCS, if the log prefix is ‘/*’ or ‘(*’ surrounded by optional white space, inserted log lines contain a space instead of ‘/’ or ‘(’; however, this usage is obsolescent and should not be relied on.
The symbolic name used to check out the revision, if any. For example, ‘co -rJoe’ generates ‘$Name: Joe $’. Plain co generates just ‘$Name: $’.
The basename of the RCS file.
The revision number assigned to the revision.
The absolute RCS filename.
The state assigned to the revision with the -s option of rcs or ci.