1. Home
  2. Tutorials
  3. CVS
Yolinux.com Tutorial

YoLinux: CVS Intro - Concurrent Versions System

CVS is a Change Management (CM) system for software source code control to store and keep track of development changes.

Free Information Technology Magazines and Document Downloads
TradePub link image

CVS Intro:

CVS is primarily used as a source code control system for text files. Programmers will generate revisions to individual source code files. A collection of these files may define a specific software release. CVS aims to manage the collection of these files and the respective revisions of the individual files that make up the collection. CVS is a command driven file checkout, update, compare and management system. Front end web and desktop GUI systems are available to ease in the use of CVS.

Setting up your environment for CVS:

  • Set environment variables: (add to your .bashrc file)

    Environment variables:

          export CVSROOT='/home/Project/CVS_root'     - directory for CVS source code repository
          export CVSEDITOR=/bin/vi

  • Set environment variables: (add to your .cshrc file) (for csh users)

    Environment variables:

          setenv CVSROOT  '/home/Project/CVS_root'
          setenv CVSEDITOR /bin/vi

  • CVSROOT: Location of CV source code repository.
Example use of CVS:

CVS commands are used with directives and command line options to create a repository, check-out, check-in and update code and interrogate changes between versions. Typically one will use a CVS repository which has already been generated, if not, one must be generated and populated with source code text files.

Creating CVS repository for the first time:

Create the CVS "root" of a new CM repository:
      cvs -d /home/Project/CVS_root init

-d: Directory used for repository. Note that an absolute pathname must be used.

[Potential Pitfall]: This is the CM repository and not a developer working area. No work, editing of files or changes should be made directly to this directory. The repository is loaded using the "import" command and files checked out to the users local working directory using cvs commands. Files are edited in the user's local working directory. Files are checked-in to synchronize and update the repository using cvs commands. Files are added and deleted using cvs commands. All interactions with the repository are done with cvs commands.

Importing a new project:

To put your project under CVS control:

Check in all files and directories from within the current working directory. The directory referenced is the tree structure for CVS not your current path.

      cvs import -m "Put text description here" ProgABC CorpABC start
The command notation is: import [-options] repositoryName vendortag releasetag

This will place the files and directories in your current working directory (and all recursively through the directory structure below the current), under CVS control. CorpABC is a "vendor tag". Start is a "release tag". The CM directory structure will be $CVSROOT/ProgABC/...

Now that it has been checked into the repository you can save,back-up or remove the current working directory. All future work will take place by checking out code from the repository. This check-out code will be under CVS CM control. The directory you just imported is not under CVS control.

      cd $HOME/src/ProgABCWorkingDir
      cvs import -m "Put text description here" ProgABC CorpABC start
The files and directories in $HOME/src/ProgABCWorkingDir were just checked into a repository named ProgABC. All exports and checkouts will start with the directory name ProgABC (not ProgABCWorkingDir). Use the same name for both if that is your intent.

[Potential Pitfall]: The directory you are importing can not be in the same directory as $CVSROOT. An endless recursive loop will take place as it will try and check-in the repository itself.


This is to get a copy of the sources and directories with the intent that the files will not be altered but shipped off site. Code extracted from CVS with export cannot be checked-in because export does not create any administrative entries.

A tag must be specified. Thus an original release would be extracted by:

      cvs export -r start ProgABC 
Start is the name of the first entry into CVS. See import. The directory ProgABC is generated with the contents of the export placed in that directory.

CVS commands and use:

By default CVS will apply recursively through sub-directories. Use the option flag "-l" to prevent this. The option "-R" explicitly defines the recursive behavior.

CVS command options: cvs [ cvs_options ] cvs_command [ command_options ] [ command_args ]

CVS OptionDescription
--allow-root=rootdirSpecify repository on the command line
-d cvs_root_directoryUse cvs_root_directory as the directory pathname of the repository. Overrides the $CVSROOT environment variable.
-e editor-commandUse the editor command specified for entering log information. Overrides $CVSEDITOR and $EDI‐ TOR environment variables.
-fDo not read the ~/.cvsrc file.
-HDisplay CVS command help
-nDo not make any changes to the root repository. Print out what would happen if the "-n" flag was not used.
-QQuiet mode. Less verbose than normal.
-qMarginally quiet mode. Reports of recursion are suppressed.
-vShow CVS software version and copyright information
-wMake new working files read-write. Overrides the setting of the $CVSREAD environment variable.

CVS Commands:

CVS OptionDescription
adminCVS interface to assorted administrative facilities.
annotateShows the revision modified each line of a file.
checkoutCheck out sources from the CVS repository for editing
commitCheck files into the CVS repository
diffShow file differences between revisions
exportExport sources from CVS. The files exported are NOT under CVS control. Note that files which are checked out are under CVS control. Use export to deliver or publich code.
historyShow status of files and users
importImport sources into CVS. Used for initial checkin of code into the CVS root repository.
logPrint out log information for files
lsUsed to list files and directories in the local working directory. Repository required.
rlsUsed to list files and directories in the repository.
rdiffGenerate "patch" format diffs between releases.
releaseIndicate that a Module is no longer in use. Cancels the effect of cvs checkout.
updateBring local work directory in sync with repository
addAdd file or directory to the repository
deleteDelete file or directory from the repository

Prints command flags used with CVS (Help):

      cvs -H 


      cvs co ProgABC
In this case, module "ProgABC" is a directory which will be created in your current directory with all the appropriate sub-directories and files.

The files/directories to checkout can be referred to by module name or relative path name from $CVSROOT.

To checkout a particular (previous) release or build:

      cvs co -r Rel-1A ProgABC
This will checkout the files necessary for the previous build for Rel-1A. The release or "tag" name in this example is "Rel-1A".

      cvs edit ProgABC/file.c

This pulls out a single file for editing without getting the whole project.

      cvs unedit ProgABC/file.c
Abandon work on file.

Note that all directories will contain a sub-directory named CVS/. This is for CVS CM management and should never be altered.

Command: cvs checkout [options] modules...

Checkout Command OptionDescription
-D dateUse the most recent revision no later than date. This option implies -P.
cvs checkout -D yesterday module-name
-lLocal; run only in current working directory.
-nDo not execute CVS command, just show what would be done if the flag "-n" was not used.
-PPrune (remove) empty directories in user working directory.
-RDefault behavior. Checkout directories recursively.
-r tag[:date]Checkout the revision specified by tag or, when date is specified and tag is a branch tag, the version from the branch tag as it existed on date. This option implies -P.
-d directoryCreate a directory called dir for the working files, instead of using the module name.
-cCopy the module file, sorted, to the standard output, instead of creating or modifying any files or directories in your working directory.
-sLike -c, but include the status of all modules, and sort it by the status string.
Other advanced options include: -f, -k, -p, -A, -j, -N


When working with a team of software developers, it is wise to periodically update your local working code to benefit from the changes and bug fixes contributed by other members of the team.

      cvs update -Pd 
This command updates the files and directories in the current directory and recursively through all sub-directories.

An update without the option "-Pd" will not add or delete directories in the local working directory when synchronizing with the root repository.

      cvs -qn update -Pd 
This command will show you the updates it is planning on making without performing the actual update. Your local files changed are also shown.

Command: cvs update [-ACdflPpR] [-I name] [-j rev [-j rev]] [-k kflag] [-r tag[:date] | -D date] [-W spec] files...

Update Command OptionDescription
-PPrune (delete/remove) all directories deleted in the root repository.
-dAdd any directory to your local working directory which has been added to the root repository.
-D dateUse the most recent revision no later than date.
-fOnly useful with the -D or -r flags. If no matching revision is found, retrieve the most recent revision.
-RDefault behavior. Update directories recursively.
-r tag[:date]Retrieve the revisions specified by tag or, when date is specified and tag is a branch tag, the version from the branch tag as it existed on date.
-lLocal; run only in current working directory.
-COverwrite locally modified files with clean copies from the repository (the modified file is saved in .#file.revision).
-I nameIgnore files whose names match name (in your working directory) during the update. More than one "-I" can be specified.
Other advanced options include: -k, -p, -A, -W, -j

History / Status / Log:

Status of checked out working repository.
      cvs status [-v] ProgABC/file.c
OR cvs status [-v] ProgABC
Option "-v": Print tag information.

Review log of change history:
      cvs log file.c

Show local modifications to review what you may want to eventually check-in:
      cvs -qn update -Pd
All modifications in your local working directory will be shown with the prefix "M". Lists all files recursively from your current directory. While this is the "update" command, the command options "-qn" prevent an actual update.
CVS descriptors:
  • M: modified files in the local working directory. Use "cvs diff filename" to see your modifications.
  • C: conflict with repository. Modifications in your file "collide" with changes made and checked into the repository. This means that someone modified the same lines of code and CVS does not know how to merge your file with that in the repository because it does not know who is correct.
  • U: file updates have been made to the repository.
  • P: Like U, but the cvs server sends a patch instead of an entire file.
  • A: The file has been added to your private copy of the sources.
  • R: File has been removed
  • ?: File does not correspond to anything in the source repository

Command: cvs history [-report] [-flags] [-options args] [files...]

History Command OptionDescription
-lShow last modification only.
-D dateShow data since date.
-cReport on each time the repository was modified.
-eEverything (all record types).
-m moduleReport on a particular module.
-TReport on all tags.
-x typeShow records of a specified type:
  • F: release
  • O: checkout
  • E: export
  • T: rtag
  • C: merge with collisions
  • G: succesful merges
  • U: updated file from the repository
  • P: patched to match the repository
  • W: working copy of the file was deleted to match the root repository
  • A: file added
  • M: file modified
  • R: file removed
-oReport on checked-out modules (default behavior).
-aShow data for all users.
-wShow only the records for modifications done from the same working directory where history is executing.
-f fileShow data for a particular file. Multiple files can be specified on the command line.
-r revShow records referring to revisions since the revision or tag named rev.
-t tagShow records since tag tag was last added.
-u user-nameShow records for user user-name.
Other advanced options include: -b, -n, -p, -z

Check-in / Commit:

When done editing the files check-in (commit) your changes:

Check in files from within the directory. i.e. file.c must be in your current working directory.

      cvs ci file.c
OR cvs ci -m "Put text description here" file.c OR cvs ci -m "Put text description here" ProgABC
The second check-in example will commit the entire module. (Files, directory structure and all)

Cleanup and get rid of all the files:

      cvs release -d ProgABC 

The flag -d will delete all of your working sub-directories. CVS will let you know if files have changed and prompt you for a [y/n] reply.

Note that the cvs directives "ci" and "commit" are the same and perform the exact same function.

Command: cvs commit [-lnRf] [-m 'log_message' | -F file] [-r revision] [files...]

Check-in Command OptionDescription
-lLocal; run only in current working directory.
-RDefault behavior. Checkout directories recursively.
-r revisionCommit to revision. revision must be either a branch, or a revision on the main trunk that is higher than any existing revision number
-cRefuse to commit files unless the user has registered a valid edit on the file via cvs edit.
-F fileRead the log message from file, instead of invoking an editor.
-m "log message goes here"Use message as the log message, instead of invoking an editor.
-fForce cvs to commit a new revision even if you haven't made any changes to the file. Causes the -c and -R (default) options are ignored.

Add/Delete files:

Add a new file to your project:
      cvs add file.c         
Multiple files can be specified on the command line:
      cvs add fileA.c fileB.c fileC.c        

Add a new directory "dirname/" and its files (and all sub-directories and files recursively), to your project:
      find dirname/ -type d \! -name CVS -exec cvs add {} \;
      find dirname/ \( -type d -name CVS -prune \) -o \( -type f -exec cvs add {} \; \)
      cvs commit -m "Programmer comments go here" dirname/

Note that if you specified a CVSEDITOR environment variable and no commit comments are added, the editor specified will pop-up for each and every directory to allow you to enter a check-in comment. CVS will get its commit/check-in comments.

Delete a file/directory from your project:

      cvs delete file.c         
The additions/deletions only fully take place after a check-in (commit) of the repository is performed.


The term "ProgABC" in our example is the name of a module as defined by the modules file found in CVSROOT/modules. To add a new module:
      cvs co CVSROOT/modules
vi modules - Add module name and path to file

Then update changes:
      cvs ci -m "Add comments here" modules
cd ..
cvs release -d CVSROOT

The module "ProgABC" is a short name for "$CVSROOT/ProgABC"

Web cgi script cvsmodules to list all modules available for check-out.

Tagging a build/revision

Tag a revision such that the current build is known to be made up of particular releases of various files.

      cvs tag Rel-1A ProgABC 
Where Rel-1A is the tag name for the build of module "ProgABC"

Tag a repository (directory/module) to add the symbolic name to the "snapshot" of the current sources. Tag the repository before check-in.

If bug fixes are added afterwards, only those files which have been changed need be re-tagged.

To relocate a tag that already exists to a newer set of code:

      cvs tag -F Rel-1A ProgABC 


      cvs diff file.c 
This will compare the version of the file in your working directory with that of the original you checked out.

The following will compare the two revisions of the file.

      cvs diff -r 1.1 -r 1.2 file.c 

Command: cvs diff [-lR] [-k kflag] [format_options] [(-r rev1[:date1] | -D date1) [-r rev2[:date2] | -D date2]] [files...]

Diff Command OptionDescription
-lLocal; run only in current working directory.
-RDefault behavior. Checkout directories recursively.
-r tag[:date]Compare with revision specified by tag or, when date is specified and tag is a branch tag, the version from the branch tag as it existed on date.
-D dateUse the most recent revision no later than date.
-linesShow lines (an integer) lines of context.
-aTreat all files as text and compare them line-by-line, even if they do not seem to be text.
-bIgnore trailing white space.
-BIgnore changes that just insert or delete blank lines.
--briefReport only whether the files differ, not the details of the differences.
--ignore-all-spaceIgnore white space when comparing lines.
--ignore-blank-linesIgnore changes that just insert or delete blank lines.
--ignore-caseIgnore changes in case; consider upper- and lower-case to be the same.
--side-by-sideUse the side by side output format.
-wIgnore white space when comparing lines.
Other advanced options include: -k, --binary, -c, -C, --context, --changed-group-format, -d, -e, --ed, --expand-tabs, -f, -F, --forward-ed, -H, --horizon-lines, -i, ...


[Potential Pitfall]: If a file becomes locked and you need to remove the lock from the CVS repository remove the lock files. (files beginning with "#")


Also see:

CVS GUI tkcvs:

TkCVS is a Tcl/Tk-based graphical front-end to CVS (and Subversion and RCS). It includes TkDiff for file diffs and merges. TkCVS is used for tagging, merging, importing, exporting, checking in/out, file query and status of CVS managed files.


  • Ubuntu: sudo apt-get install tkcvs
  • Red Hat/Fedora/CentOS: rpm -ivh tkcvs-8.2.2-1.el6.rf.noarch.rpm
    This RPM is available from the EPEL (Extra Packages for Enterprise Linux) website.
    Requires tcl and tk.


It is intuitive and easy to use. Start in your local working directory from the command line with the command: tkcvs

CVS GUI front-end tkcvs


GUI Front-Ends to CVS:


"Open Source Development with CVS"
Karl Fogel
ISBN #158880173X, Coriolis Open Press.

The only book I know of which is totally dedicated to the topic of CVS.


    Bookmark and Share