René Nyffenegger's collection of things on the web
René Nyffenegger on Oracle - Most wanted - Feedback -

CVS, the concurrent version system

CVS is an edit and merge kind of source control system, so you don't have to check out files before you can work on them (as this is the case with for example Visual Source Safe which uses a "lock-modify-unlock" model)
See also Subversion, a rewrite of CVS.
Another alternative is darcs
Normally, CVS works recursively. This can be suppressed by specifying the -l option.


The repository is the term used for the set of files and directories which are under the control of CVS.
The repository is accessed through one of the following methods:
  • :local:
  • :pserver:
    Password authenticated server
    Uses $CVSROOT\passwd file
  • :rhosts:
  • :ntserver:
    Named pipes
  • :gserver:
    for active directories
  • :sspi:
    Allows authentication against the windows NT domain login.
  • :server:
    RSH client
  • :sserver:
    SSL client
  • :ssh:
    SSH client
  • :ext:
    External command
  • :fork:
The method is used in the following way:
There are two ways to tell where the repository can be found. The first is to set the environment variable CVSROOT. The second is to indicate it with the -d flag.
A repository is created with the init command.

Working directory

The files under the control of CVS are not modified in the repository. They're first transferred to a (local) directory called the working directoyr.


Each (commited) version of a file has a distinct revision number that looks like 1.4 or or Each revision number consists of an even number of integers that are seperated by dots. The revision number 1.1 denotes a file's first or initial version.
The rightmost number is incremented by one for each new (commited) version.
When a new branch is created, the new branch's revision number is the revision number to which x.1 is appended. x will be the lowest unused even integer.

Adding files

When a new file is added to a project, its revision will be x.1. x will be equal to the highest first number of all existing files in that project.


Branches are created with the -b flag in the tag command.
Branches are accessed in the update and checkout command using the update -r and checkout -r flag.


A branch can be merged into the working directory by using the update -j command.




cvs checkout prj
Creates a directory named prj and fetches the files belonging to that project into the newly created directory.
Checkout is always the first command to issue when someone begins to work on a project.
The -r flag can be used to access a specific branch.


The following command schedules some_file.c to be added into the repository. It does not actually add the file to the repository until a commit is made.
cvs add some_file.c



The -r flag can be used to access a specific branch.
The -j flag is used to merge a branch to the working directory
cvs update -j -j foo-bar  


cvs commit my_file.c
After modifying a file that is under version control, the changes can be stored back to CVS using commit.
Additionally, cvs will fire up an editor (specified through the CVSEDITOR and, if not set, EDITOR environment variable) which can be used to enter a log message. This log message will be stored along with the newly created version.
If a file should be commited without starting the editor for a log message, this can be done through the -m option. The log message is to be specified after the -m flag:
cvs commit -m "Improved sort function."  my_file.c
A file can be commited to a specific revision with the -r flag.
cvs commit -r 2.0


cvs tag beta-release my_file.c
The -b flag creates a branch. The following example creates a branch that is named foo-bar.
cvs tag -b foo-bar


This command is used to check in the sources for the very first time.


cvs status my_file.c


After one is finished with developing on a project, this should be indicated with the release command:
cvs release prj
If there is one or more modified but not commited files in the project, cvs will warn you and you can abort the release.
It is also possible to remove the working directory with the -d option:
cvs release -d prj


The diff command is used to display differences between the version stored in the repository and the (possibly modified) version in the working directory:
cvs diff my_file.c


Init is used to create a repository.
cvs -d /foo/bar/xy init


This command stores the password in the $HOME/.cvspass file, making it more convinient for accessing the repository in subsequent operations.


cvs passwd -a some_user
cvs passwd -r real_user some_user


See also my blog entry on creating a CVS repository.