A Practical Guide to CVS (Concurrent Versioning System)


We have found CVS to be extremely useful in our daily work. The documentation is, however, rather immense, so here is a quick introduction to everyday use.

Everyday use of CVS

To check out a code the first time, you need to get, from the code maintainer, the name of the CVS repository, and the name of the code module. Then do (this is a working example):
        setenv CVSROOT ursa.astro.ku.dk:/home/aake/cvs  # specify repository
        cvs checkout docs                               # checkout the "docs" module
A subdirectory docs will be created, with the files in the module (the file you are reading now is one of them ;-).

Passive mode, just keeping up-to-date

Add yourself as a watcher, so you get emails when files are committed to the repository.
        cvs watch add
When you get an email, you may want to see the differences:
        cvs diff -rHEAD
To import the new version, do
        cvs update
It is not necessary to have the CVSROOT environment variable permanently set (the location of the repository is recorded in the subdirectory where CVS keeps its things).

Active mode, you are taking part in the development

After changing files: To see the differences relative to the version you checked out (not necessarily the current one), do
        cvs diff
To check diffs relative to the current version in the repository, do
        cvs diff -rHEAD
To import the new version, do
        cvs update
It will be merged with your own changes. Possible collision will be signalled, and both versions are available in you file, with comments around.

To commit changes to the repository, do

        cvs commit

Your favorite editor will start, and you are requested to enter a line or two with comments about the snapshot. After entering the log message and exiting from the editor, the CVS repository will be updated, and you thus have a new snapshot of your directory.

You may give the log message on the command line, using

        cvs commit -m "log message"

It is the files that you originally imported that are updated in the CVS repository, not all the files in the directory. If you make a new file that you would like to also keep in the repository, do

        cvs add the-file
        cvs commit -m new the-file
After the next commit, the file will be part of the repository, along with the files that were already there.

Retrieving old versions

One of the great advantages of CVS is that you can always get back to the version of the code from a specific date and time in the past. This greatly simplifies code testing and verification, and makes it safe to experiment and be bold about new changes.

To get back to a version from a specified date and time, specify the -D option. Here are some examples:

        cvs update -D yesterday
        cvs update -D "last week"
        cvs update -D "last month"
        cvs update -D "27 nov"
        cvs update -D "27 nov 1999"
        cvs update -D "27 nov 1999 17:15"
        cvs update -D "1999-11-27 17:15"
To get back to the latest version and clear the "sticky" date tag, for continued updating, do
        cvs update -A
Analogously, differences relative to a date in the past may be viewed with
        cvs diff -D "1999-11-30"

Creating a repository

To create a new repository (only has to be done "once in a life time"), do
        setenv CVSROOT ~/cvs
        cvs init

Creating a software module

To add everything in a directory as a new module, do
        cd that-directory
        cvs import modulename -m initial yourlogin initial
where modulename is the name of the module. The rest of the parameters are necessary, but more or less irrelevant.

To add only some file from a directory hierarchy (more typical for us), one has to do little joggling to create an empty module.

        cd topofdirs                                            # top of dir structure
        mkdir tmpd                                              # temporary dir
        cd tmpd                                                 # go there
        cvs import -m initial modulename yourlogin init         # create an empty module
        cd ..                                                   # go up
        rmdir tmpd                                              # delete the temp dir
        cvs checkout modulename                                 # check out the empty module
        mv modulename/CVS .                                     # move the CVS subdir up
        rmdir modulename                                        # remove the empty dir
Now we can add bits and pieces to the new module:
        add src                                                 # adds the dir, not the files in it
        cd src                                                  # go down into the dir
        add *.f *.inc                                           # add selected files
        cd ..                                                   # up again

        add run                                                 # same procedure ..
        cd run
        add job.csh
        cd ..

        cvs commit                                              # commit the adds
In this case, we probably want to create a file .cvsignore with the names and patterns of all files that CVS should ignore
        cat > .cvsignore
        *.o
        *.x
        *.log
        *.spool
        *.dat
        *.com
        CTRL-D
        cvs add .cvsignore

More documentation

Brief help messages are available from cvs itself:
	cvs --help
	cvs --help commands
The full documentation is available, in HTML form, at TAC.
Last updated: 1999-11-27 / aake@astro.ku.dk