Section 6.5. CVSROOT Files

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 administrative 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 number of people authorized to commit or edit files in the CVSROOT directory.

It's good practice to have a specific user be the owner of the CVSROOT directory and the repository root directory, and for this user to also be the initial owner of the CVSROOT files. This practice restricts the amount of damage that can be done to these files by a malicious or careless user, unless she happens 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 writable 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.

Example 6-3 shows a CVSROOT directory and its permissions. The initial owner of the files is cvsown, the group with write permissions to the directory is cvsgrp. The cvsusrs group consists of those authorized to use CVS, but not to modify the repository administrative files.

Example 6-3. CVSROOT permissions

 /home/cvs/CVSROOT$ ls -la drwxrwsr-x   4 cvsown    cvsgrp  4096 2006-08-08 04:13 . drwxrwsr-x  63 cvsown    cvsgrp  4096 2006-08-05 09:02 .. -r--r--r--   1 cvsown    cvsgrp    495 2006-05-13 22:02 checkoutlist -r--r--r--   1 cvsown    cvsgrp    695 2006-05-13 22:02 checkoutlist,v -r--r--r--   1 cvsown    cvsgrp     35 2003-08-07 22:36 commitinfo -r--r--r--   1 cvsown    cvsgrp   1308 2006-05-13 22:02 commitinfo,v -r--r--r--   1 cvsown    cvsgrp     15 2002-10-16 23:49 config -r--r--r--   1 cvsown    cvsgrp   1902 2006-05-13 22:02 config,v -r--r--r--   1 cvsown    cvsgrp    602 2006-05-13 22:02 cvswrappers -r--r--r--   1 cvsown    cvsgrp    802 2006-05-13 22:02 cvswrappers,v -rw-rw-r--   1 cvsown    cvsusrs 34507 2006-08-08 05:25 history -r--r--r--   1 cvsown    cvsgrp    403 2001-09-26 01:00 loginfo -r--r--r--   1 cvsown    cvsgrp   2139 2001-09-26 01:00 loginfo,v -r--r--r--   1 cvsown    cvsgrp    587 2003-01-26 06:46 modules -r--r--r--   1 cvsown    cvsgrp   1351 2006-05-13 22:02 modules,v -r--r--r--   1 cvsown    cvsgrp    752 2006-05-13 22:02 notify -r--r--r--   1 cvsown    cvsgrp    952 2006-05-13 22:02 notify,v -r---r-----   1 cvsown    cvsgrp      0 2002-10-17 00:08 passwd -r--r--r--   1 cvsown    cvsgrp    649 2006-05-13 22:02 rcsinfo -r--r--r--   1 cvsown    cvsgrp    849 2006-05-13 22:02 rcsinfo,v -r--r--r--   1 cvsown    cvsgrp   2096 2006-05-13 22:02 taginfo -r--r--r--   1 cvsown    cvsgrp   2296 2006-05-13 22:02 taginfo,v -rw-rw-r--   1 cvsown    cvsusrs   114 2002-09-13 07:30 val-tags -r--r--r--   1 cvsown    cvsgrp   1357 2006-05-13 22:02 verifymsg -r--r--r--   1 cvsown    cvsgrp   1557 2006-05-13 22:02 verifymsg,v 

We have this directory locked down fairly tightlythe only writable files are history and val-tags, and those are only writable by the members of cvsusrs. The other files (except for passwd) can be read by anyone, and checked out by anyone, but only those in cvsgrp can commit to them. (Note that write access to the directory is sufficient to permit committing.) We could improve security by further restricting read access to the files.

Files with a ,v extension are the RCS format repository copies; the ones without are the clear-text versions that CVS reads. The passwd file is normally edited in place rather than checked out, and in this case has never been used.

It is possible to commit an administrative file that has settings that prevent CVS from committing anything else. If this happens, you can edit the clear-text repository copy of the file directly to enable CVS to commit again. To ensure that your version-controlled copy matches with the hand-edited copy, overwrite your sandbox copy with the corrected, hand-edited copy and commit the sandbox again.

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 most useful of the configuration options:


This option is a repository-wide version of the -X command option to cvs import: during an import, new files are added only to the vendor branch, and not to the trunk. Chapter 7 explains vendor branches.


This option controls which keywords may be expanded. It affects all files in all projects in the repository it's configured in. The value is in the format i|e[keyword list], where keyword list is a comma-separated list of keywords. The keywords may be any of the standard CVS keywords, or any local keyword as defined in the LocalKeyword configuration option (see the following entry).

If the first character is i, the keywords in the list will be the only keywords which CVS expands. If the first character is e, the keywords in the list will not be expanded. A typical entry might be KeywordExpand=Author, Id, Locker, which would limit expansion to the Author, ID, and Locker keywords.


This option creates a keyword that is local to the current repository, which is an alias for one of the existing keywords. For example, you could use LocalKeyword=Filename=RCSfile, which would mean you could use $Filename$ instead of $RCSfile$ as the keyword that generates the name of the current file. (Or Path=Source to get the full path from the repository root.)


This option is available only in CVS versions 1.10.2 and later. If this setting is enabled, CVS puts lock files in the nominated directory rather than in the repository. This option allows you to set the repository directories to read only for people who should not be committing changes.

You need to create directory, but CVS creates all of 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 patched.


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 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.

If your repository is for public use, you should probably keep this option set to no. Your end users may want to have sandboxes from various different repositories in the same directory, and a CVS subdirectory in that directory may cause unexpected effects (such as CVS/Root overriding the CVSROOT environment variable). TopLevelAdmin is valid in CVS 1.9.29 and later.


This option is available in CVS 1.12.1 and later. If value exists, then any user can run cvs admin options listed in value. The contents of value must be a string of letters with no separators or spaces, and the letters must be the command options (without parameters) for cvs admin.

If the cvsadmin group exists on the server machine, then only members of the cvsadmin group are allowed to run commands not listed in value.

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

Example 6-4. CVSROOT/config

 SystemAuth=no LockDir=/var/lock/cvs LogHistory=TMAR 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 specified filter program every time the file leaves the repository.

-t path_to_filter

Process the file through the specified 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 "Scripting Files," later 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 of its use (see 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 inputstdin, 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.

If you allow a Perl script to be run from these scripting files, ensure that taint-checking is enabled. You do this with the -T option in the #! line of the script, e.g., #!/usr/local/bin/perl -T. (In Perl 4, use taintperl instead: #!/usr/local/bin/taintperl.)

Read perldoc perlsec for more information on Perl security.

These files usually are configured on a per-project basis, so Chapter 7 explains them in detail. This chapter provides only a basic summary. The syntax of the files changed in CVS 1.12.6, and new files were added in 1.12.10.

In the old format, the syntax is a series of lines, each containing information in the following pattern:

 name_pattern action 

The name_pattern specifies 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.

The new format is explained in Chapter 7. commitinfo

The commitinfo file indicates programs to run while a commit is being processed, before the file is written to the repository. 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. It has been removed as of CVS 1.12.2.

In CVS versions that use editinfo, the file 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. postadmin

The postadmin file was added in CVS 1.12.10. It specifies scripts to be run immediately after any cvs admin command which changes one or more project files. postproxy

The postproxy file was added in CVS 1.12.10. It specifies scripts to be run immediately after a secondary server has connected to a primary server, before the secondary server permits the client to use the connection.

Of all the scripting files, this and preproxy are most likely to be of interest to a repository administrator. See Chapter 7 for detailed information on this file. posttag

The posttag file was added in CVS 1.12.10. It specifies scripts to be run immediately after any cvs tag or rtag command that changes one or more project files. postwatch

The postwatch file was added in CVS 1.12.10. It specifies scripts to be run immediately after any cvs edit, unedit, or watch command that changes the CVS watch administration file (fileattr). preproxy

The preproxy file was added in CVS 1.12.10. It specifies scripts to be run before a secondary server has connected to a primary server, after the client has requested the connection.

Of all the scripting files, this and postproxy are most likely to be of interest to a repository administrator. See Chapter 7 for detailed information on this file. rcsinfo

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

The taginfo file specifies 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 programs exit with a nonzero exit status, the tag will not proceed. verifymsg

The verifymsg file specifies 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 that 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-5 shows a checkoutlist file.

Example 6-5. CVSROOT/checkoutlist

 passwd 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-6 shows a cvsignore file.

Example 6-6. 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 shortly.

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 writable by all CVS users, and it is created by cvs init to be owner- and group-writable. This file should not be edited manually; all changes should occur through CVS.

If you wish to turn history logging off, 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. val-tags

The val-tags file contains a list of valid tag names, acting as an internal cache for CVS. It must be writable by all CVS users, and it is created by cvs init to be owner- and group-writable. 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 variable 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-7 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-7. 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.

Essential CVS
Essential CVS (Essentials)
ISBN: 0596527039
EAN: 2147483647
Year: 2006
Pages: 148

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: