How does CVS differ from RCS?
CVS uses RCS to do much of its work and absolutely all the work
of changing the underlying RCS files in the Repository.
RCS comprises a set of programs designed to keep track of changes
to individual files. Of course, it also allows you to refer to
multiple files on the command line, but they are handled by
iterating over individual files. There is no pretense of
coordinated interaction among groups of files.
CVS's main intent is to provide a set of grouping functions that
allow you to treat a collection of RCS files as a single object.
Of course, CVS also has to do a lot of iteration, but it tries
its best to hide that it is doing so. In addition, CVS has some
truly group-oriented facets, such as the modules file and the CVS
administrative files that refer to a whole directory or module.
One group aspect that can be a bit confusing is that a CVS branch
is not the same as an RCS branch. To support a CVS branch, CVS
uses "tags" (what RCS calls "symbols") and some local state,
in addition to RCS branches.
Other features offered by CVS that are not supported directly by
RCS are
1. Automatic determination of the state of a file, (e.g.
modified, up-to-date with the Repository, already tagged
with the same string, etc.) which helps in limiting the
amount of displayed text you have to wade through to
figure out what changed and what to do next.
2. A copy-modify-merge scheme that avoids locking the files
and allows simultaneous development on a single file.
3. Serialization of commits. CVS requires you to merge all
changes committed (via "update") since you checked out
your working copy of the file. Although it is still
possible to commit a file filled with old data, it is less
likely than when using raw RCS.