Using CVS

The lastest version of this page can be found at:

This docuement is a summary of common CVS usage, see cvs(1) for details. Please read the man page to make sure we are talking the same language.

Concurrent Version Control (CVS)

Cvs(1) is a front end to the rcs(1) revision control system. CVS provides revision control for an entire tree rather than just a single directory, and supporst multiple edits concurrently.

The repository for CVS is kept under $CVSROOT and is just the same tree hierarchy containly the RCS revision (,v) files.

Most people do not need to know any of this - but it can be handy.

Common usage

checkout a copy of a module

Unless your admin has set up a modules file, a module is just a directory under $CVSROOT.
$ cvs checkout named
would check out $CVSROOT/named/* into ./named after which you can start editing to your hearts content.

commiting changes

In general your edits remain totally private until you commit them to the repository ($CVSROOT). Ideally, this should be done whenever a consistent set of changes is ready. Sometimes the changes to be made are considerable and should not be reflected in the main branch (what gets checked out by default) for some time, in these cases a branch can be made to hold the changes until they are ready to be merged back into the main branch. See the section on branches below.

Normally though you just want to commit your changes to the same branch that you checked out. You simply:

$ cvs commit -m'a useful comment decribing the change' file1 ...
If file1 etc are omitted, then all changed files under the current point in the tree are committed. If the comment is omitted, you will be dropped into $EDITOR to provide one.

pre-commit checks

CVS can be setup to do very clever things when people commit changes. This is easily setup, but arranging for a program to run when a commit is requested. The program can do anything it likes, and indicates via its exit status whether the commit should proceed or not. See DNS regression testing for an example.

what changed?

Before you commit changes it is always a good idea to see what they are. You can use:
$ cvs diff -cb
to see all the changes you have made in your copy of the tree. If you nominate one or more files on the command line only those files will be diff'd. You can do fancy things like:
$ cvs diff -cb -r1.2 file1
$ cvs diff -cb -D yesterday file2
would show the diffs between the current version of file1 and version 1.2 of the same file then show the changes made to file2 since yesterday. See cvs(1) for all the details on date_spec. In addition you often want to see the commit comments that have been made.
$ cvs log file1
will display the commit history of file3, so you see why the changes since version 1.2 were made. In some environments, changes cannot be committed into CVS without a change docket, and these are recorded against the change and therefor show up in the log.

adding files to the repository

To add a file, just create it using whatever tools take your fancy (vi, emacs etc) and then:

$ cvs add newfile
$ cvs commit -m"explain why I added newfile" newfile

removing files from the repository

Sometimes a file needs to be removed.

$ rm file6
$ cvs remove file6
$ cvs commit -m"why I removed file6" file6
The file is not actually deleted from the repository, it is moved into the Attic (incase someone wants to restore it later). To truely delete the file, use delete instead of remove, but be very very sure that is what you want (usually it is not).

keeping in sync

If multiple people are working on separately checked out versions of the tree, it is important to keep in sync. CVS makes this easy.

Whenever appropriate - such as when you have no outstanding changes and want to start editing something run:

$ cvs update
Which will ensure that you have an up to date copy of the tree. It will also warn you about files you have modified, created and not added etc.


If you have modified a file and it has been changed in the repository (by someone else committing their changes) CVS will merge your changes into the updated file. In more than 90% of cases, the merge is achieved successfully as there are no conflicting changes. In the few cases where there are conflicts, CVS will bring them to your attention and you need to resolve them before committing the file.

It is therefore vitally important to pay attention to what CVS says.

undoing changes

Sometimes you commit a change and later want to back it out. There are several ways of doing this, most require use of the underlying rcs commands co(1) or rcs(1). The approach used depends on how recent the change that needs to be backed out is.

back out uncommitted changes

This is achieved by simply removing the edited file and then updating:

$ rm file1
$ cvs update

most recent commit needs to be backed out

This is preferably done by checking out the prior version of the file and re-committing it with a comment to indicate why the previous change is being backed out. This is most easily done by using the underlying rcs command co(1).

$ co -p1.2 `cat CVS/Repository`/file1,v > file1
$ cvs diff file1
$ cvs commit -m"reverted to version 1.2 which worked" file1
The -p1.2 option to co tells it to check out version 1.2 of file1 to stdout. The CVS/Repository file contains the location of the rcs files (,v) for the working directory.

intermediate change needs to be backed out

If say the current version of file1 is 1.4 and the change made for 1.2 needs to be undone.

$ cvs diff -cb -r1.1 -r1.2 file1 > diffs
$ patch -R < diffs
In the above example, diffs contains the changes from version 1.1 to 1.2, the patch command is then used to apply the diffs in reverse (-R). If patch succeeds, then the offending change has been successfully removed and file1 can be committed.

The patch may fail to apply though if subsequent changes cause conflicts. In which case patch will create a file1.reg file which contains the patches that it could not apply. Time for some hand editing.

$Id: cvs.html,v 1.4 2001/08/30 07:48:42 sjg Exp $
Copyright © 1997-2001 Simon J. Gerraty