Alias modules
-------------

   Alias modules are the simplest kind of module:

`MNAME -a ALIASES...'
     This represents the simplest way of defining a module MNAME.  The
     `-a' flags the definition as a simple alias: CVS will treat any
     use of MNAME (as a command argument) as if the list of names
     ALIASES had been specified instead.  ALIASES may contain either
     other module names or paths.  When you use paths in aliases,
     `checkout' creates all intermediate directories in the working
     directory, just as if the path had been specified explicitly in
     the CVS arguments.

   For example, if the modules file contains:

     amodule -a first-dir

then the following two commands are equivalent:

     $ cvs co amodule
     $ cvs co first-dir

and they each would provide output such as:

     cvs checkout: Updating first-dir
     U first-dir/file1
     U first-dir/file2
     cvs checkout: Updating first-dir/sdir
     U first-dir/sdir/sfile

Regular modules
---------------

`MNAME [ options ] DIR [ FILES... ]'
     In the simplest case, this form of module definition reduces to
     `MNAME DIR'.  This defines all the files in directory DIR as
     module mname.  DIR is a relative path (from `$CVSROOT') to a
     directory of source in the source repository.  In this case, on
     checkout, a single directory called MNAME is created as a working
     directory; no intermediate directory levels are used by default,
     even if DIR was a path involving several directory levels.

   For example, if a module is defined by:

     regmodule first-dir

then regmodule will contain the files from first-dir:

     $ cvs co regmodule
     cvs checkout: Updating regmodule
     U regmodule/file1
     U regmodule/file2
     cvs checkout: Updating regmodule/sdir
     U regmodule/sdir/sfile
     $

   By explicitly specifying files in the module definition after DIR,
you can select particular files from directory DIR.  Here is an example:

     regfiles first-dir/sdir sfile

With this definition, getting the regfiles module will create a single
working directory `regfiles' containing the file listed, which comes
from a directory deeper in the CVS source repository:

     $ cvs co regfiles
     U regfiles/sfile
     $

Ampersand modules
-----------------

   A module definition can refer to other modules by including
`&MODULE' in its definition.
     MNAME [ options ] &MODULE...

   Then getting the module creates a subdirectory for each such module,
in the directory containing the module.  For example, if modules
contains

     ampermod &first-dir

then a checkout will create an `ampermod' directory which contains a
directory called `first-dir', which in turns contains all the
directories and files which live there.  For example, the command

     $ cvs co ampermod

will create the following files:

     ampermod/first-dir/file1
     ampermod/first-dir/file2
     ampermod/first-dir/sdir/sfile

   There is one quirk/bug: the messages that CVS prints omit the
`ampermod', and thus do not correctly display the location to which it
is checking out the files:

     $ cvs co ampermod
     cvs checkout: Updating first-dir
     U first-dir/file1
     U first-dir/file2
     cvs checkout: Updating first-dir/sdir
     U first-dir/sdir/sfile
     $

   Do not rely on this buggy behavior; it may get fixed in a future
release of CVS.

Excluding directories
---------------------

   An alias module may exclude particular directories from other
modules by using an exclamation mark (`!') before the name of each
directory to be excluded.

   For example, if the modules file contains:

     exmodule -a !first-dir/sdir first-dir

then checking out the module `exmodule' will check out everything in
`first-dir' except any files in the subdirectory `first-dir/sdir'.

Module options
--------------

   Either regular modules or ampersand modules can contain options,
which supply additional information concerning the module.

`-d NAME'
     Name the working directory something other than the module name.

`-e PROG'
     Specify a program PROG to run whenever files in a module are
     exported.  PROG runs with a single argument, the module name.

`-o PROG'
     Specify a program PROG to run whenever files in a module are
     checked out.  PROG runs with a single argument, the module name.
     See Module program options for information on how PROG is
     called.

`-s STATUS'
     Assign a status to the module.  When the module file is printed
     with `cvs checkout -s' the modules are sorted according to
     primarily module status, and secondarily according to the module
     name.  This option has no other meaning.  You can use this option
     for several things besides status: for instance, list the person
     that is responsible for this module.

`-t PROG'
     Specify a program PROG to run whenever files in a module are
     tagged with `rtag'.  PROG runs with two arguments: the module name
     and the symbolic tag specified to `rtag'.  It is not run when
     `tag' is executed.  Generally you will find that the `taginfo'
     file is a better solution (see taginfo).

   You should also see Module program options about how the
"program options" programs are run.

How the modules file "program options" programs are run
-------------------------------------------------------

For checkout, rtag, and export, the program is server-based, and as
such the following applies:-

   If using remote access methods (pserver, ext, etc.), CVS will
execute this program on the server from a temporary directory. The path
is searched for this program.

   If using "local access" (on a local or remote NFS file system, i.e.
repository set just to a path), the program will be executed from the
newly checked-out tree, if found there, or alternatively searched for
in the path if not.

   The programs are all run after the operation has effectively
completed.

The cvswrappers file
====================

   Wrappers refers to a CVS feature which lets you control certain
settings based on the name of the file which is being operated on.  The
settings are `-k' for binary files, and `-m' for nonmergeable text
files.

   The `-m' option specifies the merge methodology that should be used
when a non-binary file is updated.  `MERGE' means the usual CVS
behavior: try to merge the files.  `COPY' means that `cvs update' will
refuse to merge files, as it also does for files specified as binary
with `-kb' (but if the file is specified as binary, there is no need to
specify `-m 'COPY'').  CVS will provide the user with the two versions
of the files, and require the user using mechanisms outside CVS, to
insert any necessary changes.

   *WARNING: do not use `COPY' with CVS 1.9 or earlier - such versions
of CVS will copy one version of your file over the other, wiping out
the previous contents.* The `-m' wrapper option only affects behavior
when merging is done on update; it does not affect how files are
stored.  See Binary files, for more on binary files.

   The basic format of the file `cvswrappers' is:

     wildcard     [option value][option value]...

     where option is one of
     -m           update methodology      value: MERGE or COPY
     -k           keyword expansion       value: expansion mode

     and value is a single-quote delimited value.

   For example, the following command imports a directory, treating
files whose name ends in `.exe' as binary:

     cvs import -I ! -W "*.exe -k 'b'" first-dir vendortag reltag

The Trigger Scripts
===================

   Several of the administrative files support triggers, or the
launching external scripts or programs at specific times before or
after particular events, during the execution of CVS commands.  These
hooks can be used to prevent certain actions, log them, and/or maintain
anything else you deem practical.

   All the trigger scripts are launched in a copy of the user sandbox
being committed, on the server, in client-server mode.  In local mode,
the scripts are actually launched directly from the user sandbox
directory being committed.  For most intents and purposes, the same
scripts can be run in both locations without alteration.

The common syntax
-----------------

   The administrative files such as `commitinfo', `loginfo', `rcsinfo',
`verifymsg', etc., all have a common format.  The purpose of the files
are described later on.  The common syntax is described here.

   Each line contains the following:

   * A regular expression or the literal string `DEFAULT'.  Some script
     hooks also support the literal string `ALL'.  Other than the `ALL'
     and `DEFAULT' keywords, this is a basic regular expression in the
     syntax used by GNU emacs.  See the descriptions of the individual
     script hooks for information on whether the `ALL' keyword is
     supported (see Trigger Scripts).

   * A whitespace separator--one or more spaces and/or tabs.

   * A file name or command-line template.

Blank lines are ignored.  Lines that start with the character `#' are
treated as comments.  Long lines unfortunately can _not_ be broken in
two parts in any way.

   The first regular expression that matches the current directory name
in the repository or the first line containing `DEFAULT' in lieu of a
regular expression is used and all lines containing `ALL' is used for
the hooks which support the `ALL' keyword.  The rest of the line is
used as a file name or command-line template as appropriate.  See the
descriptions of the individual script hooks for information on whether
the `ALL' keyword is supported (see Trigger Scripts).

_Note:  The following information on format strings is valid as long as
the line `UseNewInfoFmtStrings=yes' appears in your repository's config
file (see config).  Otherwise, default format strings may be
appended to the command line and the `loginfo' file, especially, can
exhibit slightly different behavior.  For more information, see
Updating Commit Files._

   In the cases where the second segment of the matched line is a
command line template (e.g. `commitinfo', `loginfo', & `verifymsg'),
the command line template may contain format strings which will be
replaced with specific values before the script is run.

   Format strings can represent a single variable or one or more
attributes of a list variable.  An example of a list variable would be
the list available to scripts hung on the loginfo hooks - the list of
files which were just committed.  In the case of loginfo, three
attributes are available for each list item: file name, precommit
version, and postcommit version.

   Format strings consist of a `%' character followed by an optional
`{' (required in the multiple list attribute case), a single format
character representing a variable or a single attribute of list
elements or multiple format characters representing attributes of list
elements, and a closing `}' when the open bracket was present.

   _Flat format strings_, or single format characters which get replaced
with a single value, will generate a single argument to the called
script, regardless of whether the replacement variable contains white
space or other special characters.

   _List attributes_ will generate an argument for each attribute
requested for each list item.  For example, `%{sVv}' in a `loginfo'
command template will generate three arguments (file name, precommit
version, postcommit version, ...) for each file committed.  As in the
flat format string case, each attribute will be passed in as a single
argument regardless of whether it contains white space or other special
characters.

   `%%' will be replaced with a literal `%'.

   The format strings available to all script hooks are:

c
     The canonical name of the command being executed.  For instance,
     in the case of a hook run from `cvs up', CVS would replace `%c'
     with the string `update' and, in the case of a hook run from `cvs
     ci', CVS would replace `%c' with the string `commit'.

n
     The null, or empty, string.

p
     The name of the directory being operated on within the repository.

r
     The name of the repository (the path portion of `$CVSROOT').

R
     On a server, the name of the referrer, if any.  The referrer is
     the CVSROOT the client reports it used to contact a server which
     then referred it to this server.  Should usually be set on a
     primary server with a write proxy setup.

   Other format strings are file specific.  See the docs on the
particular script hooks for more information (see Trigger Scripts).

   As an example, the following line in a `loginfo' file would match
only the directory `module' and any subdirectories of `module':

     ^module\(/\|$\) (echo; echo %p; echo %{sVv}; cat) >>$CVSROOT/CVSROOT/commitlog

   Using this same line and assuming a commit of new revisions 1.5.4.4
and 1.27.4.1 based on old revisions 1.5.4.3 and 1.27, respectively, of
file1 and file2 in module, something like the following log message
should be appended to commitlog:

     module
     file1 1.5.4.3 1.5.4.4 file2 1.27 1.27.4.1
     Update of /cvsroot/module
     In directory localhost.localdomain:/home/jrandom/work/module

     Modified Files:
     	file1 file2
     Log Message:
     A log message.

Security and the Trigger Scripts
--------------------------------

   Security is a huge subject, and implementing a secure system is a
non-trivial task.  This section will barely touch on all the issues
involved, but it is well to note that, as with any script you will be
allowing an untrusted user to run on your server, there are measures
you can take to help prevent your trigger scripts from being abused.

   For instance, since the CVS trigger scripts all run in a copy of the
user's sandbox on the server, a naively coded Perl trigger script which
attempts to use a Perl module that is not installed on the system can
be hijacked by any user with commit access who is checking in a file
with the correct name.  Other scripting languages may be vulnerable to
similar hacks.

   One way to make a script more secure, at least with Perl, is to use
scripts which invoke the `-T', or "taint-check" switch on their `#!'
line.  In the most basic terms, this causes Perl to avoid running code
that may have come from an external source.  Please run the `perldoc
perlsec' command for more on Perl security.  Again, other languages may
implement other security verification hooks which look more or less
like Perl's "taint-check" mechanism.

The commit support files
------------------------

   The `-i' flag in the `modules' file can be used to run a certain
program whenever files are committed (see modules).  The files
described in this section provide other, more flexible, ways to run
programs whenever something is committed.

   There are three kinds of programs that can be run on commit.  They
are specified in files in the repository, as described below.  The
following table summarizes the file names and the purpose of the
corresponding programs.

`commitinfo'
     The program is responsible for checking that the commit is
     allowed.  If it exits with a non-zero exit status the commit will
     be aborted.  See commitinfo.

`verifymsg'
     The specified program is used to evaluate the log message, and
     possibly verify that it contains all required fields.  This is
     most useful in combination with the `rcsinfo' file, which can hold
     a log message template (see rcsinfo).  See verifymsg.

`loginfo'
     The specified program is called when the commit is complete.  It
     receives the log message and some additional information and can
     store the log message in a file, or mail it to appropriate
     persons, or maybe post it to a local newsgroup, or...  Your
     imagination is the limit!  See loginfo.

Updating legacy repositories to stop using deprecated command line template formats
...................................................................................

   New repositories are created set to use the new format strings by
default, so if you are creating a new repository, you shouldn't have to
worry about this section.

   If you are attempting to maintain a legacy repository which was
making use of the `commitinfo', `editinfo', `verifymsg', `loginfo',
and/or `taginfo' script hooks, you should have no immediate problems
with using the current CVS executable, but your users will probably
start to see deprecation warnings.

   The reason for this is that all of the script hooks have been
updated to use a new command line parser that extensibly supports
multiple `loginfo' & `notify' style format strings (see syntax) and
this support is not completely compatible with the old style format
strings.

   The quick upgrade method is to stick a `1' after each format string
in your old `loginfo' file.  For example:

     DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog

   would become:

     DEFAULT (echo ""; id; echo %1{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog

   If you were counting on the fact that only the first `%' in the line
was replaced as a format string, you may also have to double up any
further percent signs on the line.

   If you did this all at once and checked it in, everything should
still be running properly.

   Now add the following line to your config file (see config):
     UseNewInfoFmtStrings=yes

   Everything should still be running properly, but your users will
probably start seeing new deprecation warnings.

   Dealing with the deprecation warnings now generated by `commitinfo',
`editinfo', `verifymsg', and `taginfo' should be easy.  Simply specify
what are currently implicit arguments explicitly.  This means appending
the following strings to each active command line template in each file:
`commitinfo'
     ` %r/%p %s'

`editinfo'
     ` %l'

`taginfo'
     ` %t %o %p %{sv}'

`verifymsg'
     ` %l'

   If you don't desire that any of the newly available information be
passed to the scripts hanging off of these hooks, no further
modifications to these files should be necessary to insure current and
future compatibility with CVS's format strings.

   Fixing `loginfo' could be a little tougher.  The old style `loginfo'
format strings caused a single space and comma separated argument to be
passed in in place of the format string.  This is what will continue to
be generated due to the deprecated `1' you inserted into the format
strings.

   Since the new format separates each individual item and passes it
into the script as a separate argument (for a good reason - arguments
containing commas and/or white space are now parsable), to remove the
deprecated `1' from your `loginfo' command line templates, you will
most likely have to rewrite any scripts called by the hook to handle
the new argument format.

   Also note that the way `%' followed by unrecognized characters and by
`{}' was treated in past versions of CVS is not strictly adhered to as
there were bugs in the old versions.  Specifically, `%{}' would eat the
next character and unrecognized strings resolved only to the empty
string, which was counter to what was stated in the documentation.
This version will do what the documentation said it should have (if you
were using only some combination of `%{sVv}', e.g. `%{sVv}', `%{sV}', or
`%v', you should have no troubles).

   On the bright side, you should have plenty of time to do this before
all support for the old format strings is removed from CVS, so you can
just put up with the deprecation warnings for awhile if you like.

Commitinfo
----------

   The `commitinfo' file defines programs to execute whenever `cvs
commit' is about to execute.  These programs are used for pre-commit
checking to verify that the modified, added and removed files are really
ready to be committed.  This could be used, for instance, to verify
that the changed files conform to to your site's standards for coding
practice.

   The `commitinfo' file has the standard form for script hooks (see
Trigger Scripts), where each line is a regular expression followed by
a command to execute.  It supports only the DEFAULT keywords.

   In addition to the common format strings (see syntax),
`commitinfo' supports:

{s}
     a list of the names of files to be committed

   Currently, if no format strings are specified, a default string of `
%r/%p %{s}' will be appended to the command line template before
replacement is performed, but this feature is deprecated.  It is simply
in place so that legacy repositories will remain compatible with the
new CVS application.  For information on updating, see Updating Commit Files.

   The first line with a regular expression matching the directory
within the repository will be used.  If the command returns a non-zero
exit status the commit will be aborted.

   The command will be run in the root of the workspace containing the
new versions of any files the user would like to modify (commit), _or
in a copy of the workspace on the server (see Remote repositories)
_.  If a file is being removed, there will be no copy of
the file under the current directory.  If a file is being added, there
will be no corresponding archive file in the repository unless the file
is being resurrected.

   Note that both the repository directory and the corresponding Attic
(see Attic) directory may need to be checked to locate the archive
file corresponding to any given file being committed.  Much of the
information about the specific commit request being made, including the
destination branch, commit message, and command line options specified,
is not available to the command.

Verifying log messages
----------------------

   Once you have entered a log message, you can evaluate that message
to check for specific content, such as a bug ID.  Use the `verifymsg'
file to specify a program that is used to verify the log message.  This
program could be a simple script that checks that the entered message
contains the required fields.

   The `verifymsg' file is often most useful together with the
`rcsinfo' file, which can be used to specify a log message template
(see rcsinfo).

   The `verifymsg' file has the standard form for script hooks (see
Trigger Scripts), where each line is a regular expression followed by
a command to execute.  It supports only the DEFAULT keywords.

   In addition to the common format strings (see syntax),
`verifymsg' supports:

l
     the full path to the file containing the log message to be verified

   Currently, if no format strings are specified, a default string of `
%l' will be appended to the command line template before replacement is
performed, but this feature is deprecated.  It is simply in place so
that legacy repositories will remain compatible with the new CVS
application.  For information on updating, see Updating Commit Files.

   One thing that should be noted is that the `ALL' keyword is not
supported.  If more than one matching line is found, the first one is
used.  This can be useful for specifying a default verification script
in a directory, and then overriding it in a subdirectory.

   If the verification script exits with a non-zero exit status, the
commit is aborted.

   In the default configuration, CVS allows the verification script to
change the log message. This is controlled via the RereadLogAfterVerify
CVSROOT/config option.

   When `RereadLogAfterVerify=always' or `RereadLogAfterVerify=stat',
the log message will either always be reread after the verification
script is run or reread only if the log message file status has changed.

   See config, for more on CVSROOT/config options.

   It is NOT a good idea for a `verifymsg' script to interact directly
with the user in the various client/server methods. For the `pserver'
method, there is no protocol support for communicating between
`verifymsg' and the client on the remote end. For the `ext' and
`server' methods, it is possible for CVS to become confused by the
characters going along the same channel as the CVS protocol messages.
See Remote repositories, for more information on client/server
setups.  In addition, at the time the `verifymsg' script runs, the CVS
server has locks in place in the repository.  If control is returned to
the user here then other users may be stuck waiting for access to the
repository.

   This option can be useful if you find yourself using an rcstemplate
that needs to be modified to remove empty elements or to fill in
default values.  It can also be useful if the rcstemplate has changed
in the repository and the CVS/Template was not updated, but is able to
be adapted to the new format by the verification script that is run by
`verifymsg'.

   An example of an update might be to change all occurrences of
'BugId:' to be 'DefectId:' (which can be useful if the rcstemplate has
recently been changed and there are still checked-out user trees with
cached copies in the CVS/Template file of the older version).

   Another example of an update might be to delete a line that contains
'BugID: none' from the log message after validation of that value as
being allowed is made.

Verifying log messages
......................

   The following is a little silly example of a `verifymsg' file,
together with the corresponding `rcsinfo' file, the log message
template and a verification script.  We begin with the log message
template.  We want to always record a bug-id number on the first line
of the log message.  The rest of log message is free text.  The
following template is found in the file `/usr/cvssupport/tc.template'.

     BugId:

   The script `/usr/cvssupport/bugid.verify' is used to evaluate the
log message.

     #!/bin/sh
     #
     #       bugid.verify filename
     #
     #  Verify that the log message contains a valid bugid
     #  on the first line.
     #
     if sed 1q < $1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then
         exit 0
     elif sed 1q < $1 | grep '^BugId:[ ]*none$' > /dev/null; then
         # It is okay to allow commits with 'BugId: none',
         # but do not put that text into the real log message.
         grep -v '^BugId:[ ]*none$' > $1.rewrite
         mv $1.rewrite $1
         exit 0
     else
         echo "No BugId found."
         exit 1
     fi

   The `verifymsg' file contains this line:

     ^tc     /usr/cvssupport/bugid.verify %l

   The `rcsinfo' file contains this line:

     ^tc     /usr/cvssupport/tc.template

   The `config' file contains this line:

     RereadLogAfterVerify=always

Loginfo
-------

   The `loginfo' file is used to control where log information is sent
after versioned changes are made to repository archive files and after
directories are added ot the repository.  See posttag for how to
log tagging information and postadmin for how to log changes
due to the `admin' command.

   The `loginfo' file has the standard form for script hooks (see
Trigger Scripts), where each line is a regular expression followed by
a command to execute.  It supports the ALL and DEFAULT keywords.

   Any specified scripts are called:

`commit'
     Once per directory, immediately after a successfully completing
     the commit of all files within that directory.

`import'
     Once per import, immediately after completion of all write
     operations.

`add'
     Immediately after the successful `add' of a directory.

   Any script called via `loginfo' will be fed the log information on
its standard input.  Note that the filter program *must* read *all* of
the log information from its standard input or CVS may fail with a
broken pipe signal.

   In addition to the common format strings (see syntax), `loginfo'
supports:

{sVv}
     File attributes, where:
    s
          file name

    V
          old version number (pre-checkin)

    v
          new version number (post-checkin)

   For example, some valid format strings are `%%', `%s', `%{s}', and
`%{sVv}'.

   Currently, if `UseNewInfoFmtStrings' is not set in the `config'
administration file (see config), the format strings will be
substituted as they were in past versions of CVS, but this feature is
deprecated.  It is simply in place so that legacy repositories will
remain compatible with the new CVS application.  For information on
updating, please see Updating Commit Files.

   As an example, if `/u/src/master/yoyodyne/tc' is the repository, `%p'
and `%{sVv}' are the format strings, and three files (ChangeLog,
Makefile, foo.c) were modified, the output might be:

     yoyodyne/tc ChangeLog 1.1 1.2 Makefile 1.3 1.4 foo.c 1.12 1.13

   Note: when CVS is accessing a remote repository, `loginfo' will be
run on the _remote_ (i.e., server) side, not the client side (see
Remote repositories).

Loginfo example
...............

   The following `loginfo' file, together with the tiny shell-script
below, appends all log messages to the file
`$CVSROOT/CVSROOT/commitlog', and any commits to the administrative
files (inside the `CVSROOT' directory) are also logged in
`/usr/adm/cvsroot-log'.  Commits to the `prog1' directory are mailed to
ceder.

     ALL                     /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog $USER
     ^CVSROOT\(/\|$\)        /usr/local/bin/cvs-log /usr/adm/cvsroot-log $USER
     ^prog1\(/\|$\)          Mail -s "%p %s" ceder

   The shell-script `/usr/local/bin/cvs-log' looks like this:

     #!/bin/sh
     (echo "------------------------------------------------------";
      echo -n "$2  ";
      date;
      echo;
      cat) >> $1

Keeping a checked out copy
..........................

   It is often useful to maintain a directory tree which contains files
which correspond to the latest version in the repository.  For example,
other developers might want to refer to the latest sources without
having to check them out, or you might be maintaining a web site with
CVS and want every checkin to cause the files used by the web server to
be updated.

   The way to do this is by having loginfo invoke `cvs update'.  Doing
so in the naive way will cause a problem with locks, so the `cvs update'
must be run in the background.  Here is an example for unix (this
should all be on one line):

     ^cyclic-pages\(/\|$\)	(date; cat; (sleep 2; cd /u/www/local-docs;
      cvs -q update -d) &) >> $CVSROOT/CVSROOT/updatelog 2>&1

   This will cause checkins to repository directory `cyclic-pages' and
its subdirectories to update the checked out tree in
`/u/www/local-docs'.

Logging admin commands
----------------------

   The `postadmin' file defines programs to execute after an `admin'
command modifies files.  The `postadmin' file has the standard form for
script hooks (see Trigger Scripts), where each line is a regular
expression followed by a command to execute.  It supports the ALL and
DEFAULT keywords.

   The `postadmin' file supports no format strings other than the common
ones (see syntax),

Taginfo
-------

   The `taginfo' file defines programs to execute when someone executes
a `tag' or `rtag' command.  The `taginfo' file has the standard form
for script hooks (see Trigger Scripts), where each line is a
regular expression followed by a command to execute.  It supports the
ALL and DEFAULT keywords.

   In addition to the common format strings (see syntax), `taginfo'
supports:

b
     tag type (`T' for branch, `N' for not-branch, or `?' for unknown,
     as during delete operations)

o
     operation (`add' for `tag', `mov' for `tag -F', or `del' for `tag
     -d')

t
     tag name

{sVv}
     file attributes, where:
    s
          file name

    V
          old version number (for a move or delete operation)

    v
          new version number (for an add or move operation)

   For example, some valid format strings are `%%', `%p', `%t', `%s',
`%{s}', and `%{sVv}'.

   Currently, if no format strings are specified, a default string of `
%t %o %p %{sv}' will be appended to the command line template before
replacement is performed, but this feature is deprecated.  It is simply
in place so that legacy repositories will remain compatible with the
new CVS application.  For information on updating, see Updating Commit Files.

   A non-zero exit of the filter program will cause the tag to be
aborted.

   Here is an example of using `taginfo' to log `tag' and `rtag'
commands.  In the `taginfo' file put:

     ALL /usr/local/cvsroot/CVSROOT/loggit %t %b %o %p %{sVv}

Where `/usr/local/cvsroot/CVSROOT/loggit' contains the following script:

     #!/bin/sh
     echo "$@" >>/home/kingdon/cvsroot/CVSROOT/taglog

Logging tags
------------

   The `posttag' file defines programs to execute after a `tag' or
`rtag' command modifies files.  The `posttag' file has the standard
form for script hooks (see Trigger Scripts), where each line is a
regular expression followed by a command to execute.  It supports the
ALL and DEFAULT keywords.

   The `posttag' admin file supports the same format strings as the
`taginfo' file (see taginfo),

Logging watch commands
----------------------

   The `postwatch' file defines programs to execute after any command
(for instance, `watch', `edit', `unedit', or `commit') modifies any
`CVS/fileattr' file in the repository (see Watches).  The
`postwatch' file has the standard form for script hooks (see Trigger Scripts),
where each line is a regular expression followed by a
command to execute.  It supports the ALL and DEFAULT keywords.

   The `postwatch' file supports no format strings other than the common
ones (see syntax), but it is worth noting that the `%c' format
string may not be replaced as you might expect.  Client runs of `edit'
and `unedit' can sometimes skip contacting the CVS server and cache the
notification of the file attribute change to be sent the next time the
client contacts the server for whatever other reason,

Launch a Script before Proxying
-------------------------------

   The `preproxy' file defines programs to execute after a secondary
server receives a write request from a client, just before it starts up
the primary server and becomes a write proxy.  This hook could be used
to dial a modem, launch an SSH tunnel, establish a VPN, or anything
else that might be necessary to do before contacting the primary server.

   `preproxy' scripts are called once, at the time of the write
request, with the repository argument (if requested) set from the
topmost directory sent by the client.

   The `preproxy' file has the standard form for script hooks (see
Trigger Scripts), where each line is a regular expression followed by
a command to execute.  It supports the ALL and DEFAULT keywords.

   In addition to the common format strings, the `preproxy' file
supports the following format string:

P
     the CVSROOT string which specifies the primary server

Launch a Script after Proxying
------------------------------

   The `postproxy' file defines programs to execute after a secondary
server notes that the connection to the primary server has shut down
and before it releases the client by shutting down the connection to
the client.  This could hook could be used to disconnect a modem, an
SSH tunnel, a VPN, or anything else that might be necessary to do after
contacting the primary server.  This hook should also be used to pull
updates from the primary server before allowing the client which did
the write to disconnect since otherwise the client's next read request
may generate error messages and fail upon encountering an out of date
repository on the secondary server.

   `postproxy' scripts are called once per directory.

   The `postproxy' file has the standard form for script hooks (see
Trigger Scripts), where each line is a regular expression followed by
a command to execute.  It supports the ALL and DEFAULT keywords.

   In addition to the common format strings, the `postproxy' file
supports the following format string:

P
     the CVSROOT string which specifies the primary server

Rcsinfo
=======

   The `rcsinfo' file can be used to specify a form to edit when
filling out the commit log.  The `rcsinfo' file has a syntax similar to
the `verifymsg', `commitinfo' and `loginfo' files.  See syntax.
Unlike the other files the second part is _not_ a command-line
template.  Instead, the part after the regular expression should be a
full pathname to a file containing the log message template.

   If the repository name does not match any of the regular expressions
in this file, the `DEFAULT' line is used, if it is specified.

   All occurrences of the name `ALL' appearing as a regular expression
are used in addition to the first matching regular expression or
`DEFAULT'.

   The log message template will be used as a default log message.  If
you specify a log message with `cvs commit -m MESSAGE' or `cvs commit -f
FILE' that log message will override the template.

   See verifymsg, for an example `rcsinfo' file.

   When CVS is accessing a remote repository, the contents of `rcsinfo'
at the time a directory is first checked out will specify a template.
This template will be updated on all `cvs update' commands. It will
also be added to new directories added with a `cvs add new-directory'
command.  In versions of CVS prior to version 1.12, the `CVS/Template'
file was not updated. If the CVS server is at version 1.12 or higher an
older client may be used and the `CVS/Template' will be updated from
the server.

Ignoring files via cvsignore
============================

   There are certain file names that frequently occur inside your
working copy, but that you don't want to put under CVS control.
Examples are all the object files that you get while you compile your
sources.  Normally, when you run `cvs update', it prints a line for
each file it encounters that it doesn't know about (see update output).

   CVS has a list of files (or sh(1) file name patterns) that it should
ignore while running `update', `import' and `release'.  This list is
constructed in the following way.

   * The list is initialized to include certain file name patterns:
     names associated with CVS administration, or with other common
     source control systems; common names for patch files, object files,
     archive files, and editor backup files; and other names that are
     usually artifacts of assorted utilities.  Currently, the default
     list of ignored file name patterns is:

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

   * The per-repository list in `$CVSROOT/CVSROOT/cvsignore' is
     appended to the list, if that file exists.

   * The per-user list in `.cvsignore' in your home directory is
     appended to the list, if it exists.

   * Any entries in the environment variable `$CVSIGNORE' is appended
     to the list.

   * Any `-I' options given to CVS is appended.

   * As CVS traverses through your directories, the contents of any
     `.cvsignore' will be appended to the list.  The patterns found in
     `.cvsignore' are only valid for the directory that contains them,
     not for any sub-directories.

   In any of the 5 places listed above, a single exclamation mark (`!')
clears the ignore list.  This can be used if you want to store any file
which normally is ignored by CVS.

   Specifying `-I !' to `cvs import' will import everything, which is
generally what you want to do if you are importing files from a
pristine distribution or any other source which is known to not contain
any extraneous files.  However, looking at the rules above you will see
there is a fly in the ointment; if the distribution contains any
`.cvsignore' files, then the patterns from those files will be
processed even if `-I !' is specified.  The only workaround is to
remove the `.cvsignore' files in order to do the import.  Because this
is awkward, in the future `-I !' might be modified to override
`.cvsignore' files in each directory.

   Note that the syntax of the ignore files consists of a series of
lines, each of which contains a space separated list of filenames.
This offers no clean way to specify filenames which contain spaces, but
you can use a workaround like `foo?bar' to match a file named `foo bar'
(it also matches `fooxbar' and the like).  Also note that there is
currently no way to specify comments.

The checkoutlist file
=====================

   It may be helpful to use CVS to maintain your own files in the
`CVSROOT' directory.  For example, suppose that you have a script
`logcommit.pl' which you run by including the following line in the
`commitinfo' administrative file:

     ALL   $CVSROOT/CVSROOT/logcommit.pl %r/%p %s

   To maintain `logcommit.pl' with CVS you would add the following line
to the `checkoutlist' administrative file:

     logcommit.pl

   The format of `checkoutlist' is one line for each file that you want
to maintain using CVS, giving the name of the file, followed optionally
by more whitespace and any error message that should print if the file
cannot be checked out into CVSROOT after a commit:

     logcommit.pl	Could not update CVSROOT/logcommit.pl.

   After setting up `checkoutlist' in this fashion, the files listed
there will function just like CVS's built-in administrative files.  For
example, when checking in one of the files you should get a message
such as:

     cvs commit: Rebuilding administrative file database

and the checked out copy in the `CVSROOT' directory should be updated.

   Note that listing `passwd' (see Password authentication server)
in `checkoutlist' is not recommended for security reasons.

   For information about keeping a checkout out copy in a more general
context than the one provided by `checkoutlist', see Keeping a checked out copy.

The history file
================

   The file `$CVSROOT/CVSROOT/history' is used to log information for
the `history' command (see history).  This file must be created to
turn on logging.  This is done automatically if the `cvs init' command
is used to set up the repository (see Creating a repository).

   The file format of the `history' file is documented only in comments
in the CVS source code, but generally programs should use the `cvs
history' command to access it anyway, in case the format changes with
future releases of CVS.