home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam    

  Previous section   Next section

6.5 CVSROOT Files

The CVSROOT directory contains administrative files that contain information about the projects stored in CVS. The CVSROOT directory can be checked out to a sandbox, edited, and committed in the same way as any other directories or files managed by CVS.

As part of the process of committing an administrative file, CVS exports a clear-text copy into the CVSROOT directory. The CVSROOT directory contains both RCS-format repository copies of administrative files and clear-text copies of the latest revision of the files. The RCS-format files are named filename,v. While CVS is creating the clear-text copies, it prints the message cvs commit: Rebuilding admnistrative file database.

Some of the files in CVSROOT allow you to run user-created scripts during the execution of CVS commands. Therefore, it's important to restrict the people authorized to commit or edit files in the CVSROOT directory.

It's good practice to have a specific username to own the CVSROOT directory and the repository root directory, and to be the initial owner of the CVSROOT files. This restricts the amount of damage that can be done to these files by a malicious or careless user, unless they happen to have root permissions.

Create a group to have the group ownership of the CVSROOT directory and files, and include only trusted people in that group. If this group should be permitted to create new projects, and consists of all the people who can, it can also own the repository root directory. The CVSROOT directory and most of the files should be writable only by the repository's owner and the group, but they must be readable by all users who will be running CVS commands. The directory's SGID bit should be set, to ensure that new files are created with the same group ownership as the directory.

Two files in the CVSROOT directory should be writeable by all the users who will be using the CVS commands: the history and val-tags files. These files may have a different group ownership than the rest of the files in this directory.

It is possible to commit an administrative file that has settings that prevent CVS from commiting anything else. If this happens, you can edit the clear-text repository copy of the file directly to correct the problem.

6.5.1 Configuration Files

The files described in the next few subsections allow you to modify CVS's behavior. Three of these files are explained in more detail in chapters about the tasks the files are associated with, but the config file is fully explained here. config

The config file contains CVS configuration options. Lines that start with a # are comments. Other lines are in the form keyword=value, one pair per line. Whitespace is significant, including carriage returns, tabs, and extra spaces.

These are the available configuration options:


This option is available only in CVS Versions 1.10.2 and later.

If this setting is present, CVS puts lock files in the nominated directory rather than in the repository. This allows you to set the repository directories read-only for people who should not be committing changes.

You need to create directory, but CVS will create all the necessary subdirectories itself.

Do not use LockDir if any of your users are running CVS 1.9 or earlier and accessing a local repository, as users will then be putting locks in two different places and not honoring each other's locks. CVS 1.10 doesn't use LockDir; it displays an error and does not work. Versions prior to 1.10 ignore LockDir silently.


The text in value controls which actions are logged to the history file in the repository's CVSROOT directory. The valid values are any combination of the following letters:


Log when a file is added to the repository.


Log when a file would have been updated in a sandbox, but needed to be merged and there were conflicts in the merge.


Log when a file or files are exported.


Log when a file or files are released.


Log when a file is updated in a sandbox with a successful merge.


Log when a file is modified (a sandbox revision is added to the repository).


Log when a file or files are checked out.


Log when a file is removed from the repository.


Log when a file or files are tagged or rtagged.


Log when a file is updated in a sandbox with no merge required.


Log when a file is deleted from a sandbox during an update because it is no longer active in the repository.


This option provides the directory in which CVS should look for the rcs program. It applies only to CVS Versions 1.9.12 to 1.9.18; it is obsolete and ignored in later versions.


This option is useful only if the verifymsg file in the repository's CVSROOT directory is in use. It applies to CVS Versions 1.11.2 and later.

The log message saved during cvs commit might be changed if the verifymsg file is in use. This option controls whether the message is reread after the program listed in verifymsg file is run.

These are the available options:

always or yes

Reread the log message after the verifymsg file has been processed. This is the default case.

never or no

Do not reread the log message after the verifymsg file has been processed.


Check whether the log message has been changed, using the filesystem's stat( ) command. If the log message has changed, reread it. This option can take up to an extra second per directory to process.


This option is useful only if the client connects to CVS in pserver mode. It applies to CVS Versions 1.9.14 and later.

If value is yes, the server authenticates the connecting user with the passwd file in the repository's CVSROOT directory. If the user fails to authenticate there, the server authenticates the user against the main user database for the operating system.

If value is no, the server authenticates the user only against the passwd file.

The default value is yes. Consider setting the value to no if you run pserver, as the pserver access mode transmits passwords with minimal security. See Chapter 8 for more information.


If value is yes, a CVS subdirectory is created in the current working directory when you check out a sandbox.

If value is no, the CVS subdirectories are created only in the actual sandbox directory tree. The default is no.

The yes setting is useful if you run CVS commands in the working directory above your sandboxes. The CVS subdirectory contains a Root file, so you don't need to specify the -d repository option to CVS commands. If you use other CVS subdirectory files (such as Template), they will also be stored in the CVS subdirectory.

TopLevelAdmin is valid in CVS 1.9.29 and later.


The current version of CVS (CVS 1.11.5) does not support this option. In the versions that support it, this option causes CVS to store the sandbox permissions in the repository with other data for each revision and pass that data to the sandbox when a file revision is checked out. The valid values are yes and no.

The PreservePermissions code is not reliable. Setting it to yes is not recommended, even in CVS versions that support it.

Example 6-3 shows a configuration file (with all comments removed).

Example 6-3. CVSROOT/config
RereadLogAfterVerify=stat cvswrappers

The cvswrappers file contains a line-separated list of wrappers that control the merge method or keyword-substitution mode of files, based on a filename pattern. Wrappers are explained in Chapter 3.

There are two additional functions for wrappers. These are not available in CVS 1.11.5, so check the documentation for your version before relying on them. They are:

-f path_to_filter

Process the file through the filter program every time the file leaves the repository.

-t path_to_filter

Process the file through the filter program every time the file enters the repository. modules

The modules file contains information about projects in the repository and can group arbitrary files or directories into a single module. Information in this file must be created by the repository or project administrator; CVS does not update this file when a new project is imported.

Once a module is defined, the project files and directories it defines can be checked out into a sandbox using either the module name or the name of the repository directory it represents. A module can represent a directory and all its files and subdirectories, a file, or any collection of such files or directories. Directories can also be excluded from a module explicitly.

Module definitions are useful for splitting a project into several virtual projects, especially when you need to have several projects that share common files. You can also use module definitions to merge projects into a single virtual project.

If you intend to use modules for project organization, be aware that modules are not versioned. If you change the structure of the project, you may not be able to retrieve old releases with the module names in effect at the time those releases were current.

For example, if you create an animal project with elephant and turtle subprojects, then later change the name of turtle to tortoise, there is no way to record that versions of the project prior to the change use turtle and versions after the change use tortoise.

The modules file can also specify programs to run when files in the module are committed, exported, updated, checked out, or tagged with rtag. These programs can be used to integrate CVS with bug trackers or other project-management or program-development tools. The developers of CVS recommend that you use the scripting files rather than the options in the modules file.

Use the files described in Section 6.5.2 in this chapter to define programs to run during the operation of certain commands.

Chapter 7 explains the modules file in detail. notify

The notify file contains the commands to run when conditions exist for cvs watch to notify a user of a change to a watched file. Chapter 5 explains uses for the notify file and provides an example in Example 5-1.

The syntax of the notify file is a series of lines, each line appearing as follows:

filename-pattern command

The filename pattern can be ALL or it can be any CVS standard pattern, as used in cvsignore and cvswrappers and explained in Chapter 11. The command can be any sh shell command, but it must contain a %s, which is replaced by the name of the user to notify. The rest of the notification information is provided to the command through standard input -- stdin, in Unix or Linux.

CVS does not notify you of your own changes to a file.

6.5.2 Scripting Files

The files described in this section control scripts that run at specific times when the repository is modified. They can be used to interface CVS to bug-management or change-tracking systems, integrated development environments, or other tools; to enforce compliance with a project policy; or to trigger processes such as automated export programs to keep an up-to-date copy of the project files on a file server.

These files usually are configured on a per-project basis, so Chapter 7 explains them in more detail. For most of the files, the syntax is a series of lines, each containing information in the following pattern:

name_pattern action

The name pattern defines which files the action is run for and may include the project's root directory. The action is used to specify programs, and the programs defined in these files are passed the results or parameters of CVS commands, either as parameters or via standard input. commitinfo

The commitinfo file defines programs to run before a file is committed. Typical uses include determining whether a file meets your project's coding standards or whether a system configuration file has the correct syntax. If any of the programs exit with a nonzero exit status, the commit will not proceed. editinfo

The editinfo file is obsolete and has been replaced effectively by verifymsg and rcsinfo.

In CVS versions that use editinfo, it enforces the use of a specific editor when entering log messages. If CVS is called from a remote client or if the -m or -F command options are used with cvs commit, the editinfo file is not used. If the editor exits with a nonzero exit status, the commit will not proceed. loginfo

The loginfo file defines programs to run when a file has been committed successfully. The loginfo file is intended as a way to record log messages to specific places, such as a ChangeLog generation program, but is often used to trigger automated export programs. rcsinfo

The rcsinfo file does not actually trigger any scripts, but it uses the same syntax as the scripting files. It defines forms to be displayed as the template for commit log messages. taginfo

The taginfo file defines programs to run before a file is tagged. Typical uses include determining whether tag names meet your project's standards, and logging tags. If any of the the programs exit with a nonzero exit status, the tag will not proceed. verifymsg

The verifymsg file defines programs to run after a log message for a commit has been entered but before the commit takes place. The programs are passed the log message and can modify it or parse it to ensure that all essential fields have been filled in. The verifymsg file usually is used in tandem with the rcsinfo file to manage log messages and sometimes to interact with bug-tracking programs. If any of the programs exit with a nonzero error status, the commit is aborted.

6.5.3 Informational Files

The files in this section contain information CVS refers to when processing commands. You can set the information for most of these files, but history and val-tags should be written to only by CVS. checkoutlist

The checkoutlist file contains a list of user-defined files stored in the CVSROOT directory and exported into that directory when they're committed, in the same way that the standard administrative files are. This can be a useful way to store user-defined scripts for the other administrative files.

The file format is simply a list of the names of the files, one file per line. Paths are not needed; all files must belong in the CVSROOT directory. Example 6-4 shows a checkoutlist file.

Example 6-4. CVSROOT/checkoutlist
wiz_bugzilla cvsignore

The cvsignore file contains a list of filenames or filename patterns indicating files that CVS should not attempt to store in the repository. These files are also ignored when CVS displays informational messages, such as during update, commit, or status commands. The syntax for this file is a space-separated or line-ending-separated list of filenames or name patterns. Example 6-5 shows a cvsignore file.

Example 6-5. CVSROOT/cvsignore
*~ ignoreme ChangeLog
test.prog testing* a?out

In any of the lists of filenames to be ignored, the special filename ! causes CVS to clear the ignore list. While creating its ignore list, if CVS encounters a ! in a list of patterns to be ignored, it clears the list it has created to that point and starts a new ignore list with the next filename pattern it encounters.

The ! makes sense when you understand how CVS builds up its complete ignore list. I describe that process soon.

The special filename * causes CVS to ignore everything. cvsignore uses the standard CVS pattern matching explained in Chapter 11

The cvsignore file is space-separated, so it is difficult to ignore filenames that include spaces. You can attempt to work around this problem using the pattern-match syntax foo?bar, but that not only matches the file foo bar, it also matches fooxbar and foombar. Unfortunately, there is no perfect solution for ignoring filenames that contain spaces.

CVS includes a default list of filenames and filename patterns that are either CVS special files or common files that users don't want to store, such as C object code files. The default list is coded into the CVS source code:

. .. core RCSLOG tags TAGS RCS SCCS .make.state
 .nse_depinfo #* .#* cvslog.* ,* CVS CVS.adm .del-* *.a *.olb *.o *.obj
 *.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.exe _$* *$

There are many places where you can specify files for CVS to ignore. Not only can you have a cvsignore file in your repository's CVSROOT directory, but all CVS users can also have their own .cvsignore (note the dot) files in their home directories or in subdirectories in a sandbox. Files to ignore can also be specified via environment variables and command-line options. CVS generates the list of files to ignore in the following sequence:

  1. Create the ignore list with the default filenames and filename patterns.

  2. Add the entries from cvsignore in the repository's CVSROOT directory.

  3. Add the entries from .cvsignore in the user's home directory. (The .cvsignore file is explained later in this chapter.)

  4. Add the entries from the user's CVSIGNORE environment variable.

  5. Add the entries from the -I command option.

  6. Add the entries from the .cvsignore file in the current sandbox directory. These entries apply only to the directory they are in, not to any subdirectories. Each sandbox directory or subdirectory, excluding the administrative CVS directories, can have a .cvsignore file. (The sandbox .cvsignore file is explained later in this chapter.)

The CVS command-line option -I ! causes CVS to process every file, except any files that are specified in .cvsignore in the sandbox (or, if importing, the import directory). That's because -I ! resets the ignore list at step 5 in the previous list. This behavior is extremely useful when you're using cvs import on a directory that contains only files that you want to store, as it ensures that every file in the directory is added to the CVS repository even if it would otherwise be ignored. Later versions of CVS may alter the processing sequence so that -I ! will clear sandbox .cvsignore lists too. history

The history file contains the information displayed by the cvs history command. It must be writeable by all CVS users, and it is created by cvs init to be owner- and group-writeable. This file should not be edited manually; all changes should occur through CVS.

If you wish to turn history logging off, simply rename the history file. passwd

The passwd file contains the usernames and passwords used for the pserver remote-access method. Chapter 8 explains this file.

This file usually is edited in place, not checked out like the other administrative files. If you wish to check it out, add it to the commitinfo file, but be aware of the security risks explained in Chapter 8. readers

The readers file contains the usernames of people who have read-only access to the repository via the pserver remote-access method. (Also see the writers administrative file.) Chapter 8 explains this file. users

The users file provides a list of email addresses for users whose mailboxes are not on the same machine as the CVS repository. This list is used by the command given in the notify file, and the email address provided for the relevant username becomes the input represented by the %s string.

The format of this file is a separate line for each user, each line consisting of the username and the email address to send notifications to:


Chapter 5 explains the use of this file and provides an example in Example 5-2. val-tags

The val-tags file contains a list of valid tag names, acting as an internal cache for CVS. It must be writeable by all CVS users, and it is created by cvs init to be owner- and group-writeable. This file should not be edited manually; all changes should occur through CVS. writers

This file contains the usernames of people who have read-write access to the repository via the pserver remote-access method. If this file exists, any username not in this file is given read-only access. A username listed in both writers and readers is given read-only access. Chapter 8 explains the readers and writers files.

6.5.4 Variable Expansion

The administrative files in CVSROOT can use several types of variables, including internal, user-defined, environment, and shell variables.

The syntax to use when referencing CVS internal variables is ${VARIABLE}. If the character immediately following the variable is neither alphanumeric nor an underscore (_), you can use the alternative syntax $VARIABLE. These are the internal variables:


The path to the repository root directory (not to the CVSROOT directory within the repository). This variable contains the path only; it does not contain any access method or host information.


The editor CVS calls for commit or import commands. This is calculated after the -e CVS option or the client's environment variables have been read.


The path to the rcs program. This variable applies only to CVS 1.9.18 or earlier.


The username (on the server machine, if in client/server mode) of the user running CVS.

In the pserver access method, USER represents the third field of the appropriate line in the passwd file in the repository's CVSROOT directory; or, if there is no username there, USER is the name in the leftmost field.

CVS recognizes two shell variables within the CVS administrative files:


The home directory of the user calling the CVS process.


The home directory of the user identified as username.

CVS sets three environment variables in the environments of scripts run via the CVS administrative files:


This variable is meaningful only with the pserver access method. It refers to the CVS-specific username provided in the leftmost field of the appropriate line in the passwd file in the repository's CVSROOT directory. If this username does not exist, the variable expands to an empty string.


The username of the user calling the CVS process. In the pserver access method, this is the third field of the line in the passwd file; or, if there is no username there, LOGNAME or USER is the same as the CVS_USER.

CVS permits user-defined variables that can be passed to administrative files from the client, allowing CVS users to pass information to the scripts and commands set up by project leads and repository administrators. In an administrative file, read such a variable with the syntax ${=VARIABLE}. In the command line, use the -s variable=value CVS option to pass the variable to CVS.

Example 6-6 shows how to call CVS while providing and defining the user variable ${=TESTDIR}. Use the variable ${=TESTDIR} in one of the administrative files under CVSROOT.

Example 6-6. User-defined variables
cvs -s TESTDIR=/home/jenn/tests commit

I suggest using the contents of ${=TESTDIR} to point to either a location for test files, or a source of test data. In an administrative file (possibly the loginfo file described in Chapter 7), I suggest calling a test script with the ${=TESTDIR} variable as a parameter to the script. The loginfo file is read after the commit has been processed, so use that script to run an automated test suite over a program, using the contents of the directory provided with ${=TESTDIR} as the data for that test suite. If you have two teams working on the same project but with different test data or standards, you can use user-defined variables to allow each team to provide their own information source.

All strings that contain the $ symbol, other than the variables, are reserved for CVS internal use. There is no way to escape the $ symbol.

  Previous section   Next section