-- EladLahav - 25 Nov 2005


CVS is an easy to use, yet powerful and effective version control system. It is based on a client-server architecture that stores all files in a common place, thus allowing several people to collaborate on a project.


Common terms used by CVS:

  • Repository: A collection of file and directory revisions managed by CVS. A repository is stored on the server-side.
  • Module: A project managed by CVS. A module is simply a directory in a CVS repository.
  • Tree: A snapshot of a module stored on the client-side.
  • Root: A string containing the access method, user name and path leading to a CVS repository.
  • Import: Populating a newly created module with files.
  • Checkout: The process of creating a tree in a work directory.
  • Update: Synchronising a tree so that it reflects the current state of the repository.
  • Commit: Synchronising a tree so that changes in the work directory are applied to the repository.

CVS Life Cycle

Working with CVS usually involves the following stages:

  1. Create a module in the repository and import files into it.
  2. Create (check-out) and maintain (update) a tree in a work directory.
  3. Work on your tree.
  4. Transfer (commit) your changes.

We shall assume that a repository was already created and that it is accessed only through rsh/ssh. The root will be


where :ext: means that the repository can only be accessed using rsh, elahav is the user name, hopper is the server on which the repository resides and /u3/elahav/cvsroot is the path to the repository.

To use ssh instead of rsh, set the environment variable CVS_RSH to ssh.

Every CVS command has the following form:


Most CVS commands work recursively, which means they are applied to all sub-directories.


The import process creates a new module in the repository. The module is populated with all files in the current directory. The command has the following syntax:


where ROOT is the repository's root string, MODULE_NAME is simply the name of the module, and VENDOR_TAG and START_TAG are arbitrary symbols.

You can get rid of the -d ROOT part by setting the CVSROOT environment variable to the root string.

The vendor and start tags are just relics from old times. You can safely use the strings VENDOR and START for every module you create.

Assume ~/src/myproject is a directory containing the files to import. The following commands create the module myproject in the repository

   cd ~/src/myproject
   cvs -d :ext:elahav@hopper:/u3/elahav/cvsroot import myproject VENDOR START

Alternatively, we can use the CVSROOT environment variable:

   export CVSROOT=:ext:elahav@hopper:/u3/elahav/cvsroot
   cd ~/src/myproject
   cvs import myproject VENDOR START

Since CVS works recursively, all sub-directories and their files will also be imported.


The checkout command creates a tree by copying the latest version of all files in a module into a the current directory. Its basic syntax is:

   cvs -d ROOT co MODULE_NAME

Checkout can also create the tree in a specified directory:

   cvs -d ROOT co -d DIR MODULE_NAME

For example, to check out the myproject module in the current directory

   cvs -d :ext:elahav@hopper:/u3/elahav/cvsroot co myproject

or, if CVSROOT has already been set correctly

   cvs co myproject

This command creates a directory called myproject under the current directory, populated with the module files (including all sub-directories). Each directory in the tree has a CVS sub-directory, which contains such information as the name of the module, its root and the files in this directory that are included in the module.

Once the module has been checked out, you can work on the files in the tree directory. This will not affect the repository in any way.

There is no concept of "locking files" in CVS (as opposed to e.g., RCS).


While working on your local tree, some changes may occur in the repository. For example, someone else may have changed some files, or even you may have done so from another tree (for instance, when working from your home computer). It is therefore advisable to update the tree as often as possible. Maintaining an updated tree will reduce the risk of conflicts that arise when several people are changing the same code.

To update the entire tree, simply move to the tree's top-most directory, and issue the command

   cvs up

For example, in order to update the myproject tree kept in ~/src, run the commands

   cd ~/src/myproject
   cvs up

The tree is update recursively, so there is no need to issue the command again for each sub-directory. Note, also, that you do not need to specify the root in the update command, as the CVS sub-directory contains a Root file that is read automatically.

One can also update any sub-directory of the tree, by changing to that directory and running the cvs up command.

When CVS updates the tree, it outputs the names of any modified files and indicates their status. This status is given by any of the following letters:

  • U: This file was not in your tree, and was fetched from the repository.
  • P: The file exists in your tree, but had to be patched in order to update it to the latest version.
  • M: The file in your tree contains local changes (that were not yet committed to the repository).
  • C: The file was changed both locally and in the repository, resulting in conflicts. Conflicts need to be resolved manually.
  • ?: A local file is not part of the module (you can ignore this message).


Once your changes were made and tested, you are ready to incorporate them into the repository. This is done using the command

   cvs commit FILE1 FILE2 FILE3 ...

This command requires you to explicitly provide the names of the modified files you would like to commit. Once the command is issued, an editor session will begin, which you can use to write a log entry describing the changes made to these files. If you want a different log message for each file, you need to run the commit command separately. The files are committed once you save the contents and quit the editor (e.g., using wq in Vi). Note that lines in this file beginning with "CVS" are comments, and are not saved as part of the log entry.

You can skip the editor session by supplying the log entry with the -m switch, e.g.,

   cvs commit -m "This is my informative log entry" hello.c hello.h

Add/Remove Files

If you add files to your tree, and would like these files to also be added to the module, use

   cvs add FILE1 FILE2 FILE3 ...

Similarly, to remove files from the module use

   cvs remove FILE1 FILE2 FILE3 ...

None of these changes take effect until you issue a commit command including these files.

For example, to add foo.c and bar.h to myproject, issue the commands

   cvs add foo.c bar.h
   cvs commit foo.c bar.h

GUI Clients

While CVS is pretty simple and can be easily operated from the command line, it is sometimes more convenient to use a GUI client instead. Here are some suggestions of clients available for different environments:

  • LinCVS is a multi-platform client for Windows, Mac OS X and Linux.
  • CvsGui have different clients (the Mac OS and Linux clients are somewhat outdated).
  • Cervisia is a very good client that is distributed as part of KDE.

More Help

To learn more about the CVS command line options, use

   cvs --help


   cvs -H COMMAND

for details on the specific commands (such as import, co, up, commit, etc.). Under Unix, the man command should give you more details.

Documentation is available on the CVS main website and in this manual.

The Subscription Website and CVS

Repository Information

Access method
SSH (:ext:)

Versioning Scheme and Tags

We follow a Major. Minor versioning scheme for production versions. For ecample, the current version number is 3.0, the next minor changes (bug fixes and small features) will appear in version 3.1, and the next overhaul will result in version 4.0.

Before a version is released for production, it undergoes a Release Candidate (RC) phase, during which it is publicly tested. Release candidate versions have the same number as the future production version, with -RC N appended, where N denotes the current revision. For example, the first release candidate for version 3.0 is 3.0-RC1, the second is 3.0-RC2, etc. Once a release candidate has been approved to be of production quality, the RC number is dropped, and the version is moved as-is to the production directory.

CVS tags for the production versions follow the scheme V_Major_Minor. Thus version 3.0 is associated with the CVS tag V_3_0. For release candidates, the suffix _RCN is added, e.g., V_3_0_RC4 for the fourth release candidate of version 3.0.

Deploying a New Version

We keep three folders under the Research Subscription website:

  1. Development (subdev)
  2. Release candidate (subRC)
  3. Production (sub)

The subdev directory always points to the HEAD version of the CVS tree, while subRC and sub contain tagged versions. Deploying a new version is therefore only a matter of updating the relevant directory. For example, to upgrade the RC directory to version 3.0-RC2, use:

research$ export CVS_RSH=ssh
research$ cd subRC
subRC$ cvs up -r V_3_0_RC2
subRC$ ./fixperm

(note that the fixperm script needs to be called to set the correct permissions for the different files.)

Similarly, the following commands upgrade the production version to 3.1:

research$ export CVS_RSH=ssh
research$ cd sub
subRC$ cvs up -r V_3_1
subRC$ ./fixperm

Usually sub and subRC should not be modified in any other way. However, if, for some reason, a new sub or subRC directory need to be created, the code should be checked out from the CVS repository, and the files .options and .rtoptions should be copied into the new directory. (These two files contain user-configurable information, and are therefore not part of the CVS module. They can be fetched from a backup of the old sub or subRC directory.)

In the following example, a new subRC directory is created:

research$ export CVS_RSH=ssh
reseacrh$ cvs -d :ext:elahav@asimov.cscf:/projects/research/cvsroot co -r V_3_0_RC1 -d subRC sub
research$ cd subRC
subRC$ cp .snapshot/nightly.0/.options .
subRC$ cp .snapshot/nightly.0/.rtoptions .
subRC$ ./fixperm
Edit | Attach | Watch | Print version | History: r6 < r5 < r4 < r3 < r2 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r6 - 2006-01-27 - EladLahav
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback