summaryrefslogtreecommitdiff
path: root/doc/cvs.texinfo
diff options
context:
space:
mode:
Diffstat (limited to 'doc/cvs.texinfo')
-rw-r--r--doc/cvs.texinfo15923
1 files changed, 15923 insertions, 0 deletions
diff --git a/doc/cvs.texinfo b/doc/cvs.texinfo
new file mode 100644
index 0000000..b975de8
--- /dev/null
+++ b/doc/cvs.texinfo
@@ -0,0 +1,15923 @@
+\input texinfo @c -*-texinfo-*-
+@comment Documentation for CVS.
+@setfilename cvs.info
+@macro copyleftnotice
+@noindent
+Copyright @copyright{} 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+@multitable @columnfractions .12 .88
+@item Portions
+@item @tab Copyright @copyright{} 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Derek R. Price,
+@item @tab Copyright @copyright{} 2002, 2003, 2004, 2005
+ Ximbiot @url{http://ximbiot.com},
+@item @tab Copyright @copyright{} 1992, 1993, 1999 Signum Support AB,
+@item @tab and Copyright @copyright{} others.
+@end multitable
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by the Free Software Foundation.
+@end macro
+
+@comment This file is part of the CVS distribution.
+
+@comment CVS is free software; you can redistribute it and/or modify
+@comment it under the terms of the GNU General Public License as published by
+@comment the Free Software Foundation; either version 2, or (at your option)
+@comment any later version.
+
+@comment CVS is distributed in the hope that it will be useful,
+@comment but WITHOUT ANY WARRANTY; without even the implied warranty of
+@comment MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+@comment GNU General Public License for more details.
+
+@c See ../README for A4 vs. US letter size.
+@c When we provided A4 postscript, and people tried to
+@c print it on US letter, the usual complaint was that the
+@c page numbers would get cut off.
+@c If one prints US letter on A4, reportedly there is
+@c some extra space at the top and/or bottom, and the side
+@c margins are a bit narrow, but no text is lost.
+@c
+@c See
+@c http://www.ft.uni-erlangen.de/~mskuhn/iso-paper.html
+@c for more on paper sizes. Insuring that margins are
+@c big enough to print on either A4 or US letter does
+@c indeed seem to be the usual approach (RFC2346).
+
+@c This document seems to get overfull hboxes with some
+@c frequency (probably because the tendency is to
+@c sanity-check it with "make info" and run TeX less
+@c often). The big ugly boxes just seem to add insult
+@c to injury, and I'm not aware of them helping to fix
+@c the overfull hboxes at all.
+@finalout
+
+@include version.texi
+@settitle CVS---Concurrent Versions System v@value{VERSION}
+@setchapternewpage odd
+
+@c -- TODO list:
+@c -- Fix all lines that match "^@c -- "
+@c -- Also places marked with FIXME should be manual
+@c problems (as opposed to FIXCVS for CVS problems).
+
+@c @splitrcskeyword{} is used to avoid keyword expansion. It is replaced by
+@c @asis when generating info and dvi, and by <i></i> in the generated html,
+@c such that keywords are not expanded in the generated html.
+@ifnothtml
+@macro splitrcskeyword {arg}
+@asis{}\arg\
+@end macro
+@end ifnothtml
+
+@ifhtml
+@macro splitrcskeyword {arg}
+@i{}\arg\
+@end macro
+@end ifhtml
+
+@dircategory GNU Packages
+@direntry
+* CVS: (cvs). Concurrent Versions System
+@end direntry
+@dircategory Individual utilities
+@direntry
+* cvs: (cvs)CVS commands. Concurrent Versions System
+@end direntry
+
+@comment The titlepage section does not appear in the Info file.
+@titlepage
+@sp 4
+@comment The title is printed in a large font.
+@center @titlefont{Version Management}
+@sp
+@center @titlefont{with}
+@sp
+@center @titlefont{CVS}
+@sp 2
+@center for @sc{cvs} @value{VERSION}
+@comment -release-
+@sp 3
+@center Per Cederqvist et al
+
+@comment The following two commands start the copyright page
+@comment for the printed manual. This will not appear in the Info file.
+@page
+@vskip 0pt plus 1filll
+@copyleftnotice
+@end titlepage
+
+@summarycontents
+
+@contents
+
+@comment ================================================================
+@comment The real text starts here
+@comment ================================================================
+
+@ifnottex
+@c ---------------------------------------------------------------------
+@node Top
+@top
+
+This info manual describes how to use and administer
+@sc{cvs} version @value{VERSION}.
+@end ifnottex
+
+@ifinfo
+@copyleftnotice
+@end ifinfo
+
+@c This menu is pretty long. Not sure how easily that
+@c can be fixed (no brilliant ideas right away)...
+@menu
+* Overview:: An introduction to CVS
+* Repository:: Where all your sources are stored
+* Starting a new project:: Starting a project with CVS
+* Revisions:: Numeric and symbolic names for revisions
+* Branching and merging:: Diverging/rejoining branches of development
+* Recursive behavior:: CVS descends directories
+* Adding and removing:: Adding/removing/renaming files/directories
+* History browsing:: Viewing the history of files in various ways
+
+CVS and the Real World.
+-----------------------
+* Binary files:: CVS can handle binary files
+* Multiple developers:: How CVS helps a group of developers
+* Revision management:: Policy questions for revision management
+* Keyword substitution:: CVS can include the revision inside the file
+* Tracking sources:: Tracking third-party sources
+* Builds:: Issues related to CVS and builds
+* Special Files:: Devices, links and other non-regular files
+
+References.
+-----------
+* CVS commands:: CVS commands share some things
+* Invoking CVS:: Quick reference to CVS commands
+* Administrative files:: Reference manual for the Administrative files
+* Environment variables:: All environment variables which affect CVS
+* Compatibility:: Upgrading CVS versions
+* Troubleshooting:: Some tips when nothing works
+* Credits:: Some of the contributors to this manual
+* BUGS:: Dealing with bugs in CVS or this manual
+* Index:: Index
+@end menu
+
+@c ---------------------------------------------------------------------
+@node Overview
+@chapter Overview
+@cindex Overview
+
+This chapter is for people who have never used
+@sc{cvs}, and perhaps have never used version control
+software before.
+
+If you are already familiar with @sc{cvs} and are just
+trying to learn a particular feature or remember a
+certain command, you can probably skip everything here.
+
+@menu
+* What is CVS?:: What you can do with @sc{cvs}
+* What is CVS not?:: Problems @sc{cvs} doesn't try to solve
+* A sample session:: A tour of basic @sc{cvs} usage
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node What is CVS?
+@section What is CVS?
+@cindex What is CVS?
+@cindex Introduction to CVS
+@cindex CVS, introduction to
+
+@sc{cvs} is a version control system. Using it, you can
+record the history of your source files.
+
+@c -- ///
+@c -- ///Those who cannot remember the past are condemned to repeat it.
+@c -- /// -- George Santayana
+@c -- //////
+
+@c -- Insert history quote here!
+For example, bugs sometimes creep in when
+software is modified, and you might not detect the bug
+until a long time after you make the modification.
+With @sc{cvs}, you can easily retrieve old versions to see
+exactly which change caused the bug. This can
+sometimes be a big help.
+
+You could of course save every version of every file
+you have ever created. This would
+however waste an enormous amount of disk space. @sc{cvs}
+stores all the versions of a file in a single file in a
+clever way that only stores the differences between
+versions.
+
+@sc{cvs} also helps you if you are part of a group of people working
+on the same project. It is all too easy to overwrite
+each others' changes unless you are extremely careful.
+Some editors, like @sc{gnu} Emacs, try to make sure that
+two people never modify the same file at the
+same time. Unfortunately, if someone is using another
+editor, that safeguard will not work. @sc{cvs} solves this problem
+by insulating the different developers from each other. Every
+developer works in his own directory, and @sc{cvs} merges
+the work when each developer is done.
+
+@cindex History of CVS
+@cindex CVS, history of
+@cindex Credits (CVS program)
+@cindex Contributors (CVS program)
+@sc{cvs} started out as a bunch of shell scripts written by
+Dick Grune, posted to the newsgroup
+@code{comp.sources.unix} in the volume 6
+release of July, 1986. While no actual code from
+these shell scripts is present in the current version
+of @sc{cvs} much of the @sc{cvs} conflict resolution algorithms
+come from them.
+
+In April, 1989, Brian Berliner designed and coded @sc{cvs}.
+Jeff Polk later helped Brian with the design of the @sc{cvs}
+module and vendor branch support.
+
+@cindex Source, getting CVS source
+You can get @sc{cvs} in a variety of ways, including
+free download from the Internet. For more information
+on downloading @sc{cvs} and other @sc{cvs} topics, see:
+
+@example
+@url{http://cvs.nongnu.org/}
+@end example
+
+@cindex Mailing list
+@cindex List, mailing list
+@cindex Newsgroups
+There is a mailing list, known as @email{info-cvs@@nongnu.org},
+devoted to @sc{cvs}. To subscribe or
+unsubscribe
+write to
+@email{info-cvs-request@@nongnu.org}.
+If you prefer a Usenet group, there is a one-way mirror (posts to the email
+list are usually sent to the news group, but not visa versa) of
+@email{info-cvs@@nongnu.org} at @url{news:gnu.cvs.help}. The right
+Usenet group for posts is @url{news:comp.software.config-mgmt} which is for
+@sc{cvs} discussions (along with other configuration
+management systems). In the future, it might be
+possible to create a
+@code{comp.software.config-mgmt.cvs}, but probably only
+if there is sufficient @sc{cvs} traffic on
+@url{news:comp.software.config-mgmt}.
+@c Other random data is that the tale was very
+@c skeptical of comp.software.config-mgmt.cvs when the
+@c subject came up around 1995 or so (for one
+@c thing, because creating it would be a "reorg" which
+@c would need to take a more comprehensive look at the
+@c whole comp.software.config-mgmt.* hierarchy).
+
+You can also subscribe to the @email{bug-cvs@@nongnu.org} mailing list,
+described in more detail in @ref{BUGS}. To subscribe
+send mail to @email{bug-cvs-request@@nongnu.org}. There is a two-way
+Usenet mirror (posts to the Usenet group are usually sent to the email list and
+visa versa) of @email{bug-cvs@@nongnu.org} named @url{news:gnu.cvs.bug}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node What is CVS not?
+@section What is CVS not?
+@cindex What is CVS not?
+
+@sc{cvs} can do a lot of things for you, but it does
+not try to be everything for everyone.
+
+@table @asis
+@item @sc{cvs} is not a build system.
+
+Though the structure of your repository and modules
+file interact with your build system
+(e.g. @file{Makefile}s), they are essentially
+independent.
+
+@sc{cvs} does not dictate how you build anything. It
+merely stores files for retrieval in a tree structure
+you devise.
+
+@sc{cvs} does not dictate how to use disk space in the
+checked out working directories. If you write your
+@file{Makefile}s or scripts in every directory so they
+have to know the relative positions of everything else,
+you wind up requiring the entire repository to be
+checked out.
+
+If you modularize your work, and construct a build
+system that will share files (via links, mounts,
+@code{VPATH} in @file{Makefile}s, etc.), you can
+arrange your disk usage however you like.
+
+But you have to remember that @emph{any} such system is
+a lot of work to construct and maintain. @sc{cvs} does
+not address the issues involved.
+
+Of course, you should place the tools created to
+support such a build system (scripts, @file{Makefile}s,
+etc) under @sc{cvs}.
+
+Figuring out what files need to be rebuilt when
+something changes is, again, something to be handled
+outside the scope of @sc{cvs}. One traditional
+approach is to use @code{make} for building, and use
+some automated tool for generating the dependencies which
+@code{make} uses.
+
+See @ref{Builds}, for more information on doing builds
+in conjunction with @sc{cvs}.
+
+@item @sc{cvs} is not a substitute for management.
+
+Your managers and project leaders are expected to talk
+to you frequently enough to make certain you are aware
+of schedules, merge points, branch names and release
+dates. If they don't, @sc{cvs} can't help.
+
+@sc{cvs} is an instrument for making sources dance to
+your tune. But you are the piper and the composer. No
+instrument plays itself or writes its own music.
+
+@item @sc{cvs} is not a substitute for developer communication.
+
+When faced with conflicts within a single file, most
+developers manage to resolve them without too much
+effort. But a more general definition of ``conflict''
+includes problems too difficult to solve without
+communication between developers.
+
+@sc{cvs} cannot determine when simultaneous changes
+within a single file, or across a whole collection of
+files, will logically conflict with one another. Its
+concept of a @dfn{conflict} is purely textual, arising
+when two changes to the same base file are near enough
+to spook the merge (i.e. @code{diff3}) command.
+
+@sc{cvs} does not claim to help at all in figuring out
+non-textual or distributed conflicts in program logic.
+
+For example: Say you change the arguments to function
+@code{X} defined in file @file{A}. At the same time,
+someone edits file @file{B}, adding new calls to
+function @code{X} using the old arguments. You are
+outside the realm of @sc{cvs}'s competence.
+
+Acquire the habit of reading specs and talking to your
+peers.
+
+
+@item @sc{cvs} does not have change control
+
+Change control refers to a number of things. First of
+all it can mean @dfn{bug-tracking}, that is being able
+to keep a database of reported bugs and the status of
+each one (is it fixed? in what release? has the bug
+submitter agreed that it is fixed?). For interfacing
+@sc{cvs} to an external bug-tracking system, see the
+@file{rcsinfo} and @file{verifymsg} files
+(@pxref{Administrative files}).
+
+Another aspect of change control is keeping track of
+the fact that changes to several files were in fact
+changed together as one logical change. If you check
+in several files in a single @code{cvs commit}
+operation, @sc{cvs} then forgets that those files were
+checked in together, and the fact that they have the
+same log message is the only thing tying them
+together. Keeping a @sc{gnu} style @file{ChangeLog}
+can help somewhat.
+@c FIXME: should have an xref to a section which talks
+@c more about keeping ChangeLog's with CVS, but that
+@c section hasn't been written yet.
+
+Another aspect of change control, in some systems, is
+the ability to keep track of the status of each
+change. Some changes have been written by a developer,
+others have been reviewed by a second developer, and so
+on. Generally, the way to do this with @sc{cvs} is to
+generate a diff (using @code{cvs diff} or @code{diff})
+and email it to someone who can then apply it using the
+@code{patch} utility. This is very flexible, but
+depends on mechanisms outside @sc{cvs} to make sure
+nothing falls through the cracks.
+
+@item @sc{cvs} is not an automated testing program
+
+It should be possible to enforce mandatory use of a
+test suite using the @code{commitinfo} file. I haven't
+heard a lot about projects trying to do that or whether
+there are subtle gotchas, however.
+
+@item @sc{cvs} does not have a built-in process model
+
+Some systems provide ways to ensure that changes or
+releases go through various steps, with various
+approvals as needed. Generally, one can accomplish
+this with @sc{cvs} but it might be a little more work.
+In some cases you'll want to use the @file{commitinfo},
+@file{loginfo}, @file{rcsinfo}, or @file{verifymsg}
+files, to require that certain steps be performed
+before cvs will allow a checkin. Also consider whether
+features such as branches and tags can be used to
+perform tasks such as doing work in a development tree
+and then merging certain changes over to a stable tree
+only once they have been proven.
+@end table
+
+@c ---------------------------------------------------------------------
+@node A sample session
+@section A sample session
+@cindex Example of a work-session
+@cindex Getting started
+@cindex Work-session, example of
+@cindex tc, Trivial Compiler (example)
+@cindex Trivial Compiler (example)
+
+@c I think an example is a pretty good way to start. But
+@c somewhere in here, maybe after the sample session,
+@c we need something which is kind of
+@c a "roadmap" which is more directed at sketching out
+@c the functionality of CVS and pointing people to
+@c various other parts of the manual. As it stands now
+@c people who read in order get dumped right into all
+@c manner of hair regarding remote repositories,
+@c creating a repository, etc.
+@c
+@c The following was in the old Basic concepts node. I don't
+@c know how good a job it does at introducing modules,
+@c or whether they need to be introduced so soon, but
+@c something of this sort might go into some
+@c introductory material somewhere.
+@ignore
+@cindex Modules (intro)
+The repository contains directories and files, in an
+arbitrary tree. The @dfn{modules} feature can be used
+to group together a set of directories or files into a
+single entity (@pxref{modules}). A typical usage is to
+define one module per project.
+@end ignore
+
+As a way of introducing @sc{cvs}, we'll go through a
+typical work-session using @sc{cvs}. The first thing
+to understand is that @sc{cvs} stores all files in a
+centralized @dfn{repository} (@pxref{Repository}); this
+section assumes that a repository is set up.
+@c I'm not sure that the sentence concerning the
+@c repository quite tells the user what they need to
+@c know at this point. Might need to expand on "centralized"
+@c slightly (maybe not here, maybe further down in the example?)
+
+Suppose you are working on a simple compiler. The source
+consists of a handful of C files and a @file{Makefile}.
+The compiler is called @samp{tc} (Trivial Compiler),
+and the repository is set up so that there is a module
+called @samp{tc}.
+
+@menu
+* Getting the source:: Creating a workspace
+* Committing your changes:: Making your work available to others
+* Cleaning up:: Cleaning up
+* Viewing differences:: Viewing differences
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Getting the source
+@subsection Getting the source
+@cindex Getting the source
+@cindex Checking out source
+@cindex Fetching source
+@cindex Source, getting from CVS
+@cindex Checkout, example
+
+The first thing you must do is to get your own working copy of the
+source for @samp{tc}. For this, you use the @code{checkout} command:
+
+@example
+$ cvs checkout tc
+@end example
+
+@noindent
+This will create a new directory called @file{tc} and populate it with
+the source files.
+
+@example
+$ cd tc
+$ ls
+CVS Makefile backend.c driver.c frontend.c parser.c
+@end example
+
+The @file{CVS} directory is used internally by
+@sc{cvs}. Normally, you should not modify or remove
+any of the files in it.
+
+You start your favorite editor, hack away at @file{backend.c}, and a couple
+of hours later you have added an optimization pass to the compiler.
+A note to @sc{rcs} and @sc{sccs} users: There is no need to lock the files that
+you want to edit. @xref{Multiple developers}, for an explanation.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Committing your changes
+@subsection Committing your changes
+@cindex Committing changes to files
+@cindex Log message entry
+
+When you have checked that the compiler is still compilable you decide
+to make a new version of @file{backend.c}. This will
+store your new @file{backend.c} in the repository and
+make it available to anyone else who is using that same
+repository.
+
+@example
+$ cvs commit backend.c
+@end example
+
+@noindent
+@sc{cvs} starts an editor, to allow you to enter a log
+message. You type in ``Added an optimization pass.'',
+save the temporary file, and exit the editor.
+
+@cindex CVSEDITOR, environment variable
+@cindex EDITOR, environment variable
+The environment variable @code{$CVSEDITOR} determines
+which editor is started. If @code{$CVSEDITOR} is not
+set, then if the environment variable @code{$EDITOR} is
+set, it will be used. If both @code{$CVSEDITOR} and
+@code{$EDITOR} are not set then there is a default
+which will vary with your operating system, for example
+@code{vi} for unix or @code{notepad} for Windows
+NT/95.
+
+@cindex VISUAL, environment variable
+In addition, @sc{cvs} checks the @code{$VISUAL} environment
+variable. Opinions vary on whether this behavior is desirable and
+whether future releases of @sc{cvs} should check @code{$VISUAL} or
+ignore it. You will be OK either way if you make sure that
+@code{$VISUAL} is either unset or set to the same thing as
+@code{$EDITOR}.
+
+@c This probably should go into some new node
+@c containing detailed info on the editor, rather than
+@c the intro. In fact, perhaps some of the stuff with
+@c CVSEDITOR and -m and so on should too.
+When @sc{cvs} starts the editor, it includes a list of
+files which are modified. For the @sc{cvs} client,
+this list is based on comparing the modification time
+of the file against the modification time that the file
+had when it was last gotten or updated. Therefore, if
+a file's modification time has changed but its contents
+have not, it will show up as modified. The simplest
+way to handle this is simply not to worry about it---if
+you proceed with the commit @sc{cvs} will detect that
+the contents are not modified and treat it as an
+unmodified file. The next @code{update} will clue
+@sc{cvs} in to the fact that the file is unmodified,
+and it will reset its stored timestamp so that the file
+will not show up in future editor sessions.
+@c FIXCVS: Might be nice if "commit" and other commands
+@c would reset that timestamp too, but currently commit
+@c doesn't.
+@c FIXME: Need to talk more about the process of
+@c prompting for the log message. Like show an example
+@c of what it pops up in the editor, for example. Also
+@c a discussion of how to get the "a)bort, c)ontinue,
+@c e)dit" prompt and what to do with it. Might also
+@c work in the suggestion that if you want a diff, you
+@c should make it before running commit (someone
+@c suggested that the diff pop up in the editor. I'm
+@c not sure that is better than telling people to run
+@c "cvs diff" first if that is what they want, but if
+@c we want to tell people that, the manual possibly
+@c should say it).
+
+If you want to avoid
+starting an editor you can specify the log message on
+the command line using the @samp{-m} flag instead, like
+this:
+
+@example
+$ cvs commit -m "Added an optimization pass" backend.c
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Cleaning up
+@subsection Cleaning up
+@cindex Cleaning up
+@cindex Working copy, removing
+@cindex Removing your working copy
+@cindex Releasing your working copy
+
+Before you turn to other tasks you decide to remove your working copy of
+tc. One acceptable way to do that is of course
+
+@example
+$ cd ..
+$ rm -r tc
+@end example
+
+@noindent
+but a better way is to use the @code{release} command (@pxref{release}):
+
+@example
+$ cd ..
+$ cvs release -d tc
+M driver.c
+? tc
+You have [1] altered files in this repository.
+Are you sure you want to release (and delete) directory `tc': n
+** `release' aborted by user choice.
+@end example
+
+The @code{release} command checks that all your modifications have been
+committed. If history logging is enabled it also makes a note in the
+history file. @xref{history file}.
+
+When you use the @samp{-d} flag with @code{release}, it
+also removes your working copy.
+
+In the example above, the @code{release} command wrote a couple of lines
+of output. @samp{? tc} means that the file @file{tc} is unknown to @sc{cvs}.
+That is nothing to worry about: @file{tc} is the executable compiler,
+and it should not be stored in the repository. @xref{cvsignore},
+for information about how to make that warning go away.
+@xref{release output}, for a complete explanation of
+all possible output from @code{release}.
+
+@samp{M driver.c} is more serious. It means that the
+file @file{driver.c} has been modified since it was
+checked out.
+
+The @code{release} command always finishes by telling
+you how many modified files you have in your working
+copy of the sources, and then asks you for confirmation
+before deleting any files or making any note in the
+history file.
+
+You decide to play it safe and answer @kbd{n @key{RET}}
+when @code{release} asks for confirmation.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Viewing differences
+@subsection Viewing differences
+@cindex Viewing differences
+@cindex Diff
+
+You do not remember modifying @file{driver.c}, so you want to see what
+has happened to that file.
+
+@example
+$ cd tc
+$ cvs diff driver.c
+@end example
+
+This command runs @code{diff} to compare the version of @file{driver.c}
+that you checked out with your working copy. When you see the output
+you remember that you added a command line option that enabled the
+optimization pass. You check it in, and release the module.
+@c FIXME: we haven't yet defined the term "check in".
+
+@example
+$ cvs commit -m "Added an optimization pass" driver.c
+Checking in driver.c;
+/usr/local/cvsroot/tc/driver.c,v <-- driver.c
+new revision: 1.2; previous revision: 1.1
+done
+$ cd ..
+$ cvs release -d tc
+? tc
+You have [0] altered files in this repository.
+Are you sure you want to release (and delete) directory `tc': y
+@end example
+
+@c ---------------------------------------------------------------------
+@node Repository
+@chapter The Repository
+@cindex Repository (intro)
+@cindex Repository, example
+@cindex Layout of repository
+@cindex Typical repository
+@cindex /usr/local/cvsroot, as example repository
+@cindex cvsroot
+
+The @sc{cvs} @dfn{repository} stores a complete copy of
+all the files and directories which are under version
+control.
+
+Normally, you never access any of the files in the
+repository directly. Instead, you use @sc{cvs}
+commands to get your own copy of the files into a
+@dfn{working directory}, and then
+work on that copy. When you've finished a set of
+changes, you check (or @dfn{commit}) them back into the
+repository. The repository then contains the changes
+which you have made, as well as recording exactly what
+you changed, when you changed it, and other such
+information. Note that the repository is not a
+subdirectory of the working directory, or vice versa;
+they should be in separate locations.
+@c Need some example, e.g. repository
+@c /usr/local/cvsroot; working directory
+@c /home/joe/sources. But this node is too long
+@c as it is; need a little reorganization...
+
+@cindex :local:, setting up
+@sc{cvs} can access a repository by a variety of
+means. It might be on the local computer, or it might
+be on a computer across the room or across the world.
+To distinguish various ways to access a repository, the
+repository name can start with an @dfn{access method}.
+For example, the access method @code{:local:} means to
+access a repository directory, so the repository
+@code{:local:/usr/local/cvsroot} means that the
+repository is in @file{/usr/local/cvsroot} on the
+computer running @sc{cvs}. For information on other
+access methods, see @ref{Remote repositories}.
+
+@c Can se say this more concisely? Like by passing
+@c more of the buck to the Remote repositories node?
+If the access method is omitted, then if the repository
+starts with @samp{/}, then @code{:local:} is
+assumed. If it does not start with @samp{/} then either
+@code{:ext:} or @code{:server:} is assumed. For
+example, if you have a local repository in
+@file{/usr/local/cvsroot}, you can use
+@code{/usr/local/cvsroot} instead of
+@code{:local:/usr/local/cvsroot}. But if (under
+Windows NT, for example) your local repository is
+@file{c:\src\cvsroot}, then you must specify the access
+method, as in @code{:local:c:/src/cvsroot}.
+
+@c This might appear to go in Repository storage, but
+@c actually it is describing something which is quite
+@c user-visible, when you do a "cvs co CVSROOT". This
+@c isn't necessary the perfect place for that, though.
+The repository is split in two parts. @file{$CVSROOT/CVSROOT} contains
+administrative files for @sc{cvs}. The other directories contain the actual
+user-defined modules.
+
+@menu
+* Specifying a repository:: Telling CVS where your repository is
+* Repository storage:: The structure of the repository
+* Working directory storage:: The structure of working directories
+* Intro administrative files:: Defining modules
+* Multiple repositories:: Multiple repositories
+* Creating a repository:: Creating a repository
+* Backing up:: Backing up a repository
+* Moving a repository:: Moving a repository
+* Remote repositories:: Accessing repositories on remote machines
+* Read-only access:: Granting read-only access to the repository
+* Server temporary directory:: The server creates temporary directories
+@end menu
+
+@node Specifying a repository
+@section Telling CVS where your repository is
+
+There are several ways to tell @sc{cvs}
+where to find the repository. You can name the
+repository on the command line explicitly, with the
+@code{-d} (for "directory") option:
+
+@example
+cvs -d /usr/local/cvsroot checkout yoyodyne/tc
+@end example
+
+@cindex .profile, setting CVSROOT in
+@cindex .cshrc, setting CVSROOT in
+@cindex .tcshrc, setting CVSROOT in
+@cindex .bashrc, setting CVSROOT in
+@cindex CVSROOT, environment variable
+ Or you can set the @code{$CVSROOT} environment
+variable to an absolute path to the root of the
+repository, @file{/usr/local/cvsroot} in this example.
+To set @code{$CVSROOT}, @code{csh} and @code{tcsh}
+users should have this line in their @file{.cshrc} or
+@file{.tcshrc} files:
+
+@example
+setenv CVSROOT /usr/local/cvsroot
+@end example
+
+@noindent
+@code{sh} and @code{bash} users should instead have these lines in their
+@file{.profile} or @file{.bashrc}:
+
+@example
+CVSROOT=/usr/local/cvsroot
+export CVSROOT
+@end example
+
+@cindex Root file, in CVS directory
+@cindex CVS/Root file
+ A repository specified with @code{-d} will
+override the @code{$CVSROOT} environment variable.
+Once you've checked a working copy out from the
+repository, it will remember where its repository is
+(the information is recorded in the
+@file{CVS/Root} file in the working copy).
+
+The @code{-d} option and the @file{CVS/Root} file both
+override the @code{$CVSROOT} environment variable. If
+@code{-d} option differs from @file{CVS/Root}, the
+former is used. Of course, for proper operation they
+should be two ways of referring to the same repository.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Repository storage
+@section How data is stored in the repository
+@cindex Repository, how data is stored
+
+For most purposes it isn't important @emph{how}
+@sc{cvs} stores information in the repository. In
+fact, the format has changed in the past, and is likely
+to change in the future. Since in almost all cases one
+accesses the repository via @sc{cvs} commands, such
+changes need not be disruptive.
+
+However, in some cases it may be necessary to
+understand how @sc{cvs} stores data in the repository,
+for example you might need to track down @sc{cvs} locks
+(@pxref{Concurrency}) or you might need to deal with
+the file permissions appropriate for the repository.
+
+@menu
+* Repository files:: What files are stored in the repository
+* File permissions:: File permissions
+* Windows permissions:: Issues specific to Windows
+* Attic:: Some files are stored in the Attic
+* CVS in repository:: Additional information in CVS directory
+* Locks:: CVS locks control concurrent accesses
+* CVSROOT storage:: A few things about CVSROOT are different
+@end menu
+
+@node Repository files
+@subsection Where files are stored within the repository
+
+@c @cindex Filenames, legal
+@c @cindex Legal filenames
+@c Somewhere we need to say something about legitimate
+@c characters in filenames in working directory and
+@c repository. Not "/" (not even on non-unix). And
+@c here is a specific set of issues:
+@c Files starting with a - are handled inconsistently. They can not
+@c be added to a repository with an add command, because it they are
+@c interpreted as a switch. They can appear in a repository if they are
+@c part of a tree that is imported. They can not be removed from the tree
+@c once they are there.
+@c Note that "--" *is* supported (as a
+@c consequence of using GNU getopt). Should document
+@c this somewhere ("Common options"?). The other usual technique,
+@c "./-foo", isn't as effective, at least for "cvs add"
+@c which doesn't support pathnames containing "/".
+
+The overall structure of the repository is a directory
+tree corresponding to the directories in the working
+directory. For example, supposing the repository is in
+
+@example
+/usr/local/cvsroot
+@end example
+
+@noindent
+here is a possible directory tree (showing only the
+directories):
+
+@example
+@t{/usr}
+ |
+ +--@t{local}
+ | |
+ | +--@t{cvsroot}
+ | | |
+ | | +--@t{CVSROOT}
+ | (administrative files)
+ |
+ +--@t{gnu}
+ | |
+ | +--@t{diff}
+ | | (source code to @sc{gnu} diff)
+ | |
+ | +--@t{rcs}
+ | | (source code to @sc{rcs})
+ | |
+ | +--@t{cvs}
+ | (source code to @sc{cvs})
+ |
+ +--@t{yoyodyne}
+ |
+ +--@t{tc}
+ | |
+ | +--@t{man}
+ | |
+ | +--@t{testing}
+ |
+ +--(other Yoyodyne software)
+@end example
+
+With the directories are @dfn{history files} for each file
+under version control. The name of the history file is
+the name of the corresponding file with @samp{,v}
+appended to the end. Here is what the repository for
+the @file{yoyodyne/tc} directory might look like:
+@c FIXME: Should also mention CVS (CVSREP)
+@c FIXME? Should we introduce Attic with an xref to
+@c Attic? Not sure whether that is a good idea or not.
+@example
+ @code{$CVSROOT}
+ |
+ +--@t{yoyodyne}
+ | |
+ | +--@t{tc}
+ | | |
+ +--@t{Makefile,v}
+ +--@t{backend.c,v}
+ +--@t{driver.c,v}
+ +--@t{frontend.c,v}
+ +--@t{parser.c,v}
+ +--@t{man}
+ | |
+ | +--@t{tc.1,v}
+ |
+ +--@t{testing}
+ |
+ +--@t{testpgm.t,v}
+ +--@t{test2.t,v}
+@end example
+
+@cindex History files
+@cindex RCS history files
+@c The first sentence, about what history files
+@c contain, is kind of redundant with our intro to what the
+@c repository does in node Repository....
+The history files contain, among other things, enough
+information to recreate any revision of the file, a log
+of all commit messages and the user-name of the person
+who committed the revision. The history files are
+known as @dfn{RCS files}, because the first program to
+store files in that format was a version control system
+known as @sc{rcs}. For a full
+description of the file format, see the @code{man} page
+@cite{rcsfile(5)}, distributed with @sc{rcs}, or the
+file @file{doc/RCSFILES} in the @sc{cvs} source
+distribution. This
+file format has become very common---many systems other
+than @sc{cvs} or @sc{rcs} can at least import history
+files in this format.
+@c FIXME: Think about including documentation for this
+@c rather than citing it? In the long run, getting
+@c this to be a standard (not sure if we can cope with
+@c a standards process as formal as IEEE/ANSI/ISO/etc,
+@c though...) is the way to go, so maybe citing is
+@c better.
+
+The @sc{rcs} files used in @sc{cvs} differ in a few
+ways from the standard format. The biggest difference
+is magic branches; for more information see @ref{Magic
+branch numbers}. Also in @sc{cvs} the valid tag names
+are a subset of what @sc{rcs} accepts; for @sc{cvs}'s
+rules see @ref{Tags}.
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node File permissions
+@subsection File permissions
+@c -- Move this to @node Creating a repository or similar
+@cindex Security, file permissions in repository
+@cindex File permissions, general
+@cindex Permissions, general
+@c FIXME: we need to somehow reflect "permissions in
+@c repository" versus "permissions in working
+@c directory" in the index entries.
+@cindex Group, UNIX file permissions, in repository
+@cindex Read-only files, in repository
+All @samp{,v} files are created read-only, and you
+should not change the permission of those files. The
+directories inside the repository should be writable by
+the persons that have permission to modify the files in
+each directory. This normally means that you must
+create a UNIX group (see group(5)) consisting of the
+persons that are to edit the files in a project, and
+set up the repository so that it is that group that
+owns the directory.
+(On some systems, you also need to set the set-group-ID-on-execution bit
+on the repository directories (see chmod(1)) so that newly-created files
+and directories get the group-ID of the parent directory rather than
+that of the current process.)
+
+@c See also comment in commitinfo node regarding cases
+@c which are really awkward with unix groups.
+
+This means that you can only control access to files on
+a per-directory basis.
+
+Note that users must also have write access to check
+out files, because @sc{cvs} needs to create lock files
+(@pxref{Concurrency}). You can use LockDir in CVSROOT/config
+to put the lock files somewhere other than in the repository
+if you want to allow read-only access to some directories
+(@pxref{config}).
+
+@c CVS seems to use CVSUMASK in picking permissions for
+@c val-tags, but maybe we should say more about this.
+@c Like val-tags gets created by someone who doesn't
+@c have CVSUMASK set right?
+@cindex CVSROOT/val-tags file, and read-only access to projects
+@cindex val-tags file, and read-only access to projects
+Also note that users must have write access to the
+@file{CVSROOT/val-tags} file. @sc{cvs} uses it to keep
+track of what tags are valid tag names (it is sometimes
+updated when tags are used, as well as when they are
+created).
+
+Each @sc{rcs} file will be owned by the user who last
+checked it in. This has little significance; what
+really matters is who owns the directories.
+
+@cindex CVSUMASK, environment variable
+@cindex Umask, for repository files
+@sc{cvs} tries to set up reasonable file permissions
+for new directories that are added inside the tree, but
+you must fix the permissions manually when a new
+directory should have different permissions than its
+parent directory. If you set the @code{CVSUMASK}
+environment variable that will control the file
+permissions which @sc{cvs} uses in creating directories
+and/or files in the repository. @code{CVSUMASK} does
+not affect the file permissions in the working
+directory; such files have the permissions which are
+typical for newly created files, except that sometimes
+@sc{cvs} creates them read-only (see the sections on
+watches, @ref{Setting a watch}; -r, @ref{Global
+options}; or @code{CVSREAD}, @ref{Environment variables}).
+@c FIXME: Need more discussion of which
+@c group should own the file in the repository.
+@c Include a somewhat detailed example of the usual
+@c case where CVSUMASK is 007, the developers are all
+@c in a group, and that group owns stuff in the
+@c repository. Need to talk about group ownership of
+@c newly-created directories/files (on some unices,
+@c such as SunOS4, setting the setgid bit on the
+@c directories will make files inherit the directory's
+@c group. On other unices, your mileage may vary. I
+@c can't remember what POSIX says about this, if
+@c anything).
+
+Note that using the client/server @sc{cvs}
+(@pxref{Remote repositories}), there is no good way to
+set @code{CVSUMASK}; the setting on the client machine
+has no effect. If you are connecting with @code{rsh}, you
+can set @code{CVSUMASK} in @file{.bashrc} or @file{.cshrc}, as
+described in the documentation for your operating
+system. This behavior might change in future versions
+of @sc{cvs}; do not rely on the setting of
+@code{CVSUMASK} on the client having no effect.
+@c FIXME: need to explain what a umask is or cite
+@c someplace which does.
+@c
+@c There is also a larger (largely separate) issue
+@c about the meaning of CVSUMASK in a non-unix context.
+@c For example, whether there is
+@c an equivalent which fits better into other
+@c protection schemes like POSIX.6, VMS, &c.
+@c
+@c FIXME: Need one place which discusses this
+@c read-only files thing. Why would one use -r or
+@c CVSREAD? Why would one use watches? How do they
+@c interact?
+@c
+@c FIXME: We need to state
+@c whether using CVSUMASK removes the need for manually
+@c fixing permissions (in fact, if we are going to mention
+@c manually fixing permission, we better document a lot
+@c better just what we mean by "fix").
+
+Using pserver, you will generally need stricter
+permissions on the @sc{cvsroot} directory and
+directories above it in the tree; see @ref{Password
+authentication security}.
+
+@cindex Setuid
+@cindex Setgid
+@cindex Security, setuid
+@cindex Installed images (VMS)
+Some operating systems have features which allow a
+particular program to run with the ability to perform
+operations which the caller of the program could not.
+For example, the set user ID (setuid) or set group ID
+(setgid) features of unix or the installed image
+feature of VMS. @sc{cvs} was not written to use such
+features and therefore attempting to install @sc{cvs} in
+this fashion will provide protection against only
+accidental lapses; anyone who is trying to circumvent
+the measure will be able to do so, and depending on how
+you have set it up may gain access to more than just
+@sc{cvs}. You may wish to instead consider pserver. It
+shares some of the same attributes, in terms of
+possibly providing a false sense of security or opening
+security holes wider than the ones you are trying to
+fix, so read the documentation on pserver security
+carefully if you are considering this option
+(@ref{Password authentication security}).
+
+@node Windows permissions
+@subsection File Permission issues specific to Windows
+@cindex Windows, and permissions
+@cindex File permissions, Windows-specific
+@cindex Permissions, Windows-specific
+
+Some file permission issues are specific to Windows
+operating systems (Windows 95, Windows NT, and
+presumably future operating systems in this family.
+Some of the following might apply to OS/2 but I'm not
+sure).
+
+If you are using local @sc{cvs} and the repository is on a
+networked file system which is served by the Samba SMB
+server, some people have reported problems with
+permissions. Enabling WRITE=YES in the samba
+configuration is said to fix/workaround it.
+Disclaimer: I haven't investigated enough to know the
+implications of enabling that option, nor do I know
+whether there is something which @sc{cvs} could be doing
+differently in order to avoid the problem. If you find
+something out, please let us know as described in
+@ref{BUGS}.
+
+@node Attic
+@subsection The attic
+@cindex Attic
+
+You will notice that sometimes @sc{cvs} stores an
+@sc{rcs} file in the @code{Attic}. For example, if the
+@sc{cvsroot} is @file{/usr/local/cvsroot} and we are
+talking about the file @file{backend.c} in the
+directory @file{yoyodyne/tc}, then the file normally
+would be in
+
+@example
+/usr/local/cvsroot/yoyodyne/tc/backend.c,v
+@end example
+
+@noindent
+but if it goes in the attic, it would be in
+
+@example
+/usr/local/cvsroot/yoyodyne/tc/Attic/backend.c,v
+@end example
+
+@noindent
+@cindex Dead state
+instead. It should not matter from a user point of
+view whether a file is in the attic; @sc{cvs} keeps
+track of this and looks in the attic when it needs to.
+But in case you want to know, the rule is that the RCS
+file is stored in the attic if and only if the head
+revision on the trunk has state @code{dead}. A
+@code{dead} state means that file has been removed, or
+never added, for that revision. For example, if you
+add a file on a branch, it will have a trunk revision
+in @code{dead} state, and a branch revision in a
+non-@code{dead} state.
+@c Probably should have some more concrete examples
+@c here, or somewhere (not sure exactly how we should
+@c arrange the discussion of the dead state, versus
+@c discussion of the attic).
+
+@node CVS in repository
+@subsection The CVS directory in the repository
+@cindex CVS directory, in repository
+
+The @file{CVS} directory in each repository directory
+contains information such as file attributes (in a file
+called @file{CVS/fileattr}. In the
+future additional files may be added to this directory,
+so implementations should silently ignore additional
+files.
+
+This behavior is implemented only by @sc{cvs} 1.7 and
+later; for details see @ref{Watches Compatibility}.
+
+The format of the @file{fileattr} file is a series of entries
+of the following form (where @samp{@{} and @samp{@}}
+means the text between the braces can be repeated zero
+or more times):
+
+@var{ent-type} @var{filename} <tab> @var{attrname} = @var{attrval}
+ @{; @var{attrname} = @var{attrval}@} <linefeed>
+
+@var{ent-type} is @samp{F} for a file, in which case the entry specifies the
+attributes for that file.
+
+@var{ent-type} is @samp{D},
+and @var{filename} empty, to specify default attributes
+to be used for newly added files.
+
+Other @var{ent-type} are reserved for future expansion. @sc{cvs} 1.9 and older
+will delete them any time it writes file attributes.
+@sc{cvs} 1.10 and later will preserve them.
+
+Note that the order of the lines is not significant;
+a program writing the fileattr file may
+rearrange them at its convenience.
+
+There is currently no way of quoting tabs or line feeds in the
+filename, @samp{=} in @var{attrname},
+@samp{;} in @var{attrval}, etc. Note: some implementations also
+don't handle a NUL character in any of the fields, but
+implementations are encouraged to allow it.
+
+By convention, @var{attrname} starting with @samp{_} is for an attribute given
+special meaning by @sc{cvs}; other @var{attrname}s are for user-defined attributes
+(or will be, once implementations start supporting user-defined attributes).
+
+Built-in attributes:
+
+@table @code
+@item _watched
+Present means the file is watched and should be checked out
+read-only.
+
+@item _watchers
+Users with watches for this file. Value is
+@var{watcher} > @var{type} @{ , @var{watcher} > @var{type} @}
+where @var{watcher} is a username, and @var{type}
+is zero or more of edit,unedit,commit separated by
+@samp{+} (that is, nothing if none; there is no "none" or "all" keyword).
+
+@item _editors
+Users editing this file. Value is
+@var{editor} > @var{val} @{ , @var{editor} > @var{val} @}
+where @var{editor} is a username, and @var{val} is
+@var{time}+@var{hostname}+@var{pathname}, where
+@var{time} is when the @code{cvs edit} command (or
+equivalent) happened,
+and @var{hostname} and @var{pathname} are for the working directory.
+@end table
+
+Example:
+
+@c FIXME: sanity.sh should contain a similar test case
+@c so we can compare this example from something from
+@c Real Life(TM). See cvsclient.texi (under Notify) for more
+@c discussion of the date format of _editors.
+@example
+Ffile1 _watched=;_watchers=joe>edit,mary>commit
+Ffile2 _watched=;_editors=sue>8 Jan 1975+workstn1+/home/sue/cvs
+D _watched=
+@end example
+
+@noindent
+means that the file @file{file1} should be checked out
+read-only. Furthermore, joe is watching for edits and
+mary is watching for commits. The file @file{file2}
+should be checked out read-only; sue started editing it
+on 8 Jan 1975 in the directory @file{/home/sue/cvs} on
+the machine @code{workstn1}. Future files which are
+added should be checked out read-only. To represent
+this example here, we have shown a space after
+@samp{D}, @samp{Ffile1}, and @samp{Ffile2}, but in fact
+there must be a single tab character there and no spaces.
+
+@node Locks
+@subsection CVS locks in the repository
+
+@cindex #cvs.rfl, technical details
+@cindex #cvs.pfl, technical details
+@cindex #cvs.wfl, technical details
+@cindex #cvs.lock, technical details
+@cindex Locks, cvs, technical details
+For an introduction to @sc{cvs} locks focusing on
+user-visible behavior, see @ref{Concurrency}. The
+following section is aimed at people who are writing
+tools which want to access a @sc{cvs} repository without
+interfering with other tools accessing the same
+repository. If you find yourself confused by concepts
+described here, like @dfn{read lock}, @dfn{write lock},
+and @dfn{deadlock}, you might consult the literature on
+operating systems or databases.
+
+@cindex #cvs.tfl
+Any file in the repository with a name starting
+with @file{#cvs.rfl.} is a read lock. Any file in
+the repository with a name starting with
+@file{#cvs.pfl} is a promotable read lock. Any file in
+the repository with a name starting with
+@file{#cvs.wfl} is a write lock. Old versions of @sc{cvs}
+(before @sc{cvs} 1.5) also created files with names starting
+with @file{#cvs.tfl}, but they are not discussed here.
+The directory @file{#cvs.lock} serves as a master
+lock. That is, one must obtain this lock first before
+creating any of the other locks.
+
+To obtain a read lock, first create the @file{#cvs.lock}
+directory. This operation must be atomic (which should
+be true for creating a directory under most operating
+systems). If it fails because the directory already
+existed, wait for a while and try again. After
+obtaining the @file{#cvs.lock} lock, create a file
+whose name is @file{#cvs.rfl.} followed by information
+of your choice (for example, hostname and process
+identification number). Then remove the
+@file{#cvs.lock} directory to release the master lock.
+Then proceed with reading the repository. When you are
+done, remove the @file{#cvs.rfl} file to release the
+read lock.
+
+Promotable read locks are a concept you may not find in other literature on
+concurrency. They are used to allow a two (or more) pass process to only lock
+a file for read on the first (read) pass(es), then upgrade its read locks to
+write locks if necessary for a final pass, still assured that the files have
+not changed since they were first read. @sc{cvs} uses promotable read locks,
+for example, to prevent commit and tag verification passes from interfering
+with other reading processes. It can then lock only a single directory at a
+time for write during the write pass.
+
+To obtain a promotable read lock, first create the @file{#cvs.lock} directory,
+as with a non-promotable read lock. Then check
+that there are no files that start with
+@file{#cvs.pfl}. If there are, remove the master @file{#cvs.lock} directory,
+wait awhile (CVS waits 30 seconds between lock attempts), and try again. If
+there are no other promotable locks, go ahead and create a file whose name is
+@file{#cvs.pfl} followed by information of your choice (for example, CVS uses
+its hostname and the process identification number of the CVS server process
+creating the lock). If versions of @sc{cvs} older than version 1.12.4 access
+your repository directly (not via a @sc{cvs} server of version 1.12.4 or
+later), then you should also create a read lock since older versions of CVS
+will ignore the promotable lock when attempting to create their own write lock.
+Then remove the master @file{#cvs.lock} directory in order to allow other
+processes to obtain read locks.
+
+To obtain a write lock, first create the
+@file{#cvs.lock} directory, as with read locks. Then
+check that there are no files whose names start with
+@file{#cvs.rfl.} and no files whose names start with @file{#cvs.pfl} that are
+not owned by the process attempting to get the write lock. If either exist,
+remove @file{#cvs.lock}, wait for a while, and try again. If
+there are no readers or promotable locks from other processes, then create a
+file whose name is @file{#cvs.wfl} followed by information of your choice
+(again, CVS uses the hostname and server process identification
+number). Remove your @file{#cvs.pfl} file if present. Hang on to the
+@file{#cvs.lock} lock. Proceed
+with writing the repository. When you are done, first
+remove the @file{#cvs.wfl} file and then the
+@file{#cvs.lock} directory. Note that unlike the
+@file{#cvs.rfl} file, the @file{#cvs.wfl} file is just
+informational; it has no effect on the locking operation
+beyond what is provided by holding on to the
+@file{#cvs.lock} lock itself.
+
+Note that each lock (write lock or read lock) only locks
+a single directory in the repository, including
+@file{Attic} and @file{CVS} but not including
+subdirectories which represent other directories under
+version control. To lock an entire tree, you need to
+lock each directory (note that if you fail to obtain
+any lock you need, you must release the whole tree
+before waiting and trying again, to avoid deadlocks).
+
+Note also that @sc{cvs} expects write locks to control
+access to individual @file{foo,v} files. @sc{rcs} has
+a scheme where the @file{,foo,} file serves as a lock,
+but @sc{cvs} does not implement it and so taking out a
+@sc{cvs} write lock is recommended. See the comments at
+rcs_internal_lockfile in the @sc{cvs} source code for
+further discussion/rationale.
+
+@node CVSROOT storage
+@subsection How files are stored in the CVSROOT directory
+@cindex CVSROOT, storage of files
+
+The @file{$CVSROOT/CVSROOT} directory contains the
+various administrative files. In some ways this
+directory is just like any other directory in the
+repository; it contains @sc{rcs} files whose names end
+in @samp{,v}, and many of the @sc{cvs} commands operate
+on it the same way. However, there are a few
+differences.
+
+For each administrative file, in addition to the
+@sc{rcs} file, there is also a checked out copy of the
+file. For example, there is an @sc{rcs} file
+@file{loginfo,v} and a file @file{loginfo} which
+contains the latest revision contained in
+@file{loginfo,v}. When you check in an administrative
+file, @sc{cvs} should print
+
+@example
+cvs commit: Rebuilding administrative file database
+@end example
+
+@noindent
+and update the checked out copy in
+@file{$CVSROOT/CVSROOT}. If it does not, there is
+something wrong (@pxref{BUGS}). To add your own files
+to the files to be updated in this fashion, you can add
+them to the @file{checkoutlist} administrative file
+(@pxref{checkoutlist}).
+
+@cindex modules.db
+@cindex modules.pag
+@cindex modules.dir
+By default, the @file{modules} file behaves as
+described above. If the modules file is very large,
+storing it as a flat text file may make looking up
+modules slow (I'm not sure whether this is as much of a
+concern now as when @sc{cvs} first evolved this
+feature; I haven't seen benchmarks). Therefore, by
+making appropriate edits to the @sc{cvs} source code
+one can store the modules file in a database which
+implements the @code{ndbm} interface, such as Berkeley
+db or GDBM. If this option is in use, then the modules
+database will be stored in the files @file{modules.db},
+@file{modules.pag}, and/or @file{modules.dir}.
+@c I think fileattr also will use the database stuff.
+@c Anything else?
+
+For information on the meaning of the various
+administrative files, see @ref{Administrative files}.
+
+@node Working directory storage
+@section How data is stored in the working directory
+
+@c FIXME: Somewhere we should discuss timestamps (test
+@c case "stamps" in sanity.sh). But not here. Maybe
+@c in some kind of "working directory" chapter which
+@c would encompass the "Builds" one? But I'm not sure
+@c whether that is a good organization (is it based on
+@c what the user wants to do?).
+
+@cindex CVS directory, in working directory
+While we are discussing @sc{cvs} internals which may
+become visible from time to time, we might as well talk
+about what @sc{cvs} puts in the @file{CVS} directories
+in the working directories. As with the repository,
+@sc{cvs} handles this information and one can usually
+access it via @sc{cvs} commands. But in some cases it
+may be useful to look at it, and other programs, such
+as the @code{jCVS} graphical user interface or the
+@code{VC} package for emacs, may need to look at it.
+Such programs should follow the recommendations in this
+section if they hope to be able to work with other
+programs which use those files, including future
+versions of the programs just mentioned and the
+command-line @sc{cvs} client.
+
+The @file{CVS} directory contains several files.
+Programs which are reading this directory should
+silently ignore files which are in the directory but
+which are not documented here, to allow for future
+expansion.
+
+The files are stored according to the text file
+convention for the system in question. This means that
+working directories are not portable between systems
+with differing conventions for storing text files.
+This is intentional, on the theory that the files being
+managed by @sc{cvs} probably will not be portable between
+such systems either.
+
+@table @file
+@item Root
+This file contains the current @sc{cvs} root, as
+described in @ref{Specifying a repository}.
+
+@cindex Repository file, in CVS directory
+@cindex CVS/Repository file
+@item Repository
+This file contains the directory within the repository
+which the current directory corresponds with. It can
+be either an absolute pathname or a relative pathname;
+@sc{cvs} has had the ability to read either format
+since at least version 1.3 or so. The relative
+pathname is relative to the root, and is the more
+sensible approach, but the absolute pathname is quite
+common and implementations should accept either. For
+example, after the command
+
+@example
+cvs -d :local:/usr/local/cvsroot checkout yoyodyne/tc
+@end example
+
+@noindent
+@file{Root} will contain
+
+@example
+:local:/usr/local/cvsroot
+@end example
+
+@noindent
+and @file{Repository} will contain either
+
+@example
+/usr/local/cvsroot/yoyodyne/tc
+@end example
+
+@noindent
+or
+
+@example
+yoyodyne/tc
+@end example
+
+If the particular working directory does not correspond
+to a directory in the repository, then @file{Repository}
+should contain @file{CVSROOT/Emptydir}.
+@cindex Emptydir, in CVSROOT directory
+@cindex CVSROOT/Emptydir directory
+
+@cindex Entries file, in CVS directory
+@cindex CVS/Entries file
+@item Entries
+This file lists the files and directories in the
+working directory.
+The first character of each line indicates what sort of
+line it is. If the character is unrecognized, programs
+reading the file should silently skip that line, to
+allow for future expansion.
+
+If the first character is @samp{/}, then the format is:
+
+@example
+/@var{name}/@var{revision}/@var{timestamp}[+@var{conflict}]/@var{options}/@var{tagdate}
+@end example
+
+@noindent
+where @samp{[} and @samp{]} are not part of the entry,
+but instead indicate that the @samp{+} and conflict
+marker are optional. @var{name} is the name of the
+file within the directory. @var{revision} is the
+revision that the file in the working derives from, or
+@samp{0} for an added file, or @samp{-} followed by a
+revision for a removed file. @var{timestamp} is the
+timestamp of the file at the time that @sc{cvs} created
+it; if the timestamp differs with the actual
+modification time of the file it means the file has
+been modified. It is stored in
+the format used by the ISO C asctime() function (for
+example, @samp{Sun Apr 7 01:29:26 1996}). One may
+write a string which is not in that format, for
+example, @samp{Result of merge}, to indicate that the
+file should always be considered to be modified. This
+is not a special case; to see whether a file is
+modified a program should take the timestamp of the file
+and simply do a string compare with @var{timestamp}.
+If there was a conflict, @var{conflict} can be set to
+the modification time of the file after the file has been
+written with conflict markers (@pxref{Conflicts example}).
+Thus if @var{conflict} is subsequently the same as the actual
+modification time of the file it means that the user
+has obviously not resolved the conflict. @var{options}
+contains sticky options (for example @samp{-kb} for a
+binary file). @var{tagdate} contains @samp{T} followed
+by a tag name, or @samp{D} for a date, followed by a
+sticky tag or date. Note that if @var{timestamp}
+contains a pair of timestamps separated by a space,
+rather than a single timestamp, you are dealing with a
+version of @sc{cvs} earlier than @sc{cvs} 1.5 (not
+documented here).
+
+The timezone on the timestamp in CVS/Entries (local or
+universal) should be the same as the operating system
+stores for the timestamp of the file itself. For
+example, on Unix the file's timestamp is in universal
+time (UT), so the timestamp in CVS/Entries should be
+too. On @sc{vms}, the file's timestamp is in local
+time, so @sc{cvs} on @sc{vms} should use local time.
+This rule is so that files do not appear to be modified
+merely because the timezone changed (for example, to or
+from summer time).
+@c See comments and calls to gmtime() and friends in
+@c src/vers_ts.c (function time_stamp).
+
+If the first character of a line in @file{Entries} is
+@samp{D}, then it indicates a subdirectory. @samp{D}
+on a line all by itself indicates that the program
+which wrote the @file{Entries} file does record
+subdirectories (therefore, if there is such a line and
+no other lines beginning with @samp{D}, one knows there
+are no subdirectories). Otherwise, the line looks
+like:
+
+@example
+D/@var{name}/@var{filler1}/@var{filler2}/@var{filler3}/@var{filler4}
+@end example
+
+@noindent
+where @var{name} is the name of the subdirectory, and
+all the @var{filler} fields should be silently ignored,
+for future expansion. Programs which modify
+@code{Entries} files should preserve these fields.
+
+The lines in the @file{Entries} file can be in any order.
+
+@cindex Entries.Log file, in CVS directory
+@cindex CVS/Entries.Log file
+@item Entries.Log
+This file does not record any information beyond that
+in @file{Entries}, but it does provide a way to update
+the information without having to rewrite the entire
+@file{Entries} file, including the ability to preserve
+the information even if the program writing
+@file{Entries} and @file{Entries.Log} abruptly aborts.
+Programs which are reading the @file{Entries} file
+should also check for @file{Entries.Log}. If the latter
+exists, they should read @file{Entries} and then apply
+the changes mentioned in @file{Entries.Log}. After
+applying the changes, the recommended practice is to
+rewrite @file{Entries} and then delete @file{Entries.Log}.
+The format of a line in @file{Entries.Log} is a single
+character command followed by a space followed by a
+line in the format specified for a line in
+@file{Entries}. The single character command is
+@samp{A} to indicate that the entry is being added,
+@samp{R} to indicate that the entry is being removed,
+or any other character to indicate that the entire line
+in @file{Entries.Log} should be silently ignored (for
+future expansion). If the second character of the line
+in @file{Entries.Log} is not a space, then it was
+written by an older version of @sc{cvs} (not documented
+here).
+
+Programs which are writing rather than reading can
+safely ignore @file{Entries.Log} if they so choose.
+
+@cindex Entries.Backup file, in CVS directory
+@cindex CVS/Entries.Backup file
+@item Entries.Backup
+This is a temporary file. Recommended usage is to
+write a new entries file to @file{Entries.Backup}, and
+then to rename it (atomically, where possible) to @file{Entries}.
+
+@cindex Entries.Static file, in CVS directory
+@cindex CVS/Entries.Static file
+@item Entries.Static
+The only relevant thing about this file is whether it
+exists or not. If it exists, then it means that only
+part of a directory was gotten and @sc{cvs} will
+not create additional files in that directory. To
+clear it, use the @code{update} command with the
+@samp{-d} option, which will get the additional files
+and remove @file{Entries.Static}.
+@c FIXME: This needs to be better documented, in places
+@c other than Working Directory Storage.
+@c FIXCVS: The fact that this setting exists needs to
+@c be more visible to the user. For example "cvs
+@c status foo", in the case where the file would be
+@c gotten except for Entries.Static, might say
+@c something to distinguish this from other cases.
+@c One thing that periodically gets suggested is to
+@c have "cvs update" print something when it skips
+@c files due to Entries.Static, but IMHO that kind of
+@c noise pretty much makes the Entries.Static feature
+@c useless.
+
+@cindex Tag file, in CVS directory
+@cindex CVS/Tag file
+@cindex Sticky tags/dates, per-directory
+@cindex Per-directory sticky tags/dates
+@item Tag
+This file contains per-directory sticky tags or dates.
+The first character is @samp{T} for a branch tag,
+@samp{N} for a non-branch tag, or @samp{D} for a date,
+or another character to mean the file should be
+silently ignored, for future expansion. This character
+is followed by the tag or date. Note that
+per-directory sticky tags or dates are used for things
+like applying to files which are newly added; they
+might not be the same as the sticky tags or dates on
+individual files. For general information on sticky
+tags and dates, see @ref{Sticky tags}.
+@c FIXME: This needs to be much better documented,
+@c preferably not in the context of "working directory
+@c storage".
+@c FIXME: The Sticky tags node needs to discuss, or xref to
+@c someplace which discusses, per-directory sticky
+@c tags and the distinction with per-file sticky tags.
+
+@cindex Notify file, in CVS directory
+@cindex CVS/Notify file
+@item Notify
+This file stores notifications (for example, for
+@code{edit} or @code{unedit}) which have not yet been
+sent to the server. Its format is not yet documented
+here.
+
+@cindex Notify.tmp file, in CVS directory
+@cindex CVS/Notify.tmp file
+@item Notify.tmp
+This file is to @file{Notify} as @file{Entries.Backup}
+is to @file{Entries}. That is, to write @file{Notify},
+first write the new contents to @file{Notify.tmp} and
+then (atomically where possible), rename it to
+@file{Notify}.
+
+@cindex Base directory, in CVS directory
+@cindex CVS/Base directory
+@item Base
+If watches are in use, then an @code{edit} command
+stores the original copy of the file in the @file{Base}
+directory. This allows the @code{unedit} command to
+operate even if it is unable to communicate with the
+server.
+
+@cindex Baserev file, in CVS directory
+@cindex CVS/Baserev file
+@item Baserev
+The file lists the revision for each of the files in
+the @file{Base} directory. The format is:
+
+@example
+B@var{name}/@var{rev}/@var{expansion}
+@end example
+
+@noindent
+where @var{expansion} should be ignored, to allow for
+future expansion.
+
+@cindex Baserev.tmp file, in CVS directory
+@cindex CVS/Baserev.tmp file
+@item Baserev.tmp
+This file is to @file{Baserev} as @file{Entries.Backup}
+is to @file{Entries}. That is, to write @file{Baserev},
+first write the new contents to @file{Baserev.tmp} and
+then (atomically where possible), rename it to
+@file{Baserev}.
+
+@cindex Template file, in CVS directory
+@cindex CVS/Template file
+@item Template
+This file contains the template specified by the
+@file{rcsinfo} file (@pxref{rcsinfo}). It is only used
+by the client; the non-client/server @sc{cvs} consults
+@file{rcsinfo} directly.
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Intro administrative files
+@section The administrative files
+@cindex Administrative files (intro)
+@cindex Modules file
+@cindex CVSROOT, module name
+@cindex Defining modules (intro)
+
+@c FIXME: this node should be reorganized into "general
+@c information about admin files" and put the "editing
+@c admin files" stuff up front rather than jumping into
+@c the details of modules right away. Then the
+@c Administrative files node can go away, the information
+@c on each admin file distributed to a place appropriate
+@c to its function, and this node can contain a table
+@c listing each file and a @ref to its detailed description.
+
+The directory @file{$CVSROOT/CVSROOT} contains some @dfn{administrative
+files}. @xref{Administrative files}, for a complete description.
+You can use @sc{cvs} without any of these files, but
+some commands work better when at least the
+@file{modules} file is properly set up.
+
+The most important of these files is the @file{modules}
+file. It defines all modules in the repository. This
+is a sample @file{modules} file.
+
+@c FIXME: The CVSROOT line is a goofy example now that
+@c mkmodules doesn't exist.
+@example
+CVSROOT CVSROOT
+modules CVSROOT modules
+cvs gnu/cvs
+rcs gnu/rcs
+diff gnu/diff
+tc yoyodyne/tc
+@end example
+
+The @file{modules} file is line oriented. In its
+simplest form each line contains the name of the
+module, whitespace, and the directory where the module
+resides. The directory is a path relative to
+@code{$CVSROOT}. The last four lines in the example
+above are examples of such lines.
+
+@c FIXME: might want to introduce the concept of options in modules file
+@c (the old example which was here, -i mkmodules, is obsolete).
+
+The line that defines the module called @samp{modules}
+uses features that are not explained here.
+@xref{modules}, for a full explanation of all the
+available features.
+
+@c FIXME: subsection without node is bogus
+@subsection Editing administrative files
+@cindex Editing administrative files
+@cindex Administrative files, editing them
+
+You edit the administrative files in the same way that you would edit
+any other module. Use @samp{cvs checkout CVSROOT} to get a working
+copy, edit it, and commit your changes in the normal way.
+
+It is possible to commit an erroneous administrative
+file. You can often fix the error and check in a new
+revision, but sometimes a particularly bad error in the
+administrative file makes it impossible to commit new
+revisions.
+@c @xref{Bad administrative files} for a hint
+@c about how to solve such situations.
+@c -- administrative file checking--
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Multiple repositories
+@section Multiple repositories
+@cindex Multiple repositories
+@cindex Repositories, multiple
+@cindex Many repositories
+@cindex Parallel repositories
+@cindex Disjoint repositories
+@cindex CVSROOT, multiple repositories
+
+In some situations it is a good idea to have more than
+one repository, for instance if you have two
+development groups that work on separate projects
+without sharing any code. All you have to do to have
+several repositories is to specify the appropriate
+repository, using the @code{CVSROOT} environment
+variable, the @samp{-d} option to @sc{cvs}, or (once
+you have checked out a working directory) by simply
+allowing @sc{cvs} to use the repository that was used
+to check out the working directory
+(@pxref{Specifying a repository}).
+
+The big advantage of having multiple repositories is
+that they can reside on different servers. With @sc{cvs}
+version 1.10, a single command cannot recurse into
+directories from different repositories. With development
+versions of @sc{cvs}, you can check out code from multiple
+servers into your working directory. @sc{cvs} will
+recurse and handle all the details of making
+connections to as many server machines as necessary to
+perform the requested command. Here is an example of
+how to set up a working directory:
+
+@example
+cvs -d server1:/cvs co dir1
+cd dir1
+cvs -d server2:/root co sdir
+cvs update
+@end example
+
+The @code{cvs co} commands set up the working
+directory, and then the @code{cvs update} command will
+contact server2, to update the dir1/sdir subdirectory,
+and server1, to update everything else.
+
+@c FIXME: Does the FAQ have more about this? I have a
+@c dim recollection, but I'm too lazy to check right now.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Creating a repository
+@section Creating a repository
+
+@cindex Repository, setting up
+@cindex Creating a repository
+@cindex Setting up a repository
+
+This section describes how to set up a @sc{cvs} repository for any
+sort of access method. After completing the setup described in this
+section, you should be able to access your @sc{cvs} repository immediately
+via the local access method and several remote access methods. For
+more information on setting up remote access to the repository you create
+in this section, please read the section on @xref{Remote repositories}.
+
+To set up a @sc{cvs} repository, first choose the
+machine and disk on which you want to store the
+revision history of the source files. CPU and memory
+requirements are modest, so most machines should be
+adequate. For details see @ref{Server requirements}.
+@c Possible that we should be providing a quick rule of
+@c thumb, like the 32M memory for the server. That
+@c might increase the number of people who are happy
+@c with the answer, without following the xref.
+
+To estimate disk space
+requirements, if you are importing RCS files from
+another system, the size of those files is the
+approximate initial size of your repository, or if you
+are starting without any version history, a rule of
+thumb is to allow for the server approximately three
+times the size of the code to be under @sc{cvs} for the
+repository (you will eventually outgrow this, but not
+for a while). On the machines on which the developers
+will be working, you'll want disk space for
+approximately one working directory for each developer
+(either the entire tree or a portion of it, depending
+on what each developer uses).
+
+The repository should be accessible
+(directly or via a networked file system) from all
+machines which want to use @sc{cvs} in server or local
+mode; the client machines need not have any access to
+it other than via the @sc{cvs} protocol. It is not
+possible to use @sc{cvs} to read from a repository
+which one only has read access to; @sc{cvs} needs to be
+able to create lock files (@pxref{Concurrency}).
+
+@cindex init (subcommand)
+To create a repository, run the @code{cvs init}
+command. It will set up an empty repository in the
+@sc{cvs} root specified in the usual way
+(@pxref{Repository}). For example,
+
+@example
+cvs -d /usr/local/cvsroot init
+@end example
+
+@code{cvs init} is careful to never overwrite any
+existing files in the repository, so no harm is done if
+you run @code{cvs init} on an already set-up
+repository.
+
+@code{cvs init} will enable history logging; if you
+don't want that, remove the history file after running
+@code{cvs init}. @xref{history file}.
+
+@node Backing up
+@section Backing up a repository
+@cindex Repository, backing up
+@cindex Backing up, repository
+
+There is nothing particularly magical about the files
+in the repository; for the most part it is possible to
+back them up just like any other files. However, there
+are a few issues to consider.
+
+@cindex Locks, cvs, and backups
+@cindex #cvs.rfl, and backups
+The first is that to be paranoid, one should either not
+use @sc{cvs} during the backup, or have the backup
+program lock @sc{cvs} while doing the backup. To not
+use @sc{cvs}, you might forbid logins to machines which
+can access the repository, turn off your @sc{cvs}
+server, or similar mechanisms. The details would
+depend on your operating system and how you have
+@sc{cvs} set up. To lock @sc{cvs}, you would create
+@file{#cvs.rfl} locks in each repository directory.
+See @ref{Concurrency}, for more on @sc{cvs} locks.
+Having said all this, if you just back up without any
+of these precautions, the results are unlikely to be
+particularly dire. Restoring from backup, the
+repository might be in an inconsistent state, but this
+would not be particularly hard to fix manually.
+
+When you restore a repository from backup, assuming
+that changes in the repository were made after the time
+of the backup, working directories which were not
+affected by the failure may refer to revisions which no
+longer exist in the repository. Trying to run @sc{cvs}
+in such directories will typically produce an error
+message. One way to get those changes back into the
+repository is as follows:
+
+@itemize @bullet
+@item
+Get a new working directory.
+
+@item
+Copy the files from the working directory from before
+the failure over to the new working directory (do not
+copy the contents of the @file{CVS} directories, of
+course).
+
+@item
+Working in the new working directory, use commands such
+as @code{cvs update} and @code{cvs diff} to figure out
+what has changed, and then when you are ready, commit
+the changes into the repository.
+@end itemize
+
+@node Moving a repository
+@section Moving a repository
+@cindex Repository, moving
+@cindex Moving a repository
+@cindex Copying a repository
+
+Just as backing up the files in the repository is
+pretty much like backing up any other files, if you
+need to move a repository from one place to another it
+is also pretty much like just moving any other
+collection of files.
+
+The main thing to consider is that working directories
+point to the repository. The simplest way to deal with
+a moved repository is to just get a fresh working
+directory after the move. Of course, you'll want to
+make sure that the old working directory had been
+checked in before the move, or you figured out some
+other way to make sure that you don't lose any
+changes. If you really do want to reuse the existing
+working directory, it should be possible with manual
+surgery on the @file{CVS/Repository} files. You can
+see @ref{Working directory storage}, for information on
+the @file{CVS/Repository} and @file{CVS/Root} files, but
+unless you are sure you want to bother, it probably
+isn't worth it.
+@c FIXME: Surgery on CVS/Repository should be avoided
+@c by making RELATIVE_REPOS the default.
+@c FIXME-maybe: might want some documented way to
+@c change the CVS/Root files in some particular tree.
+@c But then again, I don't know, maybe just having
+@c people do this in perl/shell/&c isn't so bad...
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Remote repositories
+@section Remote repositories
+@cindex Repositories, remote
+@cindex Remote repositories
+@cindex Client/Server Operation
+@cindex Server, CVS
+@cindex Remote repositories, port specification
+@cindex Repositories, remote, port specification
+@cindex Client/Server Operation, port specification
+@cindex pserver (client/server connection method), port specification
+@cindex kserver (client/server connection method), port specification
+@cindex gserver (client/server connection method), port specification
+@cindex port, specifying for remote repositories
+
+ Your working copy of the sources can be on a
+different machine than the repository. Using @sc{cvs}
+in this manner is known as @dfn{client/server}
+operation. You run @sc{cvs} on a machine which can
+mount your working directory, known as the
+@dfn{client}, and tell it to communicate to a machine
+which can mount the repository, known as the
+@dfn{server}. Generally, using a remote
+repository is just like using a local one, except that
+the format of the repository name is:
+
+@example
+[:@var{method}:][[@var{user}][:@var{password}]@@]@var{hostname}[:[@var{port}]]/path/to/repository
+@end example
+
+Specifying a password in the repository name is not recommended during
+checkout, since this will cause @sc{cvs} to store a cleartext copy of the
+password in each created directory. @code{cvs login} first instead
+(@pxref{Password authentication client}).
+
+The details of exactly what needs to be set up depend
+on how you are connecting to the server.
+
+@c Should we try to explain which platforms are which?
+@c Platforms like unix and VMS, which only allow
+@c privileged programs to bind to sockets <1024 lose on
+@c :server:
+@c Platforms like Mac and VMS, whose rsh program is
+@c unusable or nonexistent, lose on :ext:
+@c Platforms like OS/2 and NT probably could plausibly
+@c default either way (modulo -b troubles).
+
+@menu
+* Server requirements:: Memory and other resources for servers
+* The connection method:: Connection methods and method options
+* Connecting via rsh:: Using the @code{rsh} program to connect
+* Password authenticated:: Direct connections using passwords
+* GSSAPI authenticated:: Direct connections using GSSAPI
+* Kerberos authenticated:: Direct connections with Kerberos
+* Connecting via fork:: Using a forked @code{cvs server} to connect
+* Write proxies:: Distributing load across several CVS servers
+@end menu
+
+@node Server requirements
+@subsection Server requirements
+
+The quick answer to what sort of machine is suitable as
+a server is that requirements are modest---a server
+with 32M of memory or even less can handle a fairly
+large source tree with a fair amount of activity.
+@c Say something about CPU speed too? I'm even less sure
+@c what to say on that subject...
+
+The real answer, of course, is more complicated.
+Estimating the known areas of large memory consumption
+should be sufficient to estimate memory requirements.
+There are two such areas documented here; other memory
+consumption should be small by comparison (if you find
+that is not the case, let us know, as described in
+@ref{BUGS}, so we can update this documentation).
+
+The first area of big memory consumption is large
+checkouts, when using the @sc{cvs} server. The server
+consists of two processes for each client that it is
+serving. Memory consumption on the child process
+should remain fairly small. Memory consumption on the
+parent process, particularly if the network connection
+to the client is slow, can be expected to grow to
+slightly more than the size of the sources in a single
+directory, or two megabytes, whichever is larger.
+@c "two megabytes" of course is SERVER_HI_WATER. But
+@c we don't mention that here because we are
+@c documenting the default configuration of CVS. If it
+@c is a "standard" thing to change that value, it
+@c should be some kind of run-time configuration.
+@c
+@c See cvsclient.texi for more on the design decision
+@c to not have locks in place while waiting for the
+@c client, which is what results in memory consumption
+@c as high as this.
+
+Multiplying the size of each @sc{cvs} server by the
+number of servers which you expect to have active at
+one time should give an idea of memory requirements for
+the server. For the most part, the memory consumed by
+the parent process probably can be swap space rather
+than physical memory.
+@c Has anyone verified that notion about swap space?
+@c I say it based pretty much on guessing that the
+@c ->text of the struct buffer_data only gets accessed
+@c in a first in, first out fashion, but I haven't
+@c looked very closely.
+
+@c What about disk usage in /tmp on the server? I think that
+@c it can be substantial, but I haven't looked at this
+@c again and tried to figure it out ("cvs import" is
+@c probably the worst case...).
+
+The second area of large memory consumption is
+@code{diff}, when checking in large files. This is
+required even for binary files. The rule of thumb is
+to allow about ten times the size of the largest file
+you will want to check in, although five times may be
+adequate. For example, if you want to check in a file
+which is 10 megabytes, you should have 100 megabytes of
+memory on the machine doing the checkin (the server
+machine for client/server, or the machine running
+@sc{cvs} for non-client/server). This can be swap
+space rather than physical memory. Because the memory
+is only required briefly, there is no particular need
+to allow memory for more than one such checkin at a
+time.
+@c The 5-10 times rule of thumb is from Paul Eggert for
+@c GNU diff. I don't think it is in the GNU diff
+@c manual or anyplace like that.
+@c
+@c Probably we could be saying more about
+@c non-client/server CVS.
+@c I would guess for non-client/server CVS in an NFS
+@c environment the biggest issues are the network and
+@c the NFS server.
+
+Resource consumption for the client is even more
+modest---any machine with enough capacity to run the
+operating system in question should have little
+trouble.
+@c Is that true? I think the client still wants to
+@c (bogusly) store entire files in memory at times.
+
+For information on disk space requirements, see
+@ref{Creating a repository}.
+
+@node The connection method
+@subsection The connection method
+
+In its simplest form, the @var{method} portion of the repository string
+(@pxref{Remote repositories}) may be one of @samp{ext}, @samp{fork},
+@samp{gserver}, @samp{kserver}, @samp{local}, @samp{pserver}, and, on some
+platforms, @samp{server}.
+
+If @var{method} is not specified, and the repository
+name starts with a @samp{/}, then the default is @code{local}.
+If @var{method} is not specified, and the repository
+name does not start with a @samp{/}, then the default is @code{ext}
+or @code{server}, depending on your platform; both the @samp{ext}
+and @samp{server} methods are described in @ref{Connecting via rsh}.
+
+@cindex connection method options
+@cindex options, connection method
+The @code{ext}, @code{fork}, @code{gserver}, and @code{pserver} connection
+methods all accept optional method options, specified as part of the
+@var{method} string, like so:
+
+@example
+:@var{method}[;@var{option}=@var{arg}...]:@var{other_connection_data}
+@end example
+
+@sc{cvs} is not sensitive to the case of @var{method} or @var{option}, though
+it may sometimes be sensitive to the case of @var{arg}. The possible method
+options are as follows:
+
+@table @code
+@cindex CVS_PROXY_PORT
+@cindex proxy, method option
+@cindex proxyport, method option
+@cindex proxies, web, connecting via
+@cindex web proxies, connecting via
+@cindex proxies, HTTP, connecting via
+@cindex HTTP proxies, connecting via
+@item proxy=@var{hostname}
+@itemx proxyport=@var{port}
+These two method options can be used to connect via an HTTP tunnel style web
+proxy. @var{hostname} should be the name of the HTTP proxy server to connect
+through and @var{port} is the port number on the HTTP proxy server to connect
+via. @var{port} defaults to 8080.
+
+@strong{NOTE: An HTTP proxy server is not the same as a @sc{cvs} write proxy
+server - please see @ref{Write proxies} for more on @sc{cvs} write proxies.}
+
+For example, to connect pserver via a web proxy listening on port 8000 of
+www.myproxy.net, you would use a method of:
+
+@example
+:pserver;proxy=www.myproxy.net;proxyport=8000:@var{pserver_connection_string}
+@end example
+
+@strong{NOTE: In the above example, @var{pserver_connection_string} is still
+required to connect and authenticate to the CVS server, as noted in the
+upcoming sections on password authentication, @code{gserver}, and
+@code{kserver}. The example above only demonstrates a modification to the
+@var{method} portion of the repository name.}
+
+These options first appeared in @sc{cvs} version 1.12.7 and are valid as
+modifcations to the @code{gserver} and @code{pserver} connection methods.
+
+@cindex CVS_RSH method option
+@item CVS_RSH=@var{path}
+This method option can be used with the @code{ext} method to specify the path
+the @sc{cvs} client will use to find the remote shell used to contact the
+@sc{cvs} server and takes precedence over any path specified in the
+@code{$CVS_RSH} environment variable (@pxref{Connecting via rsh}). For
+example, to connect to a @sc{cvs} server via the local
+@file{/path/to/ssh/command} command, you could choose to specify the following
+@var{path} via the @code{CVS_RSH} method option:
+
+@example
+:ext;CVS_RSH=/path/to/ssh/command:@var{ext_connection_string}
+@end example
+
+This method option first appeared in @sc{cvs} version 1.12.11 and is valid only
+as a modifcation to the @code{ext} connection method.
+
+@cindex CVS_SERVER method option
+@item CVS_SERVER=@var{path}
+This method option can be used with the @code{ext} and @code{fork} methods to
+specify the path @sc{cvs} will use to find the @sc{cvs} executable on the
+@sc{cvs} server and takes precedence over any path specified in the
+@code{$CVS_SERVER} environment variable (@pxref{Connecting via rsh}). For
+example, to select the remote @file{/path/to/cvs/command} executable as your
+@sc{cvs} server application on the @sc{cvs} server machine, you could choose to
+specify the following @var{path} via the @code{CVS_SERVER} method option:
+
+@example
+:ext;CVS_SERVER=/path/to/cvs/command:@var{ext_connection_string}
+@end example
+
+@noindent
+or, to select an executable named @samp{cvs-1.12.11}, assuming it is in your
+@code{$PATH} on the @sc{cvs} server:
+
+@example
+:ext;CVS_SERVER=cvs-1.12.11:@var{ext_connection_string}
+@end example
+
+This method option first appeared in @sc{cvs} version 1.12.11 and is valid
+as a modifcation to both the @code{ext} and @code{fork} connection methods.
+
+@cindex Redirect, method option
+@item Redirect=@var{boolean-state}
+The @code{Redirect} method option determines whether the @sc{cvs} client will
+allow a @sc{cvs} server to redirect it to a different @sc{cvs} server, usually
+for write requests, as in a write proxy setup.
+
+A @var{boolean-state} of any value acceptable for boolean @file{CVSROOT/config}
+file options is acceptable here (@pxref{config}). For example, @samp{on},
+@samp{off}, @samp{true}, and @samp{false} are all valid values for
+@var{boolean-state}. @var{boolean-state} for the @code{Redirect} method option
+defaults to @samp{on}.
+
+This option will have no effect when talking to any non-secondary @sc{cvs}
+server. For more on write proxies and secondary servers, please see
+@ref{Write proxies}.
+
+This method option first appeared in @sc{cvs} version 1.12.11 and is valid only
+as a modifcation to the @code{ext} connection method.
+@end table
+
+As a further example, to combine both the @code{CVS_RSH} and @code{CVS_SERVER}
+options, a method specification like the following would work:
+
+@example
+:ext;CVS_RSH=/path/to/ssh/command;CVS_SERVER=/path/to/cvs/command:
+@end example
+
+This means that you would not need to have
+the @code{CVS_SERVER} or @code{CVS_RSH} environment
+variables set correctly. See @ref{Connecting via rsh}, for more details on
+these environment variables.
+
+@node Connecting via rsh
+@subsection Connecting with rsh
+
+@cindex rsh
+@sc{cvs} uses the @samp{rsh} protocol to perform these
+operations, so the remote user host needs to have a
+@file{.rhosts} file which grants access to the local
+user. Note that the program that @sc{cvs} uses for this
+purpose may be specified using the @file{--with-rsh}
+flag to configure.
+
+For example, suppose you are the user @samp{mozart} on
+the local machine @samp{toe.example.com}, and the
+server machine is @samp{faun.example.org}. On
+faun, put the following line into the file
+@file{.rhosts} in @samp{bach}'s home directory:
+
+@example
+toe.example.com mozart
+@end example
+
+@noindent
+Then test that @samp{rsh} is working with
+
+@example
+rsh -l bach faun.example.org 'echo $PATH'
+@end example
+
+@cindex CVS_SERVER, environment variable
+Next you have to make sure that @code{rsh} will be able
+to find the server. Make sure that the path which
+@code{rsh} printed in the above example includes the
+directory containing a program named @code{cvs} which
+is the server. You need to set the path in
+@file{.bashrc}, @file{.cshrc}, etc., not @file{.login}
+or @file{.profile}. Alternately, you can set the
+environment variable @code{CVS_SERVER} on the client
+machine to the filename of the server you want to use,
+for example @file{/usr/local/bin/cvs-1.6}.
+For the @code{ext} and @code{fork} methods, you may
+also specify @var{CVS_SERVER} as an otpion in the
+@var{CVSROOT} so that you may use different servers for
+differnt roots. See @ref{Remote repositories} for more
+details.
+
+There is no need to edit @file{inetd.conf} or start a
+@sc{cvs} server daemon.
+
+@cindex :server:, setting up
+@cindex :ext:, setting up
+@cindex Kerberos, using kerberized rsh
+@cindex SSH (rsh replacement)
+@cindex rsh replacements (Kerberized, SSH, &c)
+There are two access methods that you use in @code{CVSROOT}
+for rsh. @code{:server:} specifies an internal rsh
+client, which is supported only by some @sc{cvs} ports.
+@code{:ext:} specifies an external rsh program. By
+default this is @code{rsh} (unless otherwise specified
+by the @file{--with-rsh} flag to configure) but you may set the
+@code{CVS_RSH} environment variable to invoke another
+program which can access the remote server (for
+example, @code{remsh} on HP-UX 9 because @code{rsh} is
+something different). It must be a program which can
+transmit data to and from the server without modifying
+it; for example the Windows NT @code{rsh} is not
+suitable since it by default translates between CRLF
+and LF. The OS/2 @sc{cvs} port has a hack to pass @samp{-b}
+to @code{rsh} to get around this, but since this could
+potentially cause problems for programs other than the
+standard @code{rsh}, it may change in the future. If
+you set @code{CVS_RSH} to @code{SSH} or some other rsh
+replacement, the instructions in the rest of this
+section concerning @file{.rhosts} and so on are likely
+to be inapplicable; consult the documentation for your rsh
+replacement.
+
+You may choose to specify the @var{CVS_RSH} option as a method option
+in the @var{CVSROOT} string to allow you to use different connection tools
+for different roots (@pxref{The connection method}). For example, allowing
+some roots to use @code{CVS_RSH=remsh} and some to use
+@code{CVS_RSH=ssh} for the @code{ext} method. See also
+the @ref{Remote repositories} for more details.
+@c See also the comment in src/client.c for rationale
+@c concerning "rsh" being the default and never
+@c "remsh".
+
+Continuing our example, supposing you want to access
+the module @file{foo} in the repository
+@file{/usr/local/cvsroot/}, on machine
+@file{faun.example.org}, you are ready to go:
+
+@example
+cvs -d :ext:bach@@faun.example.org:/usr/local/cvsroot checkout foo
+@end example
+
+@noindent
+(The @file{bach@@} can be omitted if the username is
+the same on both the local and remote hosts.)
+
+@c Should we mention "rsh host echo hi" and "rsh host
+@c cat" (the latter followed by typing text and ^D)
+@c as troubleshooting techniques? Probably yes
+@c (people tend to have trouble setting this up),
+@c but this kind of thing can be hard to spell out.
+
+@node Password authenticated
+@subsection Direct connection with password authentication
+
+The @sc{cvs} client can also connect to the server
+using a password protocol. This is particularly useful
+if using @code{rsh} is not feasible (for example,
+the server is behind a firewall), and Kerberos also is
+not available.
+
+ To use this method, it is necessary to make
+some adjustments on both the server and client sides.
+
+@menu
+* Password authentication server:: Setting up the server
+* Password authentication client:: Using the client
+* Password authentication security:: What this method does and does not do
+@end menu
+
+@node Password authentication server
+@subsubsection Setting up the server for password authentication
+
+First of all, you probably want to tighten the
+permissions on the @file{$CVSROOT} and
+@file{$CVSROOT/CVSROOT} directories. See @ref{Password
+authentication security}, for more details.
+
+@cindex pserver (subcommand)
+@cindex Remote repositories, port specification
+@cindex Repositories, remote, port specification
+@cindex Client/Server Operation, port specification
+@cindex pserver (client/server connection method), port specification
+@cindex kserver (client/server connection method), port specification
+@cindex gserver (client/server connection method), port specification
+@cindex port, specifying for remote repositories
+@cindex Password server, setting up
+@cindex Authenticating server, setting up
+@cindex inetd, configuring for pserver
+@cindex xinetd, configuring for pserver
+@c FIXME: this isn't quite right regarding port
+@c numbers; CVS looks up "cvspserver" in
+@c /etc/services (on unix, but what about non-unix?).
+On the server side, the file @file{/etc/inetd.conf}
+needs to be edited so @code{inetd} knows to run the
+command @code{cvs pserver} when it receives a
+connection on the right port. By default, the port
+number is 2401; it would be different if your client
+were compiled with @code{CVS_AUTH_PORT} defined to
+something else, though. This can also be specified in the CVSROOT variable
+(@pxref{Remote repositories}) or overridden with the CVS_CLIENT_PORT
+environment variable (@pxref{Environment variables}).
+
+ If your @code{inetd} allows raw port numbers in
+@file{/etc/inetd.conf}, then the following (all on a
+single line in @file{inetd.conf}) should be sufficient:
+
+@example
+2401 stream tcp nowait root /usr/local/bin/cvs
+cvs -f --allow-root=/usr/cvsroot pserver
+@end example
+
+@noindent
+(You could also use the
+@samp{-T} option to specify a temporary directory.)
+
+The @samp{--allow-root} option specifies the allowable
+@sc{cvsroot} directory. Clients which attempt to use a
+different @sc{cvsroot} directory will not be allowed to
+connect. If there is more than one @sc{cvsroot}
+directory which you want to allow, repeat the option.
+(Unfortunately, many versions of @code{inetd} have very small
+limits on the number of arguments and/or the total length
+of the command. The usual solution to this problem is
+to have @code{inetd} run a shell script which then invokes
+@sc{cvs} with the necessary arguments.)
+
+ If your @code{inetd} wants a symbolic service
+name instead of a raw port number, then put this in
+@file{/etc/services}:
+
+@example
+cvspserver 2401/tcp
+@end example
+
+@noindent
+and put @code{cvspserver} instead of @code{2401} in @file{inetd.conf}.
+
+If your system uses @code{xinetd} instead of @code{inetd},
+the procedure is slightly different.
+Create a file called @file{/etc/xinetd.d/cvspserver} containing the following:
+
+@example
+service cvspserver
+@{
+ port = 2401
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = root
+ passenv = PATH
+ server = /usr/local/bin/cvs
+ server_args = -f --allow-root=/usr/cvsroot pserver
+@}
+@end example
+
+@noindent
+(If @code{cvspserver} is defined in @file{/etc/services}, you can omit
+the @code{port} line.)
+
+ Once the above is taken care of, restart your
+@code{inetd}, or do whatever is necessary to force it
+to reread its initialization files.
+
+If you are having trouble setting this up, see
+@ref{Connection}.
+
+@cindex CVS passwd file
+@cindex passwd (admin file)
+Because the client stores and transmits passwords in
+cleartext (almost---see @ref{Password authentication
+security}, for details), a separate @sc{cvs} password
+file is generally used, so people don't compromise
+their regular passwords when they access the
+repository. This file is
+@file{$CVSROOT/CVSROOT/passwd} (@pxref{Intro
+administrative files}). It uses a colon-separated
+format, similar to @file{/etc/passwd} on Unix systems,
+except that it has fewer fields: @sc{cvs} username,
+optional password, and an optional system username for
+@sc{cvs} to run as if authentication succeeds. Here is
+an example @file{passwd} file with five entries:
+
+@example
+anonymous:
+bach:ULtgRLXo7NRxs
+spwang:1sOp854gDF3DY
+melissa:tGX1fS8sun6rY:pubcvs
+qproj:XR4EZcEs0szik:pubcvs
+@end example
+
+@noindent
+(The passwords are encrypted according to the standard
+Unix @code{crypt()} function, so it is possible to
+paste in passwords directly from regular Unix
+@file{/etc/passwd} files.)
+
+The first line in the example will grant access to any
+@sc{cvs} client attempting to authenticate as user
+@code{anonymous}, no matter what password they use,
+including an empty password. (This is typical for
+sites granting anonymous read-only access; for
+information on how to do the "read-only" part, see
+@ref{Read-only access}.)
+
+The second and third lines will grant access to
+@code{bach} and @code{spwang} if they supply their
+respective plaintext passwords.
+
+@cindex User aliases
+The fourth line will grant access to @code{melissa}, if
+she supplies the correct password, but her @sc{cvs}
+operations will actually run on the server side under
+the system user @code{pubcvs}. Thus, there need not be
+any system user named @code{melissa}, but there
+@emph{must} be one named @code{pubcvs}.
+
+The fifth line shows that system user identities can be
+shared: any client who successfully authenticates as
+@code{qproj} will actually run as @code{pubcvs}, just
+as @code{melissa} does. That way you could create a
+single, shared system user for each project in your
+repository, and give each developer their own line in
+the @file{$CVSROOT/CVSROOT/passwd} file. The @sc{cvs}
+username on each line would be different, but the
+system username would be the same. The reason to have
+different @sc{cvs} usernames is that @sc{cvs} will log their
+actions under those names: when @code{melissa} commits
+a change to a project, the checkin is recorded in the
+project's history under the name @code{melissa}, not
+@code{pubcvs}. And the reason to have them share a
+system username is so that you can arrange permissions
+in the relevant area of the repository such that only
+that account has write-permission there.
+
+If the system-user field is present, all
+password-authenticated @sc{cvs} commands run as that
+user; if no system user is specified, @sc{cvs} simply
+takes the @sc{cvs} username as the system username and
+runs commands as that user. In either case, if there
+is no such user on the system, then the @sc{cvs}
+operation will fail (regardless of whether the client
+supplied a valid password).
+
+The password and system-user fields can both be omitted
+(and if the system-user field is omitted, then also
+omit the colon that would have separated it from the
+encrypted password). For example, this would be a
+valid @file{$CVSROOT/CVSROOT/passwd} file:
+
+@example
+anonymous::pubcvs
+fish:rKa5jzULzmhOo:kfogel
+sussman:1sOp854gDF3DY
+@end example
+
+@noindent
+When the password field is omitted or empty, then the
+client's authentication attempt will succeed with any
+password, including the empty string. However, the
+colon after the @sc{cvs} username is always necessary,
+even if the password is empty.
+
+@sc{cvs} can also fall back to use system authentication.
+When authenticating a password, the server first checks
+for the user in the @file{$CVSROOT/CVSROOT/passwd}
+file. If it finds the user, it will use that entry for
+authentication as described above. But if it does not
+find the user, or if the @sc{cvs} @file{passwd} file
+does not exist, then the server can try to authenticate
+the username and password using the operating system's
+user-lookup routines (this "fallback" behavior can be
+disabled by setting @code{SystemAuth=no} in the
+@sc{cvs} @file{config} file, @pxref{config}).
+
+The default fallback behavior is to look in
+@file{/etc/passwd} for this system user unless your
+system has PAM (Pluggable Authentication Modules)
+and your @sc{cvs} server executable was configured to
+use it at compile time (using @code{./configure --enable-pam} - see the
+INSTALL file for more). In this case, PAM will be consulted instead.
+This means that @sc{cvs} can be configured to use any password
+authentication source PAM can be configured to use (possibilities
+include a simple UNIX password, NIS, LDAP, and others) in its
+global configuration file (usually @file{/etc/pam.conf}
+or possibly @file{/etc/pam.d/cvs}). See your PAM documentation
+for more details on PAM configuration.
+
+Note that PAM is an experimental feature in @sc{cvs} and feedback is
+encouraged. Please send a mail to one of the @sc{cvs} mailing lists
+(@code{info-cvs@@nongnu.org} or @code{bug-cvs@@nongnu.org}) if you use the
+@sc{cvs} PAM support.
+
+@strong{WARNING: Using PAM gives the system administrator much more
+flexibility about how @sc{cvs} users are authenticated but
+no more security than other methods. See below for more.}
+
+CVS needs an "auth", "account" and "session" module in the
+PAM configuration file. A typical PAM configuration
+would therefore have the following lines
+in @file{/etc/pam.conf} to emulate the standard @sc{cvs}
+system @file{/etc/passwd} authentication:
+
+@example
+cvs auth required pam_unix.so
+cvs account required pam_unix.so
+cvs session required pam_unix.so
+@end example
+
+The the equivalent @file{/etc/pam.d/cvs} would contain
+
+@example
+auth required pam_unix.so
+account required pam_unix.so
+session required pam_unix.so
+@end example
+
+Some systems require a full path to the module so that
+@file{pam_unix.so} (Linux) would become something like
+@file{/usr/lib/security/$ISA/pam_unix.so.1} (Sun Solaris).
+See the @file{contrib/pam} subdirectory of the @sc{cvs}
+source distribution for further example configurations.
+
+The PAM service name given above as "cvs" is just
+the service name in the default configuration and can be
+set using
+@code{./configure --with-hardcoded-pam-service-name=<pam-service-name>}
+before compiling. @sc{cvs} can also be configured to use whatever
+name it is invoked as as its PAM service name using
+@code{./configure --without-hardcoded-pam-service-name}, but this
+feature should not be used if you may not have control of the name
+@sc{cvs} will be invoked as.
+
+Be aware, also, that falling back to system
+authentication might be a security risk: @sc{cvs}
+operations would then be authenticated with that user's
+regular login password, and the password flies across
+the network in plaintext. See @ref{Password
+authentication security} for more on this.
+This may be more of a problem with PAM authentication
+because it is likely that the source of the system
+password is some central authentication service like
+LDAP which is also used to authenticate other services.
+
+On the other hand, PAM makes it very easy to change your password
+regularly. If they are given the option of a one-password system for
+all of their activities, users are often more willing to change their
+password on a regular basis.
+
+In the non-PAM configuration where the password is stored in the
+@file{CVSROOT/passwd} file, it is difficult to change passwords on a
+regular basis since only administrative users (or in some cases
+processes that act as an administrative user) are typically given
+access to modify this file. Either there needs to be some
+hand-crafted web page or set-uid program to update the file, or the
+update needs to be done by submitting a request to an administrator to
+perform the duty by hand. In the first case, having to remember to
+update a separate password on a periodic basis can be difficult. In
+the second case, the manual nature of the change will typically mean
+that the password will not be changed unless it is absolutely
+necessary.
+
+Note that PAM administrators should probably avoid configuring
+one-time-passwords (OTP) for @sc{cvs} authentication/authorization. If
+OTPs are desired, the administrator may wish to encourage the use of
+one of the other Client/Server access methods. See the section on
+@pxref{Remote repositories} for a list of other methods.
+
+Right now, the only way to put a password in the
+@sc{cvs} @file{passwd} file is to paste it there from
+somewhere else. Someday, there may be a @code{cvs
+passwd} command.
+
+Unlike many of the files in @file{$CVSROOT/CVSROOT}, it
+is normal to edit the @file{passwd} file in-place,
+rather than via @sc{cvs}. This is because of the
+possible security risks of having the @file{passwd}
+file checked out to people's working copies. If you do
+want to include the @file{passwd} file in checkouts of
+@file{$CVSROOT/CVSROOT}, see @ref{checkoutlist}.
+
+@c We might also suggest using the @code{htpasswd} command
+@c from freely available web servers as well, but that
+@c would open up a can of worms in that the users next
+@c questions are likely to be "where do I get it?" and
+@c "how do I use it?"
+@c Also note that htpasswd, at least the version I had,
+@c likes to clobber the third field.
+
+@node Password authentication client
+@subsubsection Using the client with password authentication
+@cindex Login (subcommand)
+@cindex Password client, using
+@cindex Authenticated client, using
+@cindex :pserver:, setting up
+To run a @sc{cvs} command on a remote repository via
+the password-authenticating server, one specifies the
+@code{pserver} protocol, optional username, repository host, an
+optional port number, and path to the repository. For example:
+
+@example
+cvs -d :pserver:faun.example.org:/usr/local/cvsroot checkout someproj
+@end example
+
+@noindent
+or
+
+@example
+CVSROOT=:pserver:bach@@faun.example.org:2401/usr/local/cvsroot
+cvs checkout someproj
+@end example
+
+However, unless you're connecting to a public-access
+repository (i.e., one where that username doesn't
+require a password), you'll need to supply a password or @dfn{log in} first.
+Logging in verifies your password with the repository and stores it in a file.
+It's done with the @code{login} command, which will
+prompt you interactively for the password if you didn't supply one as part of
+@var{$CVSROOT}:
+
+@example
+cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot login
+CVS password:
+@end example
+
+@noindent
+or
+
+@example
+cvs -d :pserver:bach:p4ss30rd@@faun.example.org:/usr/local/cvsroot login
+@end example
+
+After you enter the password, @sc{cvs} verifies it with
+the server. If the verification succeeds, then that
+combination of username, host, repository, and password
+is permanently recorded, so future transactions with
+that repository won't require you to run @code{cvs
+login}. (If verification fails, @sc{cvs} will exit
+complaining that the password was incorrect, and
+nothing will be recorded.)
+
+The records are stored, by default, in the file
+@file{$HOME/.cvspass}. That file's format is
+human-readable, and to a degree human-editable, but
+note that the passwords are not stored in
+cleartext---they are trivially encoded to protect them
+from "innocent" compromise (i.e., inadvertent viewing
+by a system administrator or other non-malicious
+person).
+
+@cindex CVS_PASSFILE, environment variable
+You can change the default location of this file by
+setting the @code{CVS_PASSFILE} environment variable.
+If you use this variable, make sure you set it
+@emph{before} @code{cvs login} is run. If you were to
+set it after running @code{cvs login}, then later
+@sc{cvs} commands would be unable to look up the
+password for transmission to the server.
+
+Once you have logged in, all @sc{cvs} commands using
+that remote repository and username will authenticate
+with the stored password. So, for example
+
+@example
+cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot checkout foo
+@end example
+
+@noindent
+should just work (unless the password changes on the
+server side, in which case you'll have to re-run
+@code{cvs login}).
+
+Note that if the @samp{:pserver:} were not present in
+the repository specification, @sc{cvs} would assume it
+should use @code{rsh} to connect with the server
+instead (@pxref{Connecting via rsh}).
+
+Of course, once you have a working copy checked out and
+are running @sc{cvs} commands from within it, there is
+no longer any need to specify the repository
+explicitly, because @sc{cvs} can deduce the repository
+from the working copy's @file{CVS} subdirectory.
+
+@c FIXME: seems to me this needs somewhat more
+@c explanation.
+@cindex Logout (subcommand)
+The password for a given remote repository can be
+removed from the @code{CVS_PASSFILE} by using the
+@code{cvs logout} command.
+
+@node Password authentication security
+@subsubsection Security considerations with password authentication
+
+@cindex Security, of pserver
+The passwords are stored on the client side in a
+trivial encoding of the cleartext, and transmitted in
+the same encoding. The encoding is done only to
+prevent inadvertent password compromises (i.e., a
+system administrator accidentally looking at the file),
+and will not prevent even a naive attacker from gaining
+the password.
+
+@c FIXME: The bit about "access to the repository
+@c implies general access to the system is *not* specific
+@c to pserver; it applies to kerberos and SSH and
+@c everything else too. Should reorganize the
+@c documentation to make this clear.
+The separate @sc{cvs} password file (@pxref{Password
+authentication server}) allows people
+to use a different password for repository access than
+for login access. On the other hand, once a user has
+non-read-only
+access to the repository, she can execute programs on
+the server system through a variety of means. Thus, repository
+access implies fairly broad system access as well. It
+might be possible to modify @sc{cvs} to prevent that,
+but no one has done so as of this writing.
+@c OpenBSD uses chroot() and copies the repository to
+@c provide anonymous read-only access (for details see
+@c http://www.openbsd.org/anoncvs.shar). While this
+@c closes the most obvious holes, I'm not sure it
+@c closes enough holes to recommend it (plus it is
+@c *very* easy to accidentally screw up a setup of this
+@c type).
+
+Note that because the @file{$CVSROOT/CVSROOT} directory
+contains @file{passwd} and other files which are used
+to check security, you must control the permissions on
+this directory as tightly as the permissions on
+@file{/etc}. The same applies to the @file{$CVSROOT}
+directory itself and any directory
+above it in the tree. Anyone who has write access to
+such a directory will have the ability to become any
+user on the system. Note that these permissions are
+typically tighter than you would use if you are not
+using pserver.
+@c TODO: Would be really nice to document/implement a
+@c scheme where the CVS server can run as some non-root
+@c user, e.g. "cvs". CVSROOT/passwd would contain a
+@c bunch of entries of the form foo:xxx:cvs (or the "cvs"
+@c would be implicit). This would greatly reduce
+@c security risks such as those hinted at in the
+@c previous paragraph. I think minor changes to CVS
+@c might be required but mostly this would just need
+@c someone who wants to play with it, document it, &c.
+
+In summary, anyone who gets the password gets
+repository access (which may imply some measure of general system
+access as well). The password is available to anyone
+who can sniff network packets or read a protected
+(i.e., user read-only) file. If you want real
+security, get Kerberos.
+
+@node GSSAPI authenticated
+@subsection Direct connection with GSSAPI
+
+@cindex GSSAPI
+@cindex Security, GSSAPI
+@cindex :gserver:, setting up
+@cindex Kerberos, using :gserver:
+GSSAPI is a generic interface to network security
+systems such as Kerberos 5.
+If you have a working GSSAPI library, you can have
+@sc{cvs} connect via a direct @sc{tcp} connection,
+authenticating with GSSAPI.
+
+To do this, @sc{cvs} needs to be compiled with GSSAPI
+support; when configuring @sc{cvs} it tries to detect
+whether GSSAPI libraries using Kerberos version 5 are
+present. You can also use the @file{--with-gssapi}
+flag to configure.
+
+The connection is authenticated using GSSAPI, but the
+message stream is @emph{not} authenticated by default.
+You must use the @code{-a} global option to request
+stream authentication.
+
+The data transmitted is @emph{not} encrypted by
+default. Encryption support must be compiled into both
+the client and the server; use the
+@file{--enable-encrypt} configure option to turn it on.
+You must then use the @code{-x} global option to
+request encryption.
+
+GSSAPI connections are handled on the server side by
+the same server which handles the password
+authentication server; see @ref{Password authentication
+server}. If you are using a GSSAPI mechanism such as
+Kerberos which provides for strong authentication, you
+will probably want to disable the ability to
+authenticate via cleartext passwords. To do so, create
+an empty @file{CVSROOT/passwd} password file, and set
+@code{SystemAuth=no} in the config file
+(@pxref{config}).
+
+The GSSAPI server uses a principal name of
+cvs/@var{hostname}, where @var{hostname} is the
+canonical name of the server host. You will have to
+set this up as required by your GSSAPI mechanism.
+
+To connect using GSSAPI, use the @samp{:gserver:} method. For
+example,
+
+@example
+cvs -d :gserver:faun.example.org:/usr/local/cvsroot checkout foo
+@end example
+
+@node Kerberos authenticated
+@subsection Direct connection with Kerberos
+
+@cindex Kerberos, using :kserver:
+@cindex Security, Kerberos
+@cindex :kserver:, setting up
+The easiest way to use Kerberos is to use the Kerberos
+@code{rsh}, as described in @ref{Connecting via rsh}.
+The main disadvantage of using rsh is that all the data
+needs to pass through additional programs, so it may be
+slower. So if you have Kerberos installed you can
+connect via a direct @sc{tcp} connection,
+authenticating with Kerberos.
+
+This section concerns the Kerberos network security
+system, version 4. Kerberos version 5 is supported via
+the GSSAPI generic network security interface, as
+described in the previous section.
+
+To do this, @sc{cvs} needs to be compiled with Kerberos
+support; when configuring @sc{cvs} it tries to detect
+whether Kerberos is present or you can use the
+@file{--with-krb4} flag to configure.
+
+The data transmitted is @emph{not} encrypted by
+default. Encryption support must be compiled into both
+the client and server; use the
+@file{--enable-encryption} configure option to turn it
+on. You must then use the @code{-x} global option to
+request encryption.
+
+The CVS client will attempt to connect to port 1999 by default.
+
+@cindex kinit
+When you want to use @sc{cvs}, get a ticket in the
+usual way (generally @code{kinit}); it must be a ticket
+which allows you to log into the server machine. Then
+you are ready to go:
+
+@example
+cvs -d :kserver:faun.example.org:/usr/local/cvsroot checkout foo
+@end example
+
+Previous versions of @sc{cvs} would fall back to a
+connection via rsh; this version will not do so.
+
+@node Connecting via fork
+@subsection Connecting with fork
+
+@cindex fork, access method
+@cindex :fork:, setting up
+This access method allows you to connect to a
+repository on your local disk via the remote protocol.
+In other words it does pretty much the same thing as
+@code{:local:}, but various quirks, bugs and the like are
+those of the remote @sc{cvs} rather than the local
+@sc{cvs}.
+
+For day-to-day operations you might prefer either
+@code{:local:} or @code{:fork:}, depending on your
+preferences. Of course @code{:fork:} comes in
+particularly handy in testing or
+debugging @code{cvs} and the remote protocol.
+Specifically, we avoid all of the network-related
+setup/configuration, timeouts, and authentication
+inherent in the other remote access methods but still
+create a connection which uses the remote protocol.
+
+To connect using the @code{fork} method, use
+@samp{:fork:} and the pathname to your local
+repository. For example:
+
+@example
+cvs -d :fork:/usr/local/cvsroot checkout foo
+@end example
+
+@cindex CVS_SERVER, and :fork:
+As with @code{:ext:}, the server is called @samp{cvs}
+by default, or the value of the @code{CVS_SERVER}
+environment variable.
+
+
+@node Write proxies
+@subsection Distributing load across several CVS servers
+
+@cindex PrimaryServer, in CVSROOT/config
+@cindex Primary server
+@cindex Secondary server
+@cindex proxy, write
+@cindex write proxy
+@sc{cvs} can be configured to distribute usage across several @sc{cvs}
+servers. This is accomplished by means of one or more @dfn{write proxies}, or
+@dfn{secondary servers}, for a single @dfn{primary server}.
+
+When a @sc{cvs} client accesses a secondary server and only sends read
+requests, then the secondary server handles the entire request. If the client
+sends any write requests, however, the secondary server asks the client to
+redirect its write request to the primary server, if the client supports
+redirect requests, and otherwise becomes a transparent proxy for the primary
+server, which actually handles the write request.
+
+In this manner, any number of read-only secondary servers may be configured as
+write proxies for the primary server, effectively distributing the load from
+all read operations between the secondary servers and restricting the load on
+the primary server to write operations and pushing changes to the secondaries.
+
+Primary servers will not automatically push changes to secondaries. This must
+be configured via @file{loginfo}, @file{postadmin}, @file{posttag}, &
+@file{postwatch} scripts (@pxref{Trigger Scripts}) like the following:
+
+@example
+ALL rsync -gopr -essh ./ secondary:/cvsroot/%p &
+@end example
+
+You would probably actually want to lock directories for write on the secondary
+and for read on the primary before running the @samp{rsync} in the above
+example, but describing such a setup is beyond the scope of this document.
+
+A secondary advantage of a write proxy setup is that users pointing at the
+secondary server can still execute fast read operations while on a network that
+connects to the primary over a slow link or even one where the link to the
+primary is periodically broken. Only write operations will require the network
+link to the primary.
+
+To configure write proxies, the primary must be specified with the
+@samp{PrimaryServer} option in @file{CVSROOT/config} (@pxref{config}). For the
+transparent proxy mode to work, all secondary servers must also be running the
+same version of the @sc{cvs} server, or at least one that provides the same
+list of supported requests to the client as the primary server. This is not
+necessary for redirection.
+
+Once a primary server is configured, secondary servers may be configured by:
+
+@enumerate
+@item
+Duplicating the primary repository at the new location.
+@item
+Setting up the @file{loginfo}, @file{postadmin}, @file{posttag}, and
+@file{postwatch} files on the primary to propagate writes to the new secondary.
+@item
+Configure remote access to the secondary(ies) as you would configure access
+to any other CVS server (@pxref{Remote repositories}).
+@item
+Ensuring that @code{--allow-root=@var{secondary-cvsroot}} is passed to
+@strong{all} incovations of the secondary server if the path to the @sc{cvs}
+repository directory is different on the two servers and you wish to support
+clients that do not handle the @samp{Redirect} resopnse (CVS 1.12.9 and earlier
+clients do not handle the @samp{Redirect} response).
+
+Please note, again, that writethrough proxy suport requires
+@code{--allow-root=@var{secondary-cvsroot}} to be specified for @strong{all}
+incovations of the secondary server, not just @samp{pserver} invocations.
+This may require a wrapper script for the @sc{cvs} executable
+on your server machine.
+@end enumerate
+
+
+@c ---------------------------------------------------------------------
+@node Read-only access
+@section Read-only repository access
+@cindex Read-only repository access
+@cindex readers (admin file)
+@cindex writers (admin file)
+
+ It is possible to grant read-only repository
+access to people using the password-authenticated
+server (@pxref{Password authenticated}). (The
+other access methods do not have explicit support for
+read-only users because those methods all assume login
+access to the repository machine anyway, and therefore
+the user can do whatever local file permissions allow
+her to do.)
+
+ A user who has read-only access can do only
+those @sc{cvs} operations which do not modify the
+repository, except for certain ``administrative'' files
+(such as lock files and the history file). It may be
+desirable to use this feature in conjunction with
+user-aliasing (@pxref{Password authentication server}).
+
+Unlike with previous versions of @sc{cvs}, read-only
+users should be able merely to read the repository, and
+not to execute programs on the server or otherwise gain
+unexpected levels of access. Or to be more accurate,
+the @emph{known} holes have been plugged. Because this
+feature is new and has not received a comprehensive
+security audit, you should use whatever level of
+caution seems warranted given your attitude concerning
+security.
+
+ There are two ways to specify read-only access
+for a user: by inclusion, and by exclusion.
+
+ "Inclusion" means listing that user
+specifically in the @file{$CVSROOT/CVSROOT/readers}
+file, which is simply a newline-separated list of
+users. Here is a sample @file{readers} file:
+
+@example
+melissa
+splotnik
+jrandom
+@end example
+
+@noindent
+ (Don't forget the newline after the last user.)
+
+ "Exclusion" means explicitly listing everyone
+who has @emph{write} access---if the file
+
+@example
+$CVSROOT/CVSROOT/writers
+@end example
+
+@noindent
+exists, then only
+those users listed in it have write access, and
+everyone else has read-only access (of course, even the
+read-only users still need to be listed in the
+@sc{cvs} @file{passwd} file). The
+@file{writers} file has the same format as the
+@file{readers} file.
+
+ Note: if your @sc{cvs} @file{passwd}
+file maps cvs users onto system users (@pxref{Password
+authentication server}), make sure you deny or grant
+read-only access using the @emph{cvs} usernames, not
+the system usernames. That is, the @file{readers} and
+@file{writers} files contain cvs usernames, which may
+or may not be the same as system usernames.
+
+ Here is a complete description of the server's
+behavior in deciding whether to grant read-only or
+read-write access:
+
+ If @file{readers} exists, and this user is
+listed in it, then she gets read-only access. Or if
+@file{writers} exists, and this user is NOT listed in
+it, then she also gets read-only access (this is true
+even if @file{readers} exists but she is not listed
+there). Otherwise, she gets full read-write access.
+
+ Of course there is a conflict if the user is
+listed in both files. This is resolved in the more
+conservative way, it being better to protect the
+repository too much than too little: such a user gets
+read-only access.
+
+@node Server temporary directory
+@section Temporary directories for the server
+@cindex Temporary directories, and server
+@cindex Server, temporary directories
+
+While running, the @sc{cvs} server creates temporary
+directories. They are named
+
+@example
+cvs-serv@var{pid}
+@end example
+
+@noindent
+where @var{pid} is the process identification number of
+the server.
+They are located in the directory specified by
+the @samp{-T} global option (@pxref{Global options}),
+the @code{TMPDIR} environment variable (@pxref{Environment variables}),
+or, failing that, @file{/tmp}.
+
+In most cases the server will remove the temporary
+directory when it is done, whether it finishes normally
+or abnormally. However, there are a few cases in which
+the server does not or cannot remove the temporary
+directory, for example:
+
+@itemize @bullet
+@item
+If the server aborts due to an internal server error,
+it may preserve the directory to aid in debugging
+
+@item
+If the server is killed in a way that it has no way of
+cleaning up (most notably, @samp{kill -KILL} on unix).
+
+@item
+If the system shuts down without an orderly shutdown,
+which tells the server to clean up.
+@end itemize
+
+In cases such as this, you will need to manually remove
+the @file{cvs-serv@var{pid}} directories. As long as
+there is no server running with process identification
+number @var{pid}, it is safe to do so.
+
+@c ---------------------------------------------------------------------
+@node Starting a new project
+@chapter Starting a project with CVS
+@cindex Starting a project with CVS
+@cindex Creating a project
+
+@comment --moduledb--
+Because renaming files and moving them between
+directories is somewhat inconvenient, the first thing
+you do when you start a new project should be to think
+through your file organization. It is not impossible
+to rename or move files, but it does increase the
+potential for confusion and @sc{cvs} does have some
+quirks particularly in the area of renaming
+directories. @xref{Moving files}.
+
+What to do next depends on the situation at hand.
+
+@menu
+* Setting up the files:: Getting the files into the repository
+* Defining the module:: How to make a module of the files
+@end menu
+@c -- File permissions!
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Setting up the files
+@section Setting up the files
+
+The first step is to create the files inside the repository. This can
+be done in a couple of different ways.
+
+@c -- The contributed scripts
+@menu
+* From files:: This method is useful with old projects
+ where files already exists.
+* From other version control systems:: Old projects where you want to
+ preserve history from another system.
+* From scratch:: Creating a directory tree from scratch.
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node From files
+@subsection Creating a directory tree from a number of files
+@cindex Importing files
+
+When you begin using @sc{cvs}, you will probably already have several
+projects that can be
+put under @sc{cvs} control. In these cases the easiest way is to use the
+@code{import} command. An example is probably the easiest way to
+explain how to use it. If the files you want to install in
+@sc{cvs} reside in @file{@var{wdir}}, and you want them to appear in the
+repository as @file{$CVSROOT/yoyodyne/@var{rdir}}, you can do this:
+
+@example
+$ cd @var{wdir}
+$ cvs import -m "Imported sources" yoyodyne/@var{rdir} yoyo start
+@end example
+
+Unless you supply a log message with the @samp{-m}
+flag, @sc{cvs} starts an editor and prompts for a
+message. The string @samp{yoyo} is a @dfn{vendor tag},
+and @samp{start} is a @dfn{release tag}. They may fill
+no purpose in this context, but since @sc{cvs} requires
+them they must be present. @xref{Tracking sources}, for
+more information about them.
+
+You can now verify that it worked, and remove your
+original source directory.
+@c FIXME: Need to say more about "verify that it
+@c worked". What should the user look for in the output
+@c from "diff -r"?
+
+@example
+$ cd ..
+$ cvs checkout yoyodyne/@var{rdir} # @r{Explanation below}
+$ diff -r @var{wdir} yoyodyne/@var{rdir}
+$ rm -r @var{wdir}
+@end example
+
+@noindent
+Erasing the original sources is a good idea, to make sure that you do
+not accidentally edit them in @var{wdir}, bypassing @sc{cvs}.
+Of course, it would be wise to make sure that you have
+a backup of the sources before you remove them.
+
+The @code{checkout} command can either take a module
+name as argument (as it has done in all previous
+examples) or a path name relative to @code{$CVSROOT},
+as it did in the example above.
+
+It is a good idea to check that the permissions
+@sc{cvs} sets on the directories inside @code{$CVSROOT}
+are reasonable, and that they belong to the proper
+groups. @xref{File permissions}.
+
+If some of the files you want to import are binary, you
+may want to use the wrappers features to specify which
+files are binary and which are not. @xref{Wrappers}.
+
+@c The node name is too long, but I am having trouble
+@c thinking of something more concise.
+@node From other version control systems
+@subsection Creating Files From Other Version Control Systems
+@cindex Importing files, from other version control systems
+
+If you have a project which you are maintaining with
+another version control system, such as @sc{rcs}, you
+may wish to put the files from that project into
+@sc{cvs}, and preserve the revision history of the
+files.
+
+@table @asis
+@cindex RCS, importing files from
+@item From RCS
+If you have been using @sc{rcs}, find the @sc{rcs}
+files---usually a file named @file{foo.c} will have its
+@sc{rcs} file in @file{RCS/foo.c,v} (but it could be
+other places; consult the @sc{rcs} documentation for
+details). Then create the appropriate directories in
+@sc{cvs} if they do not already exist. Then copy the
+files into the appropriate directories in the @sc{cvs}
+repository (the name in the repository must be the name
+of the source file with @samp{,v} added; the files go
+directly in the appropriate directory of the repository,
+not in an @file{RCS} subdirectory). This is one of the
+few times when it is a good idea to access the @sc{cvs}
+repository directly, rather than using @sc{cvs}
+commands. Then you are ready to check out a new
+working directory.
+@c Someday there probably should be a "cvs import -t
+@c rcs" or some such. It could even create magic
+@c branches. It could also do something about the case
+@c where the RCS file had a (non-magic) "0" branch.
+
+The @sc{rcs} file should not be locked when you move it
+into @sc{cvs}; if it is, @sc{cvs} will have trouble
+letting you operate on it.
+@c What is the easiest way to unlock your files if you
+@c have them locked? Especially if you have a lot of them?
+@c This is a CVS bug/misfeature; importing RCS files
+@c should ignore whether they are locked and leave them in
+@c an unlocked state. Yet another reason for a separate
+@c "import RCS file" command.
+
+@c How many is "many"? Or do they just import RCS files?
+@item From another version control system
+Many version control systems have the ability to export
+@sc{rcs} files in the standard format. If yours does,
+export the @sc{rcs} files and then follow the above
+instructions.
+
+Failing that, probably your best bet is to write a
+script that will check out the files one revision at a
+time using the command line interface to the other
+system, and then check the revisions into @sc{cvs}.
+The @file{sccs2rcs} script mentioned below may be a
+useful example to follow.
+
+@cindex SCCS, importing files from
+@item From SCCS
+There is a script in the @file{contrib} directory of
+the @sc{cvs} source distribution called @file{sccs2rcs}
+which converts @sc{sccs} files to @sc{rcs} files.
+Note: you must run it on a machine which has both
+@sc{sccs} and @sc{rcs} installed, and like everything
+else in contrib it is unsupported (your mileage may
+vary).
+
+@cindex PVCS, importing files from
+@item From PVCS
+There is a script in the @file{contrib} directory of
+the @sc{cvs} source distribution called @file{pvcs_to_rcs}
+which converts @sc{pvcs} archives to @sc{rcs} files.
+You must run it on a machine which has both
+@sc{pvcs} and @sc{rcs} installed, and like everything
+else in contrib it is unsupported (your mileage may
+vary). See the comments in the script for details.
+@end table
+@c CMZ and/or PATCHY were systems that were used in the
+@c high energy physics community (especially for
+@c CERNLIB). CERN has replaced them with CVS, but the
+@c CAR format seems to live on as a way to submit
+@c changes. There is a program car2cvs which converts
+@c but I'm not sure where one gets a copy.
+@c Not sure it is worth mentioning here, since it would
+@c appear to affect only one particular community.
+@c Best page for more information is:
+@c http://wwwcn1.cern.ch/asd/cvs/index.html
+@c See also:
+@c http://ecponion.cern.ch/ecpsa/cernlib.html
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node From scratch
+@subsection Creating a directory tree from scratch
+
+@c Also/instead should be documenting
+@c $ cvs co -l .
+@c $ mkdir tc
+@c $ cvs add tc
+@c $ cd tc
+@c $ mkdir man
+@c $ cvs add man
+@c etc.
+@c Using import to create the directories only is
+@c probably a somewhat confusing concept.
+For a new project, the easiest thing to do is probably
+to create an empty directory structure, like this:
+
+@example
+$ mkdir tc
+$ mkdir tc/man
+$ mkdir tc/testing
+@end example
+
+After that, you use the @code{import} command to create
+the corresponding (empty) directory structure inside
+the repository:
+
+@example
+$ cd tc
+$ cvs import -m "Created directory structure" yoyodyne/@var{dir} yoyo start
+@end example
+
+This will add yoyodyne/@var{dir} as a directory under
+@code{$CVSROOT}.
+
+Use @code{checkout} to get the new project. Then, use @code{add}
+to add files (and new directories) as needed.
+
+@example
+$ cd ..
+$ cvs co yoyodyne/@var{dir}
+@end example
+
+Check that the permissions @sc{cvs} sets on the
+directories inside @code{$CVSROOT} are reasonable.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Defining the module
+@section Defining the module
+@cindex Defining a module
+@cindex Editing the modules file
+@cindex Module, defining
+@cindex Modules file, changing
+
+The next step is to define the module in the
+@file{modules} file. This is not strictly necessary,
+but modules can be convenient in grouping together
+related files and directories.
+
+In simple cases these steps are sufficient to define a module.
+
+@enumerate
+@item
+Get a working copy of the modules file.
+
+@example
+$ cvs checkout CVSROOT/modules
+$ cd CVSROOT
+@end example
+
+@item
+Edit the file and insert a line that defines the module. @xref{Intro
+administrative files}, for an introduction. @xref{modules}, for a full
+description of the modules file. You can use the
+following line to define the module @samp{tc}:
+
+@example
+tc yoyodyne/tc
+@end example
+
+@item
+Commit your changes to the modules file.
+
+@example
+$ cvs commit -m "Added the tc module." modules
+@end example
+
+@item
+Release the modules module.
+
+@example
+$ cd ..
+$ cvs release -d CVSROOT
+@end example
+@end enumerate
+
+@c ---------------------------------------------------------------------
+@node Revisions
+@chapter Revisions
+
+For many uses of @sc{cvs}, one doesn't need to worry
+too much about revision numbers; @sc{cvs} assigns
+numbers such as @code{1.1}, @code{1.2}, and so on, and
+that is all one needs to know. However, some people
+prefer to have more knowledge and control concerning
+how @sc{cvs} assigns revision numbers.
+
+If one wants to keep track of a set of revisions
+involving more than one file, such as which revisions
+went into a particular release, one uses a @dfn{tag},
+which is a symbolic revision which can be assigned to a
+numeric revision in each file.
+
+@menu
+* Revision numbers:: The meaning of a revision number
+* Versions revisions releases:: Terminology used in this manual
+* Assigning revisions:: Assigning revisions
+* Tags:: Tags--Symbolic revisions
+* Tagging the working directory:: The cvs tag command
+* Tagging by date/tag:: The cvs rtag command
+* Modifying tags:: Adding, renaming, and deleting tags
+* Tagging add/remove:: Tags with adding and removing files
+* Sticky tags:: Certain tags are persistent
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Revision numbers
+@section Revision numbers
+@cindex Revision numbers
+@cindex Revision tree
+@cindex Linear development
+@cindex Number, revision-
+@cindex Decimal revision number
+@cindex Branch number
+@cindex Number, branch
+
+Each version of a file has a unique @dfn{revision
+number}. Revision numbers look like @samp{1.1},
+@samp{1.2}, @samp{1.3.2.2} or even @samp{1.3.2.2.4.5}.
+A revision number always has an even number of
+period-separated decimal integers. By default revision
+1.1 is the first revision of a file. Each successive
+revision is given a new number by increasing the
+rightmost number by one. The following figure displays
+a few revisions, with newer revisions to the right.
+
+@example
+ +-----+ +-----+ +-----+ +-----+ +-----+
+ ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
+ +-----+ +-----+ +-----+ +-----+ +-----+
+@end example
+
+It is also possible to end up with numbers containing
+more than one period, for example @samp{1.3.2.2}. Such
+revisions represent revisions on branches
+(@pxref{Branching and merging}); such revision numbers
+are explained in detail in @ref{Branches and
+revisions}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Versions revisions releases
+@section Versions, revisions and releases
+@cindex Revisions, versions and releases
+@cindex Versions, revisions and releases
+@cindex Releases, revisions and versions
+
+A file can have several versions, as described above.
+Likewise, a software product can have several versions.
+A software product is often given a version number such
+as @samp{4.1.1}.
+
+Versions in the first sense are called @dfn{revisions}
+in this document, and versions in the second sense are
+called @dfn{releases}. To avoid confusion, the word
+@dfn{version} is almost never used in this document.
+
+@node Assigning revisions
+@section Assigning revisions
+
+@c We avoid the "major revision" terminology. It seems
+@c like jargon. Hopefully "first number" is clear enough.
+@c
+@c Well, in the context of software release numbers,
+@c "major" and "minor" release or version numbers are
+@c documented in at least the GNU Coding Standards, but I'm
+@c still not sure I find that a valid reason to apply the
+@c terminology to RCS revision numbers. "First", "Second",
+@c "subsequent", and so on is almost surely clearer,
+@c especially to a novice reader. -DRP
+By default, @sc{cvs} will assign numeric revisions by
+leaving the first number the same and incrementing the
+second number. For example, @code{1.1}, @code{1.2},
+@code{1.3}, etc.
+
+When adding a new file, the second number will always
+be one and the first number will equal the highest
+first number of any file in that directory. For
+example, the current directory contains files whose
+highest numbered revisions are @code{1.7}, @code{3.1},
+and @code{4.12}, then an added file will be given the
+numeric revision @code{4.1}.
+(When using client/server @sc{cvs},
+only files that are actually sent to the server are considered.)
+
+@c This is sort of redundant with something we said a
+@c while ago. Somewhere we need a better way of
+@c introducing how the first number can be anything
+@c except "1", perhaps. Also I don't think this
+@c presentation is clear on why we are discussing releases
+@c and first numbers of numeric revisions in the same
+@c breath.
+Normally there is no reason to care
+about the revision numbers---it is easier to treat them
+as internal numbers that @sc{cvs} maintains, and tags
+provide a better way to distinguish between things like
+release 1 versus release 2 of your product
+(@pxref{Tags}). However, if you want to set the
+numeric revisions, the @samp{-r} option to @code{cvs
+commit} can do that. The @samp{-r} option implies the
+@samp{-f} option, in the sense that it causes the
+files to be committed even if they are not modified.
+
+For example, to bring all your files up to
+revision 3.0 (including those that haven't changed),
+you might invoke:
+
+@example
+$ cvs commit -r 3.0
+@end example
+
+Note that the number you specify with @samp{-r} must be
+larger than any existing revision number. That is, if
+revision 3.0 exists, you cannot @samp{cvs commit
+-r 1.3}. If you want to maintain several releases in
+parallel, you need to use a branch (@pxref{Branching and merging}).
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Tags
+@section Tags--Symbolic revisions
+@cindex Tags
+
+The revision numbers live a life of their own. They
+need not have anything at all to do with the release
+numbers of your software product. Depending
+on how you use @sc{cvs} the revision numbers might change several times
+between two releases. As an example, some of the
+source files that make up @sc{rcs} 5.6 have the following
+revision numbers:
+@cindex RCS revision numbers
+
+@example
+ci.c 5.21
+co.c 5.9
+ident.c 5.3
+rcs.c 5.12
+rcsbase.h 5.11
+rcsdiff.c 5.10
+rcsedit.c 5.11
+rcsfcmp.c 5.9
+rcsgen.c 5.10
+rcslex.c 5.11
+rcsmap.c 5.2
+rcsutil.c 5.10
+@end example
+
+@cindex tag (subcommand), introduction
+@cindex Tags, symbolic name
+@cindex Symbolic name (tag)
+@cindex Name, symbolic (tag)
+@cindex HEAD, as reserved tag name
+@cindex BASE, as reserved tag name
+You can use the @code{tag} command to give a symbolic name to a
+certain revision of a file. You can use the @samp{-v} flag to the
+@code{status} command to see all tags that a file has, and
+which revision numbers they represent. Tag names must
+start with an uppercase or lowercase letter and can
+contain uppercase and lowercase letters, digits,
+@samp{-}, and @samp{_}. The two tag names @code{BASE}
+and @code{HEAD} are reserved for use by @sc{cvs}. It
+is expected that future names which are special to
+@sc{cvs} will be specially named, for example by
+starting with @samp{.}, rather than being named analogously to
+@code{BASE} and @code{HEAD}, to avoid conflicts with
+actual tag names.
+@c Including a character such as % or = has also been
+@c suggested as the naming convention for future
+@c special tag names. Starting with . is nice because
+@c that is not a legal tag name as far as RCS is concerned.
+@c FIXME: CVS actually accepts quite a few characters
+@c in tag names, not just the ones documented above
+@c (see RCS_check_tag). RCS
+@c defines legitimate tag names by listing illegal
+@c characters rather than legal ones. CVS is said to lose its
+@c mind if you try to use "/" (try making such a tag sticky
+@c and using "cvs status" client/server--see remote
+@c protocol format for entries line for probable cause).
+@c TODO: The testsuite
+@c should test for whatever are documented above as
+@c officially-OK tag names, and CVS should at least reject
+@c characters that won't work, like "/".
+
+You'll want to choose some convention for naming tags,
+based on information such as the name of the program
+and the version number of the release. For example,
+one might take the name of the program, immediately
+followed by the version number with @samp{.} changed to
+@samp{-}, so that @sc{cvs} 1.9 would be tagged with the name
+@code{cvs1-9}. If you choose a consistent convention,
+then you won't constantly be guessing whether a tag is
+@code{cvs-1-9} or @code{cvs1_9} or what. You might
+even want to consider enforcing your convention in the
+@file{taginfo} file (@pxref{taginfo}).
+@c Might be nice to say more about using taginfo this
+@c way, like giving an example, or pointing out any particular
+@c issues which arise.
+
+@cindex Adding a tag
+@cindex Tags, example
+The following example shows how you can add a tag to a
+file. The commands must be issued inside your working
+directory. That is, you should issue the
+command in the directory where @file{backend.c}
+resides.
+
+@example
+$ cvs tag rel-0-4 backend.c
+T backend.c
+$ cvs status -v backend.c
+===================================================================
+File: backend.c Status: Up-to-date
+
+ Version: 1.4 Tue Dec 1 14:39:01 1992
+ RCS Version: 1.4 /u/cvsroot/yoyodyne/tc/backend.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ rel-0-4 (revision: 1.4)
+
+@end example
+
+For a complete summary of the syntax of @code{cvs tag},
+including the various options, see @ref{Invoking CVS}.
+
+There is seldom reason to tag a file in isolation. A more common use is
+to tag all the files that constitute a module with the same tag at
+strategic points in the development life-cycle, such as when a release
+is made.
+
+@example
+$ cvs tag rel-1-0 .
+cvs tag: Tagging .
+T Makefile
+T backend.c
+T driver.c
+T frontend.c
+T parser.c
+@end example
+
+@noindent
+(When you give @sc{cvs} a directory as argument, it generally applies the
+operation to all the files in that directory, and (recursively), to any
+subdirectories that it may contain. @xref{Recursive behavior}.)
+
+@cindex Retrieving an old revision using tags
+@cindex Tags, retrieving old revisions
+The @code{checkout} command has a flag, @samp{-r}, that lets you check out
+a certain revision of a module. This flag makes it easy to
+retrieve the sources that make up release 1.0 of the module @samp{tc} at
+any time in the future:
+
+@example
+$ cvs checkout -r rel-1-0 tc
+@end example
+
+@noindent
+This is useful, for instance, if someone claims that there is a bug in
+that release, but you cannot find the bug in the current working copy.
+
+You can also check out a module as it was on any branch at any given date.
+@xref{checkout options}. When specifying @samp{-r} or @samp{-D} to
+any of these commands, you will need beware of sticky
+tags; see @ref{Sticky tags}.
+
+When you tag more than one file with the same tag you
+can think about the tag as "a curve drawn through a
+matrix of filename vs. revision number." Say we have 5
+files with the following revisions:
+
+@example
+@group
+ file1 file2 file3 file4 file5
+
+ 1.1 1.1 1.1 1.1 /--1.1* <-*- TAG
+ 1.2*- 1.2 1.2 -1.2*-
+ 1.3 \- 1.3*- 1.3 / 1.3
+ 1.4 \ 1.4 / 1.4
+ \-1.5*- 1.5
+ 1.6
+@end group
+@end example
+
+At some time in the past, the @code{*} versions were tagged.
+You can think of the tag as a handle attached to the curve
+drawn through the tagged revisions. When you pull on
+the handle, you get all the tagged revisions. Another
+way to look at it is that you "sight" through a set of
+revisions that is "flat" along the tagged revisions,
+like this:
+
+@example
+@group
+ file1 file2 file3 file4 file5
+
+ 1.1
+ 1.2
+ 1.1 1.3 _
+ 1.1 1.2 1.4 1.1 /
+ 1.2*----1.3*----1.5*----1.2*----1.1* (--- <--- Look here
+ 1.3 1.6 1.3 \_
+ 1.4 1.4
+ 1.5
+@end group
+@end example
+
+@node Tagging the working directory
+@section Specifying what to tag from the working directory
+
+@cindex tag (subcommand)
+The example in the previous section demonstrates one of
+the most common ways to choose which revisions to tag.
+Namely, running the @code{cvs tag} command without
+arguments causes @sc{cvs} to select the revisions which
+are checked out in the current working directory. For
+example, if the copy of @file{backend.c} in working
+directory was checked out from revision 1.4, then
+@sc{cvs} will tag revision 1.4. Note that the tag is
+applied immediately to revision 1.4 in the repository;
+tagging is not like modifying a file, or other
+operations in which one first modifies the working
+directory and then runs @code{cvs commit} to transfer
+that modification to the repository.
+
+One potentially surprising aspect of the fact that
+@code{cvs tag} operates on the repository is that you
+are tagging the checked-in revisions, which may differ
+from locally modified files in your working directory.
+If you want to avoid doing this by mistake, specify the
+@samp{-c} option to @code{cvs tag}. If there are any
+locally modified files, @sc{cvs} will abort with an
+error before it tags any files:
+
+@example
+$ cvs tag -c rel-0-4
+cvs tag: backend.c is locally modified
+cvs [tag aborted]: correct the above errors first!
+@end example
+
+@node Tagging by date/tag
+@section Specifying what to tag by date or revision
+@cindex rtag (subcommand)
+
+The @code{cvs rtag} command tags the repository as of a
+certain date or time (or can be used to tag the latest
+revision). @code{rtag} works directly on the
+repository contents (it requires no prior checkout and
+does not look for a working directory).
+
+The following options specify which date or revision to
+tag. See @ref{Common options}, for a complete
+description of them.
+
+@table @code
+@item -D @var{date}
+Tag the most recent revision no later than @var{date}.
+
+@item -f
+Only useful with the @samp{-D} or @samp{-r}
+flags. If no matching revision is found, use the most
+recent revision (instead of ignoring the file).
+
+@item -r @var{tag}[:@var{date}]
+Tag the revision already tagged with @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Common options}.
+@end table
+
+The @code{cvs tag} command also allows one to specify
+files by revision or date, using the same @samp{-r},
+@samp{-D}, and @samp{-f} options. However, this
+feature is probably not what you want. The reason is
+that @code{cvs tag} chooses which files to tag based on
+the files that exist in the working directory, rather
+than the files which existed as of the given tag/date.
+Therefore, you are generally better off using @code{cvs
+rtag}. The exceptions might be cases like:
+
+@example
+cvs tag -r 1.4 stable backend.c
+@end example
+
+@node Modifying tags
+@section Deleting, moving, and renaming tags
+
+@c Also see:
+@c "How do I move or rename a magic branch tag?"
+@c in the FAQ (I think the issues it talks about still
+@c apply, but this could use some sanity.sh work).
+
+Normally one does not modify tags. They exist in order
+to record the history of the repository and so deleting
+them or changing their meaning would, generally, not be
+what you want.
+
+However, there might be cases in which one uses a tag
+temporarily or accidentally puts one in the wrong
+place. Therefore, one might delete, move, or rename a
+tag.
+
+@noindent
+@strong{WARNING: the commands in this section are
+dangerous; they permanently discard historical
+information and it can be difficult or impossible to
+recover from errors. If you are a @sc{cvs}
+administrator, you may consider restricting these
+commands with the @file{taginfo} file (@pxref{taginfo}).}
+
+@cindex Deleting tags
+@cindex Deleting branch tags
+@cindex Removing tags
+@cindex Removing branch tags
+@cindex Tags, deleting
+@cindex Branch tags, deleting
+To delete a tag, specify the @samp{-d} option to either
+@code{cvs tag} or @code{cvs rtag}. For example:
+
+@example
+cvs rtag -d rel-0-4 tc
+@end example
+
+@noindent
+deletes the non-branch tag @code{rel-0-4} from the module @code{tc}.
+In the event that branch tags are encountered within the repository
+with the given name, a warning message will be issued and the branch
+tag will not be deleted. If you are absolutely certain you know what
+you are doing, the @code{-B} option may be specified to allow deletion
+of branch tags. In that case, any non-branch tags encountered will
+trigger warnings and will not be deleted.
+
+@noindent
+@strong{WARNING: Moving branch tags is very dangerous! If you think
+you need the @code{-B} option, think again and ask your @sc{cvs}
+administrator about it (if that isn't you). There is almost certainly
+another way to accomplish what you want to accomplish.}
+
+@cindex Moving tags
+@cindex Moving branch tags
+@cindex Tags, moving
+@cindex Branch tags, moving
+When we say @dfn{move} a tag, we mean to make the same
+name point to different revisions. For example, the
+@code{stable} tag may currently point to revision 1.4
+of @file{backend.c} and perhaps we want to make it
+point to revision 1.6. To move a non-branch tag, specify the
+@samp{-F} option to either @code{cvs tag} or @code{cvs
+rtag}. For example, the task just mentioned might be
+accomplished as:
+
+@example
+cvs tag -r 1.6 -F stable backend.c
+@end example
+
+@noindent
+If any branch tags are encountered in the repository
+with the given name, a warning is issued and the branch
+tag is not disturbed. If you are absolutely certain you
+wish to move the branch tag, the @code{-B} option may be specified.
+In that case, non-branch tags encountered with the given
+name are ignored with a warning message.
+
+@noindent
+@strong{WARNING: Moving branch tags is very dangerous! If you think you
+need the @code{-B} option, think again and ask your @sc{cvs}
+administrator about it (if that isn't you). There is almost certainly
+another way to accomplish what you want to accomplish.}
+
+@cindex Renaming tags
+@cindex Tags, renaming
+When we say @dfn{rename} a tag, we mean to make a
+different name point to the same revisions as the old
+tag. For example, one may have misspelled the tag name
+and want to correct it (hopefully before others are
+relying on the old spelling). To rename a tag, first
+create a new tag using the @samp{-r} option to
+@code{cvs rtag}, and then delete the old name. (Caution:
+this method will not work with branch tags.)
+This leaves the new tag on exactly the
+same files as the old tag. For example:
+
+@example
+cvs rtag -r old-name-0-4 rel-0-4 tc
+cvs rtag -d old-name-0-4 tc
+@end example
+
+@node Tagging add/remove
+@section Tagging and adding and removing files
+
+The subject of exactly how tagging interacts with
+adding and removing files is somewhat obscure; for the
+most part @sc{cvs} will keep track of whether files
+exist or not without too much fussing. By default,
+tags are applied to only files which have a revision
+corresponding to what is being tagged. Files which did
+not exist yet, or which were already removed, simply
+omit the tag, and @sc{cvs} knows to treat the absence
+of a tag as meaning that the file didn't exist as of
+that tag.
+
+However, this can lose a small amount of information.
+For example, suppose a file was added and then removed.
+Then, if the tag is missing for that file, there is no
+way to know whether the tag refers to the time before
+the file was added, or the time after it was removed.
+If you specify the @samp{-r} option to @code{cvs rtag},
+then @sc{cvs} tags the files which have been removed,
+and thereby avoids this problem. For example, one
+might specify @code{-r HEAD} to tag the head.
+
+On the subject of adding and removing files, the
+@code{cvs rtag} command has a @samp{-a} option which
+means to clear the tag from removed files that would
+not otherwise be tagged. For example, one might
+specify this option in conjunction with @samp{-F} when
+moving a tag. If one moved a tag without @samp{-a},
+then the tag in the removed files might still refer to
+the old revision, rather than reflecting the fact that
+the file had been removed. I don't think this is
+necessary if @samp{-r} is specified, as noted above.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Sticky tags
+@section Sticky tags
+@cindex Sticky tags
+@cindex Tags, sticky
+
+@c A somewhat related issue is per-directory sticky
+@c tags (see comment at CVS/Tag in node Working
+@c directory storage); we probably want to say
+@c something like "you can set a sticky tag for only
+@c some files, but you don't want to" or some such.
+
+Sometimes a working copy's revision has extra data
+associated with it, for example it might be on a branch
+(@pxref{Branching and merging}), or restricted to
+versions prior to a certain date by @samp{checkout -D}
+or @samp{update -D}. Because this data persists --
+that is, it applies to subsequent commands in the
+working copy -- we refer to it as @dfn{sticky}.
+
+Most of the time, stickiness is an obscure aspect of
+@sc{cvs} that you don't need to think about. However,
+even if you don't want to use the feature, you may need
+to know @emph{something} about sticky tags (for
+example, how to avoid them!).
+
+You can use the @code{status} command to see if any
+sticky tags or dates are set:
+
+@example
+$ cvs status driver.c
+===================================================================
+File: driver.c Status: Up-to-date
+
+ Version: 1.7.2.1 Sat Dec 5 19:35:03 1992
+ RCS Version: 1.7.2.1 /u/cvsroot/yoyodyne/tc/driver.c,v
+ Sticky Tag: rel-1-0-patches (branch: 1.7.2)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+@end example
+
+@cindex Resetting sticky tags
+@cindex Sticky tags, resetting
+@cindex Deleting sticky tags
+The sticky tags will remain on your working files until
+you delete them with @samp{cvs update -A}. The
+@samp{-A} option merges local changes into the version of the
+file from the head of the trunk, removing any sticky tags,
+dates, or options. See @ref{update} for more on the operation
+of @code{cvs update}.
+
+@cindex Sticky date
+The most common use of sticky tags is to identify which
+branch one is working on, as described in
+@ref{Accessing branches}. However, non-branch
+sticky tags have uses as well. For example,
+suppose that you want to avoid updating your working
+directory, to isolate yourself from possibly
+destabilizing changes other people are making. You
+can, of course, just refrain from running @code{cvs
+update}. But if you want to avoid updating only a
+portion of a larger tree, then sticky tags can help.
+If you check out a certain revision (such as 1.4) it
+will become sticky. Subsequent @code{cvs update}
+commands will
+not retrieve the latest revision until you reset the
+tag with @code{cvs update -A}. Likewise, use of the
+@samp{-D} option to @code{update} or @code{checkout}
+sets a @dfn{sticky date}, which, similarly, causes that
+date to be used for future retrievals.
+
+People often want to retrieve an old version of
+a file without setting a sticky tag. This can
+be done with the @samp{-p} option to @code{checkout} or
+@code{update}, which sends the contents of the file to
+standard output. For example:
+@example
+$ cvs update -p -r 1.1 file1 >file1
+===================================================================
+Checking out file1
+RCS: /tmp/cvs-sanity/cvsroot/first-dir/Attic/file1,v
+VERS: 1.1
+***************
+$
+@end example
+
+However, this isn't the easiest way, if you are asking
+how to undo a previous checkin (in this example, put
+@file{file1} back to the way it was as of revision
+1.1). In that case you are better off using the
+@samp{-j} option to @code{update}; for further
+discussion see @ref{Merging two revisions}.
+
+@c ---------------------------------------------------------------------
+@node Branching and merging
+@chapter Branching and merging
+@cindex Branching
+@cindex Merging
+@cindex Copying changes
+@cindex Main trunk and branches
+@cindex Revision tree, making branches
+@cindex Branches, copying changes between
+@cindex Changes, copying between branches
+@cindex Modifications, copying between branches
+
+@sc{cvs} allows you to isolate changes onto a separate
+line of development, known as a @dfn{branch}. When you
+change files on a branch, those changes do not appear
+on the main trunk or other branches.
+
+Later you can move changes from one branch to another
+branch (or the main trunk) by @dfn{merging}. Merging
+involves first running @code{cvs update -j}, to merge
+the changes into the working directory.
+You can then commit that revision, and thus effectively
+copy the changes onto another branch.
+
+@menu
+* Branches motivation:: What branches are good for
+* Creating a branch:: Creating a branch
+* Accessing branches:: Checking out and updating branches
+* Branches and revisions:: Branches are reflected in revision numbers
+* Magic branch numbers:: Magic branch numbers
+* Merging a branch:: Merging an entire branch
+* Merging more than once:: Merging from a branch several times
+* Merging two revisions:: Merging differences between two revisions
+* Merging adds and removals:: What if files are added or removed?
+* Merging and keywords:: Avoiding conflicts due to keyword substitution
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Branches motivation
+@section What branches are good for
+@cindex Branches motivation
+@cindex What branches are good for
+@cindex Motivation for branches
+
+@c FIXME: this node mentions one way to use branches,
+@c but it is by no means the only way. For example,
+@c the technique of committing a new feature on a branch,
+@c until it is ready for the main trunk. The whole
+@c thing is generally speaking more akin to the
+@c "Revision management" node although it isn't clear to
+@c me whether policy matters should be centralized or
+@c distributed throughout the relevant sections.
+Suppose that release 1.0 of tc has been made. You are continuing to
+develop tc, planning to create release 1.1 in a couple of months. After a
+while your customers start to complain about a fatal bug. You check
+out release 1.0 (@pxref{Tags}) and find the bug
+(which turns out to have a trivial fix). However, the current revision
+of the sources are in a state of flux and are not expected to be stable
+for at least another month. There is no way to make a
+bug fix release based on the newest sources.
+
+The thing to do in a situation like this is to create a @dfn{branch} on
+the revision trees for all the files that make up
+release 1.0 of tc. You can then make
+modifications to the branch without disturbing the main trunk. When the
+modifications are finished you can elect to either incorporate them on
+the main trunk, or leave them on the branch.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Creating a branch
+@section Creating a branch
+@cindex Creating a branch
+@cindex Branch, creating a
+@cindex tag (subcommand), creating a branch using
+@cindex rtag (subcommand), creating a branch using
+
+You can create a branch with @code{tag -b}; for
+example, assuming you're in a working copy:
+
+@example
+$ cvs tag -b rel-1-0-patches
+@end example
+
+@c FIXME: we should be more explicit about the value of
+@c having a tag on the branchpoint. For example
+@c "cvs tag rel-1-0-patches-branchpoint" before
+@c the "cvs tag -b". This points out that
+@c rel-1-0-patches is a pretty awkward name for
+@c this example (more so than for the rtag example
+@c below).
+
+This splits off a branch based on the current revisions
+in the working copy, assigning that branch the name
+@samp{rel-1-0-patches}.
+
+It is important to understand that branches get created
+in the repository, not in the working copy. Creating a
+branch based on current revisions, as the above example
+does, will @emph{not} automatically switch the working
+copy to be on the new branch. For information on how
+to do that, see @ref{Accessing branches}.
+
+You can also create a branch without reference to any
+working copy, by using @code{rtag}:
+
+@example
+$ cvs rtag -b -r rel-1-0 rel-1-0-patches tc
+@end example
+
+@samp{-r rel-1-0} says that this branch should be
+rooted at the revision that
+corresponds to the tag @samp{rel-1-0}. It need not
+be the most recent revision -- it's often useful to
+split a branch off an old revision (for example, when
+fixing a bug in a past release otherwise known to be
+stable).
+
+As with @samp{tag}, the @samp{-b} flag tells
+@code{rtag} to create a branch (rather than just a
+symbolic revision name). Note that the numeric
+revision number that matches @samp{rel-1-0} will
+probably be different from file to file.
+
+So, the full effect of the command is to create a new
+branch -- named @samp{rel-1-0-patches} -- in module
+@samp{tc}, rooted in the revision tree at the point tagged
+by @samp{rel-1-0}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Accessing branches
+@section Accessing branches
+@cindex Check out a branch
+@cindex Retrieve a branch
+@cindex Access a branch
+@cindex Identifying a branch
+@cindex Branch, check out
+@cindex Branch, retrieving
+@cindex Branch, accessing
+@cindex Branch, identifying
+
+You can retrieve a branch in one of two ways: by
+checking it out fresh from the repository, or by
+switching an existing working copy over to the branch.
+
+To check out a branch from the repository, invoke
+@samp{checkout} with the @samp{-r} flag, followed by
+the tag name of the branch (@pxref{Creating a branch}):
+
+@example
+$ cvs checkout -r rel-1-0-patches tc
+@end example
+
+Or, if you already have a working copy, you can switch
+it to a given branch with @samp{update -r}:
+
+@example
+$ cvs update -r rel-1-0-patches tc
+@end example
+
+@noindent
+or equivalently:
+
+@example
+$ cd tc
+$ cvs update -r rel-1-0-patches
+@end example
+
+It does not matter if the working copy was originally
+on the main trunk or on some other branch -- the above
+command will switch it to the named branch. And
+similarly to a regular @samp{update} command,
+@samp{update -r} merges any changes you have made,
+notifying you of conflicts where they occur.
+
+Once you have a working copy tied to a particular
+branch, it remains there until you tell it otherwise.
+This means that changes checked in from the working
+copy will add new revisions on that branch, while
+leaving the main trunk and other branches unaffected.
+
+@cindex Branches, sticky
+To find out what branch a working copy is on, you can
+use the @samp{status} command. In its output, look for
+the field named @samp{Sticky tag} (@pxref{Sticky tags})
+-- that's @sc{cvs}'s way of telling you the branch, if
+any, of the current working files:
+
+@example
+$ cvs status -v driver.c backend.c
+===================================================================
+File: driver.c Status: Up-to-date
+
+ Version: 1.7 Sat Dec 5 18:25:54 1992
+ RCS Version: 1.7 /u/cvsroot/yoyodyne/tc/driver.c,v
+ Sticky Tag: rel-1-0-patches (branch: 1.7.2)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ rel-1-0-patches (branch: 1.7.2)
+ rel-1-0 (revision: 1.7)
+
+===================================================================
+File: backend.c Status: Up-to-date
+
+ Version: 1.4 Tue Dec 1 14:39:01 1992
+ RCS Version: 1.4 /u/cvsroot/yoyodyne/tc/backend.c,v
+ Sticky Tag: rel-1-0-patches (branch: 1.4.2)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ rel-1-0-patches (branch: 1.4.2)
+ rel-1-0 (revision: 1.4)
+ rel-0-4 (revision: 1.4)
+
+@end example
+
+Don't be confused by the fact that the branch numbers
+for each file are different (@samp{1.7.2} and
+@samp{1.4.2} respectively). The branch tag is the
+same, @samp{rel-1-0-patches}, and the files are
+indeed on the same branch. The numbers simply reflect
+the point in each file's revision history at which the
+branch was made. In the above example, one can deduce
+that @samp{driver.c} had been through more changes than
+@samp{backend.c} before this branch was created.
+
+See @ref{Branches and revisions} for details about how
+branch numbers are constructed.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Branches and revisions
+@section Branches and revisions
+@cindex Branch number
+@cindex Number, branch
+@cindex Revision numbers (branches)
+
+Ordinarily, a file's revision history is a linear
+series of increments (@pxref{Revision numbers}):
+
+@example
+ +-----+ +-----+ +-----+ +-----+ +-----+
+ ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
+ +-----+ +-----+ +-----+ +-----+ +-----+
+@end example
+
+However, @sc{cvs} is not limited to linear development. The
+@dfn{revision tree} can be split into @dfn{branches},
+where each branch is a self-maintained line of
+development. Changes made on one branch can easily be
+moved back to the main trunk.
+
+Each branch has a @dfn{branch number}, consisting of an
+odd number of period-separated decimal integers. The
+branch number is created by appending an integer to the
+revision number where the corresponding branch forked
+off. Having branch numbers allows more than one branch
+to be forked off from a certain revision.
+
+@need 3500
+All revisions on a branch have revision numbers formed
+by appending an ordinal number to the branch number.
+The following figure illustrates branching with an
+example.
+
+@example
+@c This example used to have a 1.2.2.4 revision, which
+@c might help clarify that development can continue on
+@c 1.2.2. Might be worth reinstating if it can be done
+@c without overfull hboxes.
+@group
+ +-------------+
+ Branch 1.2.2.3.2 -> ! 1.2.2.3.2.1 !
+ / +-------------+
+ /
+ /
+ +---------+ +---------+ +---------+
+Branch 1.2.2 -> _! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
+ / +---------+ +---------+ +---------+
+ /
+ /
++-----+ +-----+ +-----+ +-----+ +-----+
+! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk
++-----+ +-----+ +-----+ +-----+ +-----+
+ !
+ !
+ ! +---------+ +---------+ +---------+
+Branch 1.2.4 -> +---! 1.2.4.1 !----! 1.2.4.2 !----! 1.2.4.3 !
+ +---------+ +---------+ +---------+
+
+@end group
+@end example
+
+@c -- However, at least for me the figure is not enough. I suggest more
+@c -- text to accompany it. "A picture is worth a thousand words", so you
+@c -- have to make sure the reader notices the couple of hundred words
+@c -- *you* had in mind more than the others!
+
+@c -- Why an even number of segments? This section implies that this is
+@c -- how the main trunk is distinguished from branch roots, but you never
+@c -- explicitly say that this is the purpose of the [by itself rather
+@c -- surprising] restriction to an even number of segments.
+
+The exact details of how the branch number is
+constructed is not something you normally need to be
+concerned about, but here is how it works: When
+@sc{cvs} creates a branch number it picks the first
+unused even integer, starting with 2. So when you want
+to create a branch from revision 6.4 it will be
+numbered 6.4.2. All branch numbers ending in a zero
+(such as 6.4.0) are used internally by @sc{cvs}
+(@pxref{Magic branch numbers}). The branch 1.1.1 has a
+special meaning. @xref{Tracking sources}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Magic branch numbers
+@section Magic branch numbers
+
+@c Want xref to here from "log"?
+
+This section describes a @sc{cvs} feature called
+@dfn{magic branches}. For most purposes, you need not
+worry about magic branches; @sc{cvs} handles them for
+you. However, they are visible to you in certain
+circumstances, so it may be useful to have some idea of
+how it works.
+
+Externally, branch numbers consist of an odd number of
+dot-separated decimal integers. @xref{Revision
+numbers}. That is not the whole truth, however. For
+efficiency reasons @sc{cvs} sometimes inserts an extra 0
+in the second rightmost position (1.2.4 becomes
+1.2.0.4, 8.9.10.11.12 becomes 8.9.10.11.0.12 and so
+on).
+
+@sc{cvs} does a pretty good job at hiding these so
+called magic branches, but in a few places the hiding
+is incomplete:
+
+@itemize @bullet
+@ignore
+@c This is in ignore as I'm taking their word for it,
+@c that this was fixed
+@c a long time ago. But before deleting this
+@c entirely, I'd rather verify it (and add a test
+@c case to the testsuite).
+@item
+The magic branch can appear in the output from
+@code{cvs status} in vanilla @sc{cvs} 1.3. This is
+fixed in @sc{cvs} 1.3-s2.
+
+@end ignore
+@item
+The magic branch number appears in the output from
+@code{cvs log}.
+@c What output should appear instead?
+
+@item
+You cannot specify a symbolic branch name to @code{cvs
+admin}.
+
+@end itemize
+
+@c Can CVS do this automatically the first time
+@c you check something in to that branch? Should
+@c it?
+You can use the @code{admin} command to reassign a
+symbolic name to a branch the way @sc{rcs} expects it
+to be. If @code{R4patches} is assigned to the branch
+1.4.2 (magic branch number 1.4.0.2) in file
+@file{numbers.c} you can do this:
+
+@example
+$ cvs admin -NR4patches:1.4.2 numbers.c
+@end example
+
+It only works if at least one revision is already
+committed on the branch. Be very careful so that you
+do not assign the tag to the wrong number. (There is
+no way to see how the tag was assigned yesterday).
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Merging a branch
+@section Merging an entire branch
+@cindex Merging a branch
+@cindex -j (merging branches)
+
+You can merge changes made on a branch into your working copy by giving
+the @samp{-j @var{branchname}} flag to the @code{update} subcommand. With one
+@samp{-j @var{branchname}} option it merges the changes made between the
+greatest common ancestor (GCA) of the branch and the destination revision (in
+the simple case below the GCA is the point where the branch forked) and the
+newest revision on that branch into your working copy.
+
+@cindex Join
+The @samp{-j} stands for ``join''.
+
+@cindex Branch merge example
+@cindex Example, branch merge
+@cindex Merge, branch example
+Consider this revision tree:
+
+@example
++-----+ +-----+ +-----+ +-----+
+! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 ! <- The main trunk
++-----+ +-----+ +-----+ +-----+
+ !
+ !
+ ! +---------+ +---------+
+Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
+ +---------+ +---------+
+@end example
+
+@noindent
+The branch 1.2.2 has been given the tag (symbolic name) @samp{R1fix}. The
+following example assumes that the module @samp{mod} contains only one
+file, @file{m.c}.
+
+@example
+$ cvs checkout mod # @r{Retrieve the latest revision, 1.4}
+
+$ cvs update -j R1fix m.c # @r{Merge all changes made on the branch,}
+ # @r{i.e. the changes between revision 1.2}
+ # @r{and 1.2.2.2, into your working copy}
+ # @r{of the file.}
+
+$ cvs commit -m "Included R1fix" # @r{Create revision 1.5.}
+@end example
+
+A conflict can result from a merge operation. If that
+happens, you should resolve it before committing the
+new revision. @xref{Conflicts example}.
+
+If your source files contain keywords (@pxref{Keyword substitution}),
+you might be getting more conflicts than strictly necessary. See
+@ref{Merging and keywords}, for information on how to avoid this.
+
+The @code{checkout} command also supports the @samp{-j @var{branchname}} flag. The
+same effect as above could be achieved with this:
+
+@example
+$ cvs checkout -j R1fix mod
+$ cvs commit -m "Included R1fix"
+@end example
+
+It should be noted that @code{update -j @var{tagname}} will also work but may
+not produce the desired result. @xref{Merging adds and removals}, for more.
+
+@node Merging more than once
+@section Merging from a branch several times
+
+Continuing our example, the revision tree now looks
+like this:
+
+@example
++-----+ +-----+ +-----+ +-----+ +-----+
+! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk
++-----+ +-----+ +-----+ +-----+ +-----+
+ ! *
+ ! *
+ ! +---------+ +---------+
+Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
+ +---------+ +---------+
+@end example
+
+@noindent
+where the starred line represents the merge from the
+@samp{R1fix} branch to the main trunk, as just
+discussed.
+
+Now suppose that development continues on the
+@samp{R1fix} branch:
+
+@example
++-----+ +-----+ +-----+ +-----+ +-----+
+! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk
++-----+ +-----+ +-----+ +-----+ +-----+
+ ! *
+ ! *
+ ! +---------+ +---------+ +---------+
+Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
+ +---------+ +---------+ +---------+
+@end example
+
+@noindent
+and then you want to merge those new changes onto the
+main trunk. If you just use the @code{cvs update -j
+R1fix m.c} command again, @sc{cvs} will attempt to
+merge again the changes which you have already merged,
+which can have undesirable side effects.
+
+So instead you need to specify that you only want to
+merge the changes on the branch which have not yet been
+merged into the trunk. To do that you specify two
+@samp{-j} options, and @sc{cvs} merges the changes from
+the first revision to the second revision. For
+example, in this case the simplest way would be
+
+@example
+cvs update -j 1.2.2.2 -j R1fix m.c # @r{Merge changes from 1.2.2.2 to the}
+ # @r{head of the R1fix branch}
+@end example
+
+The problem with this is that you need to specify the
+1.2.2.2 revision manually. A slightly better approach
+might be to use the date the last merge was done:
+
+@example
+cvs update -j R1fix:yesterday -j R1fix m.c
+@end example
+
+Better yet, tag the R1fix branch after every merge into
+the trunk, and then use that tag for subsequent merges:
+
+@example
+cvs update -j merged_from_R1fix_to_trunk -j R1fix m.c
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Merging two revisions
+@section Merging differences between any two revisions
+@cindex Merging two revisions
+@cindex Revisions, merging differences between
+@cindex Differences, merging
+
+With two @samp{-j @var{revision}} flags, the @code{update}
+(and @code{checkout}) command can merge the differences
+between any two revisions into your working file.
+
+@cindex Undoing a change
+@cindex Removing a change
+@example
+$ cvs update -j 1.5 -j 1.3 backend.c
+@end example
+
+@noindent
+will undo all changes made between revision
+1.3 and 1.5. Note the order of the revisions!
+
+If you try to use this option when operating on
+multiple files, remember that the numeric revisions will
+probably be very different between the various files.
+You almost always use symbolic
+tags rather than revision numbers when operating on
+multiple files.
+
+@cindex Restoring old version of removed file
+@cindex Resurrecting old version of dead file
+Specifying two @samp{-j} options can also undo file
+removals or additions. For example, suppose you have
+a file
+named @file{file1} which existed as revision 1.1, and
+you then removed it (thus adding a dead revision 1.2).
+Now suppose you want to add it again, with the same
+contents it had previously. Here is how to do it:
+
+@example
+$ cvs update -j 1.2 -j 1.1 file1
+U file1
+$ cvs commit -m test
+Checking in file1;
+/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1
+new revision: 1.3; previous revision: 1.2
+done
+$
+@end example
+
+@node Merging adds and removals
+@section Merging can add or remove files
+
+If the changes which you are merging involve removing
+or adding some files, @code{update -j} will reflect
+such additions or removals.
+
+@c FIXME: This example needs a lot more explanation.
+@c We also need other examples for some of the other
+@c cases (not all--there are too many--as long as we present a
+@c coherent general principle).
+For example:
+@example
+cvs update -A
+touch a b c
+cvs add a b c ; cvs ci -m "added" a b c
+cvs tag -b branchtag
+cvs update -r branchtag
+touch d ; cvs add d
+rm a ; cvs rm a
+cvs ci -m "added d, removed a"
+cvs update -A
+cvs update -jbranchtag
+@end example
+
+After these commands are executed and a @samp{cvs commit} is done,
+file @file{a} will be removed and file @file{d} added in the main branch.
+@c (which was determined by trying it)
+
+Note that using a single static tag (@samp{-j @var{tagname}})
+rather than a dynamic tag (@samp{-j @var{branchname}}) to merge
+changes from a branch will usually not remove files which were removed on the
+branch since @sc{cvs} does not automatically add static tags to dead revisions.
+The exception to this rule occurs when
+a static tag has been attached to a dead revision manually. Use the branch tag
+to merge all changes from the branch or use two static tags as merge endpoints
+to be sure that all intended changes are propagated in the merge.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Merging and keywords
+@section Merging and keywords
+@cindex Merging, and keyword substitution
+@cindex Keyword substitution, and merging
+@cindex -j (merging branches), and keyword substitution
+@cindex -kk, to avoid conflicts during a merge
+
+If you merge files containing keywords (@pxref{Keyword
+substitution}), you will normally get numerous
+conflicts during the merge, because the keywords are
+expanded differently in the revisions which you are
+merging.
+
+Therefore, you will often want to specify the
+@samp{-kk} (@pxref{Substitution modes}) switch to the
+merge command line. By substituting just the name of
+the keyword, not the expanded value of that keyword,
+this option ensures that the revisions which you are
+merging will be the same as each other, and avoid
+spurious conflicts.
+
+For example, suppose you have a file like this:
+
+@example
+ +---------+
+ _! 1.1.2.1 ! <- br1
+ / +---------+
+ /
+ /
++-----+ +-----+
+! 1.1 !----! 1.2 !
++-----+ +-----+
+@end example
+
+@noindent
+and your working directory is currently on the trunk
+(revision 1.2). Then you might get the following
+results from a merge:
+
+@example
+$ cat file1
+key $@splitrcskeyword{Revision}: 1.2 $
+. . .
+$ cvs update -j br1
+U file1
+RCS file: /cvsroot/first-dir/file1,v
+retrieving revision 1.1
+retrieving revision 1.1.2.1
+Merging differences between 1.1 and 1.1.2.1 into file1
+rcsmerge: warning: conflicts during merge
+$ cat file1
+@asis{}<<<<<<< file1
+key $@splitrcskeyword{Revision}: 1.2 $
+@asis{}=======
+key $@splitrcskeyword{Revision}: 1.1.2.1 $
+@asis{}>>>>>>> 1.1.2.1
+. . .
+@end example
+
+What happened was that the merge tried to merge the
+differences between 1.1 and 1.1.2.1 into your working
+directory. So, since the keyword changed from
+@code{Revision: 1.1} to @code{Revision: 1.1.2.1},
+@sc{cvs} tried to merge that change into your working
+directory, which conflicted with the fact that your
+working directory had contained @code{Revision: 1.2}.
+
+Here is what happens if you had used @samp{-kk}:
+
+@example
+$ cat file1
+key $@splitrcskeyword{Revision}: 1.2 $
+. . .
+$ cvs update -kk -j br1
+U file1
+RCS file: /cvsroot/first-dir/file1,v
+retrieving revision 1.1
+retrieving revision 1.1.2.1
+Merging differences between 1.1 and 1.1.2.1 into file1
+$ cat file1
+key $@splitrcskeyword{Revision}$
+. . .
+@end example
+
+What is going on here is that revision 1.1 and 1.1.2.1
+both expand as plain @code{Revision}, and therefore
+merging the changes between them into the working
+directory need not change anything. Therefore, there
+is no conflict.
+
+@strong{WARNING: In versions of @sc{cvs} prior to 1.12.2, there was a
+major problem with using @samp{-kk} on merges. Namely, @samp{-kk}
+overrode any default keyword expansion mode set in the archive file in
+the repository. This could, unfortunately for some users, cause data
+corruption in binary files (with a default keyword expansion mode set
+to @samp{-kb}). Therefore, when a repository contained binary files,
+conflicts had to be dealt with manually rather than using @samp{-kk} in
+a merge command.}
+
+In @sc{cvs} version 1.12.2 and later, the keyword expansion mode
+provided on the command line to any @sc{cvs} command no longer
+overrides the @samp{-kb} keyword expansion mode setting for binary
+files, though it will still override other default keyword expansion
+modes. You can now safely merge using @samp{-kk} to avoid spurious conflicts
+on lines containing RCS keywords, even when your repository contains
+binary files.
+
+@c ---------------------------------------------------------------------
+@node Recursive behavior
+@chapter Recursive behavior
+@cindex Recursive (directory descending)
+@cindex Directory, descending
+@cindex Descending directories
+@cindex Subdirectories
+
+Almost all of the subcommands of @sc{cvs} work
+recursively when you specify a directory as an
+argument. For instance, consider this directory
+structure:
+
+@example
+ @code{$HOME}
+ |
+ +--@t{tc}
+ | |
+ +--@t{CVS}
+ | (internal @sc{cvs} files)
+ +--@t{Makefile}
+ +--@t{backend.c}
+ +--@t{driver.c}
+ +--@t{frontend.c}
+ +--@t{parser.c}
+ +--@t{man}
+ | |
+ | +--@t{CVS}
+ | | (internal @sc{cvs} files)
+ | +--@t{tc.1}
+ |
+ +--@t{testing}
+ |
+ +--@t{CVS}
+ | (internal @sc{cvs} files)
+ +--@t{testpgm.t}
+ +--@t{test2.t}
+@end example
+
+@noindent
+If @file{tc} is the current working directory, the
+following is true:
+
+@itemize @bullet
+@item
+@samp{cvs update testing} is equivalent to
+
+@example
+cvs update testing/testpgm.t testing/test2.t
+@end example
+
+@item
+@samp{cvs update testing man} updates all files in the
+subdirectories
+
+@item
+@samp{cvs update .} or just @samp{cvs update} updates
+all files in the @code{tc} directory
+@end itemize
+
+If no arguments are given to @code{update} it will
+update all files in the current working directory and
+all its subdirectories. In other words, @file{.} is a
+default argument to @code{update}. This is also true
+for most of the @sc{cvs} subcommands, not only the
+@code{update} command.
+
+The recursive behavior of the @sc{cvs} subcommands can be
+turned off with the @samp{-l} option.
+Conversely, the @samp{-R} option can be used to force recursion if
+@samp{-l} is specified in @file{~/.cvsrc} (@pxref{~/.cvsrc}).
+
+@example
+$ cvs update -l # @r{Don't update files in subdirectories}
+@end example
+
+@c ---------------------------------------------------------------------
+@node Adding and removing
+@chapter Adding, removing, and renaming files and directories
+
+In the course of a project, one will often add new
+files. Likewise with removing or renaming, or with
+directories. The general concept to keep in mind in
+all these cases is that instead of making an
+irreversible change you want @sc{cvs} to record the
+fact that a change has taken place, just as with
+modifying an existing file. The exact mechanisms to do
+this in @sc{cvs} vary depending on the situation.
+
+@menu
+* Adding files:: Adding files
+* Removing files:: Removing files
+* Removing directories:: Removing directories
+* Moving files:: Moving and renaming files
+* Moving directories:: Moving and renaming directories
+@end menu
+
+@node Adding files
+@section Adding files to a directory
+@cindex Adding files
+
+To add a new file to a directory, follow these steps.
+
+@itemize @bullet
+@item
+You must have a working copy of the directory.
+@xref{Getting the source}.
+
+@item
+Create the new file inside your working copy of the directory.
+
+@item
+Use @samp{cvs add @var{filename}} to tell @sc{cvs} that you
+want to version control the file. If the file contains
+binary data, specify @samp{-kb} (@pxref{Binary files}).
+
+@item
+Use @samp{cvs commit @var{filename}} to actually check
+in the file into the repository. Other developers
+cannot see the file until you perform this step.
+@end itemize
+
+You can also use the @code{add} command to add a new
+directory.
+@c FIXCVS and/or FIXME: Adding a directory doesn't
+@c require the commit step. This probably can be
+@c considered a CVS bug, but it is possible we should
+@c warn people since this behavior probably won't be
+@c changing right away.
+
+Unlike most other commands, the @code{add} command is
+not recursive. You have to expcicitly name files and
+directories that you wish to add to the repository.
+However, each directory will need to be added
+separately before you will be able to add new files
+to those directories.
+
+@example
+$ mkdir -p foo/bar
+$ cp ~/myfile foo/bar/myfile
+$ cvs add foo foo/bar
+$ cvs add foo/bar/myfile
+@end example
+
+@cindex add (subcommand)
+@deffn Command {cvs add} [@code{-k} kflag] [@code{-m} message] files @dots{}
+
+Schedule @var{files} to be added to the repository.
+The files or directories specified with @code{add} must
+already exist in the current directory. To add a whole
+new directory hierarchy to the source repository (for
+example, files received from a third-party vendor), use
+the @code{import} command instead. @xref{import}.
+
+The added files are not placed in the source repository
+until you use @code{commit} to make the change
+permanent. Doing an @code{add} on a file that was
+removed with the @code{remove} command will undo the
+effect of the @code{remove}, unless a @code{commit}
+command intervened. @xref{Removing files}, for an
+example.
+
+The @samp{-k} option specifies the default way that
+this file will be checked out; for more information see
+@ref{Substitution modes}.
+
+@c As noted in BUGS, -m is broken client/server (Nov
+@c 96). Also see testsuite log2-* tests.
+The @samp{-m} option specifies a description for the
+file. This description appears in the history log (if
+it is enabled, @pxref{history file}). It will also be
+saved in the version history inside the repository when
+the file is committed. The @code{log} command displays
+this description. The description can be changed using
+@samp{admin -t}. @xref{admin}. If you omit the
+@samp{-m @var{description}} flag, an empty string will
+be used. You will not be prompted for a description.
+@end deffn
+
+For example, the following commands add the file
+@file{backend.c} to the repository:
+
+@c This example used to specify
+@c -m "Optimizer and code generation passes."
+@c to the cvs add command, but that doesn't work
+@c client/server (see log2 in sanity.sh). Should fix CVS,
+@c but also seems strange to document things which
+@c don't work...
+@example
+$ cvs add backend.c
+$ cvs commit -m "Early version. Not yet compilable." backend.c
+@end example
+
+When you add a file it is added only on the branch
+which you are working on (@pxref{Branching and merging}). You can
+later merge the additions to another branch if you want
+(@pxref{Merging adds and removals}).
+@c Should we mention that earlier versions of CVS
+@c lacked this feature (1.3) or implemented it in a buggy
+@c way (well, 1.8 had many bugs in cvs update -j)?
+@c Should we mention the bug/limitation regarding a
+@c file being a regular file on one branch and a directory
+@c on another?
+@c FIXME: This needs an example, or several, here or
+@c elsewhere, for it to make much sense.
+@c Somewhere we need to discuss the aspects of death
+@c support which don't involve branching, I guess.
+@c Like the ability to re-create a release from a tag.
+
+@c ---------------------------------------------------------------------
+@node Removing files
+@section Removing files
+@cindex Removing files
+@cindex Deleting files
+
+@c FIXME: this node wants to be split into several
+@c smaller nodes. Could make these children of
+@c "Adding and removing", probably (death support could
+@c be its own section, for example, as could the
+@c various bits about undoing mistakes in adding and
+@c removing).
+Directories change. New files are added, and old files
+disappear. Still, you want to be able to retrieve an
+exact copy of old releases.
+
+Here is what you can do to remove a file,
+but remain able to retrieve old revisions:
+
+@itemize @bullet
+@c FIXME: should probably be saying something about
+@c having a working directory in the first place.
+@item
+Make sure that you have not made any uncommitted
+modifications to the file. @xref{Viewing differences},
+for one way to do that. You can also use the
+@code{status} or @code{update} command. If you remove
+the file without committing your changes, you will of
+course not be able to retrieve the file as it was
+immediately before you deleted it.
+
+@item
+Remove the file from your working copy of the directory.
+You can for instance use @code{rm}.
+
+@item
+Use @samp{cvs remove @var{filename}} to tell @sc{cvs} that
+you really want to delete the file.
+
+@item
+Use @samp{cvs commit @var{filename}} to actually
+perform the removal of the file from the repository.
+@end itemize
+
+@c FIXME: Somehow this should be linked in with a more
+@c general discussion of death support. I don't know
+@c whether we want to use the term "death support" or
+@c not (we can perhaps get by without it), but we do
+@c need to discuss the "dead" state in "cvs log" and
+@c related subjects. The current discussion is
+@c scattered around, and not xref'd to each other.
+@c FIXME: I think this paragraph wants to be moved
+@c later down, at least after the first example.
+When you commit the removal of the file, @sc{cvs}
+records the fact that the file no longer exists. It is
+possible for a file to exist on only some branches and
+not on others, or to re-add another file with the same
+name later. @sc{cvs} will correctly create or not create
+the file, based on the @samp{-r} and @samp{-D} options
+specified to @code{checkout} or @code{update}.
+
+@c FIXME: This style seems to clash with how we
+@c document things in general.
+@cindex Remove (subcommand)
+@deffn Command {cvs remove} [options] files @dots{}
+
+Schedule file(s) to be removed from the repository
+(files which have not already been removed from the
+working directory are not processed). This command
+does not actually remove the file from the repository
+until you commit the removal. For a full list of
+options, see @ref{Invoking CVS}.
+@end deffn
+
+Here is an example of removing several files:
+
+@example
+$ cd test
+$ rm *.c
+$ cvs remove
+cvs remove: Removing .
+cvs remove: scheduling a.c for removal
+cvs remove: scheduling b.c for removal
+cvs remove: use 'cvs commit' to remove these files permanently
+$ cvs ci -m "Removed unneeded files"
+cvs commit: Examining .
+cvs commit: Committing .
+@end example
+
+As a convenience you can remove the file and @code{cvs
+remove} it in one step, by specifying the @samp{-f}
+option. For example, the above example could also be
+done like this:
+
+@example
+$ cd test
+$ cvs remove -f *.c
+cvs remove: scheduling a.c for removal
+cvs remove: scheduling b.c for removal
+cvs remove: use 'cvs commit' to remove these files permanently
+$ cvs ci -m "Removed unneeded files"
+cvs commit: Examining .
+cvs commit: Committing .
+@end example
+
+If you execute @code{remove} for a file, and then
+change your mind before you commit, you can undo the
+@code{remove} with an @code{add} command.
+@ignore
+@c is this worth saying or not? Somehow it seems
+@c confusing to me.
+Of course,
+since you have removed your copy of file in the working
+directory, @sc{cvs} does not necessarily bring back the
+contents of the file from right before you executed
+@code{remove}; instead it gets the file from the
+repository again.
+@end ignore
+
+@c FIXME: what if you change your mind after you commit
+@c it? (answer is also "cvs add" but we don't say that...).
+@c We need some index entries for thinks like "undoing
+@c removal" too.
+
+@example
+$ ls
+CVS ja.h oj.c
+$ rm oj.c
+$ cvs remove oj.c
+cvs remove: scheduling oj.c for removal
+cvs remove: use 'cvs commit' to remove this file permanently
+$ cvs add oj.c
+U oj.c
+cvs add: oj.c, version 1.1.1.1, resurrected
+@end example
+
+If you realize your mistake before you run the
+@code{remove} command you can use @code{update} to
+resurrect the file:
+
+@example
+$ rm oj.c
+$ cvs update oj.c
+cvs update: warning: oj.c was lost
+U oj.c
+@end example
+
+When you remove a file it is removed only on the branch
+which you are working on (@pxref{Branching and merging}). You can
+later merge the removals to another branch if you want
+(@pxref{Merging adds and removals}).
+
+@node Removing directories
+@section Removing directories
+@cindex Removing directories
+@cindex Directories, removing
+
+In concept, removing directories is somewhat similar to
+removing files---you want the directory to not exist in
+your current working directories, but you also want to
+be able to retrieve old releases in which the directory
+existed.
+
+The way that you remove a directory is to remove all
+the files in it. You don't remove the directory
+itself; there is no way to do that.
+Instead you specify the @samp{-P} option to
+@code{cvs update} or @code{cvs checkout},
+which will cause @sc{cvs} to remove empty
+directories from working directories.
+(Note that @code{cvs export} always removes empty directories.)
+Probably the
+best way to do this is to always specify @samp{-P}; if
+you want an empty directory then put a dummy file (for
+example @file{.keepme}) in it to prevent @samp{-P} from
+removing it.
+
+@c I'd try to give a rationale for this, but I'm not
+@c sure there is a particularly convincing one. What
+@c we would _like_ is for CVS to do a better job of version
+@c controlling whether directories exist, to eliminate the
+@c need for -P and so that a file can be a directory in
+@c one revision and a regular file in another.
+Note that @samp{-P} is implied by the @samp{-r} or @samp{-D}
+options of @code{checkout}. This way,
+@sc{cvs} will be able to correctly create the directory
+or not depending on whether the particular version you
+are checking out contains any files in that directory.
+
+@c ---------------------------------------------------------------------
+@node Moving files
+@section Moving and renaming files
+@cindex Moving files
+@cindex Renaming files
+@cindex Files, moving
+
+Moving files to a different directory or renaming them
+is not difficult, but some of the ways in which this
+works may be non-obvious. (Moving or renaming a
+directory is even harder. @xref{Moving directories}.).
+
+The examples below assume that the file @var{old} is renamed to
+@var{new}.
+
+@menu
+* Outside:: The normal way to Rename
+* Inside:: A tricky, alternative way
+* Rename by copying:: Another tricky, alternative way
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Outside
+@subsection The Normal way to Rename
+
+@c More rename issues. Not sure whether these are
+@c worth documenting; I'm putting them here because
+@c it seems to be as good a place as any to try to
+@c set down the issues.
+@c * "cvs annotate" will annotate either the new
+@c file or the old file; it cannot annotate _each
+@c line_ based on whether it was last changed in the
+@c new or old file. Unlike "cvs log", where the
+@c consequences of having to select either the new
+@c or old name seem fairly benign, this may be a
+@c real advantage to having CVS know about renames
+@c other than as a deletion and an addition.
+
+The normal way to move a file is to copy @var{old} to
+@var{new}, and then issue the normal @sc{cvs} commands
+to remove @var{old} from the repository, and add
+@var{new} to it.
+@c The following sentence is not true: one must cd into
+@c the directory to run "cvs add".
+@c (Both @var{old} and @var{new} could
+@c contain relative paths, for example @file{foo/bar.c}).
+
+@example
+$ mv @var{old} @var{new}
+$ cvs remove @var{old}
+$ cvs add @var{new}
+$ cvs commit -m "Renamed @var{old} to @var{new}" @var{old} @var{new}
+@end example
+
+This is the simplest way to move a file, it is not
+error-prone, and it preserves the history of what was
+done. Note that to access the history of the file you
+must specify the old or the new name, depending on what
+portion of the history you are accessing. For example,
+@code{cvs log @var{old}} will give the log up until the
+time of the rename.
+
+When @var{new} is committed its revision numbers will
+start again, usually at 1.1, so if that bothers you,
+use the @samp{-r @var{tag}} option to commit. For more
+information see @ref{Assigning revisions}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Inside
+@subsection Moving the history file
+
+This method is more dangerous, since it involves moving
+files inside the repository. Read this entire section
+before trying it out!
+
+@example
+$ cd $CVSROOT/@var{dir}
+$ mv @var{old},v @var{new},v
+@end example
+
+@noindent
+Advantages:
+
+@itemize @bullet
+@item
+The log of changes is maintained intact.
+
+@item
+The revision numbers are not affected.
+@end itemize
+
+@noindent
+Disadvantages:
+
+@itemize @bullet
+@item
+Old releases cannot easily be fetched from the
+repository. (The file will show up as @var{new} even
+in revisions from the time before it was renamed).
+
+@item
+There is no log information of when the file was renamed.
+
+@item
+Nasty things might happen if someone accesses the history file
+while you are moving it. Make sure no one else runs any of the @sc{cvs}
+commands while you move it.
+@end itemize
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Rename by copying
+@subsection Copying the history file
+
+This way also involves direct modifications to the
+repository. It is safe, but not without drawbacks.
+
+@example
+# @r{Copy the @sc{rcs} file inside the repository}
+$ cd $CVSROOT/@var{dir}
+$ cp @var{old},v @var{new},v
+# @r{Remove the old file}
+$ cd ~/@var{dir}
+$ rm @var{old}
+$ cvs remove @var{old}
+$ cvs commit @var{old}
+# @r{Remove all tags from @var{new}}
+$ cvs update @var{new}
+$ cvs log @var{new} # @r{Remember the non-branch tag names}
+$ cvs tag -d @var{tag1} @var{new}
+$ cvs tag -d @var{tag2} @var{new}
+@dots{}
+@end example
+
+By removing the tags you will be able to check out old
+revisions.
+
+@noindent
+Advantages:
+
+@itemize @bullet
+@item
+@c FIXME: Is this true about -D now that we have death
+@c support? See 5B.3 in the FAQ.
+Checking out old revisions works correctly, as long as
+you use @samp{-r @var{tag}} and not @samp{-D @var{date}}
+to retrieve the revisions.
+
+@item
+The log of changes is maintained intact.
+
+@item
+The revision numbers are not affected.
+@end itemize
+
+@noindent
+Disadvantages:
+
+@itemize @bullet
+@item
+You cannot easily see the history of the file across the rename.
+
+@ignore
+@c Is this true? I don't see how the revision numbers
+@c _could_ start over, when new,v is just old,v with
+@c the tags deleted.
+@c If there is some need to reinstate this text,
+@c it is "usually 1.1", not "1.0" and it needs an
+@c xref to Assigning revisions
+@item
+Unless you use the @samp{-r @var{tag}} (@pxref{commit
+options}) flag when @var{new} is committed its revision
+numbers will start at 1.0 again.
+@end ignore
+@end itemize
+
+@c ---------------------------------------------------------------------
+@node Moving directories
+@section Moving and renaming directories
+@cindex Moving directories
+@cindex Renaming directories
+@cindex Directories, moving
+
+The normal way to rename or move a directory is to
+rename or move each file within it as described in
+@ref{Outside}. Then check out with the @samp{-P}
+option, as described in @ref{Removing directories}.
+
+If you really want to hack the repository to rename or
+delete a directory in the repository, you can do it
+like this:
+
+@enumerate
+@item
+Inform everyone who has a checked out copy of the directory that the
+directory will be renamed. They should commit all their changes in all their
+copies of the project containing the directory to be removed, and remove
+all their working copies of said project, before you take the steps below.
+
+@item
+Rename the directory inside the repository.
+
+@example
+$ cd $CVSROOT/@var{parent-dir}
+$ mv @var{old-dir} @var{new-dir}
+@end example
+
+@item
+Fix the @sc{cvs} administrative files, if necessary (for
+instance if you renamed an entire module).
+
+@item
+Tell everyone that they can check out again and continue
+working.
+
+@end enumerate
+
+If someone had a working copy the @sc{cvs} commands will
+cease to work for him, until he removes the directory
+that disappeared inside the repository.
+
+It is almost always better to move the files in the
+directory instead of moving the directory. If you move the
+directory you are unlikely to be able to retrieve old
+releases correctly, since they probably depend on the
+name of the directories.
+
+@c ---------------------------------------------------------------------
+@node History browsing
+@chapter History browsing
+@cindex History browsing
+@cindex Traceability
+@cindex Isolation
+
+@ignore
+@c This is too long for an introduction (goal is
+@c one 20x80 character screen), and also mixes up a
+@c variety of issues (parallel development, history,
+@c maybe even touches on process control).
+
+@c -- @quote{To lose ones history is to lose ones soul.}
+@c -- ///
+@c -- ///Those who cannot remember the past are condemned to repeat it.
+@c -- /// -- George Santayana
+@c -- ///
+
+@sc{cvs} tries to make it easy for a group of people to work
+together. This is done in two ways:
+
+@itemize @bullet
+@item
+Isolation---You have your own working copy of the
+source. You are not affected by modifications made by
+others until you decide to incorporate those changes
+(via the @code{update} command---@pxref{update}).
+
+@item
+Traceability---When something has changed, you can
+always see @emph{exactly} what changed.
+@end itemize
+
+There are several features of @sc{cvs} that together lead
+to traceability:
+
+@itemize @bullet
+@item
+Each revision of a file has an accompanying log
+message.
+
+@item
+All commits are optionally logged to a central history
+database.
+
+@item
+Logging information can be sent to a user-defined
+program (@pxref{loginfo}).
+@end itemize
+
+@c -- More text here.
+
+This chapter should talk about the history file, the
+@code{log} command, the usefulness of ChangeLogs
+even when you run @sc{cvs}, and things like that.
+
+@end ignore
+
+@c kind of lame, in a lot of ways the above text inside
+@c the @ignore motivates this chapter better
+Once you have used @sc{cvs} to store a version control
+history---what files have changed when, how, and by
+whom, there are a variety of mechanisms for looking
+through the history.
+
+@c FIXME: should also be talking about how you look at
+@c old revisions (e.g. "cvs update -p -r 1.2 foo.c").
+@menu
+* log messages:: Log messages
+* history database:: The history database
+* user-defined logging:: User-defined logging
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node log messages
+@section Log messages
+
+@c FIXME: @xref to place where we talk about how to
+@c specify message to commit.
+Whenever you commit a file you specify a log message.
+
+@c FIXME: bring the information here, and get rid of or
+@c greatly shrink the "log" node.
+To look through the log messages which have been
+specified for every revision which has been committed,
+use the @code{cvs log} command (@pxref{log}).
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node history database
+@section The history database
+
+@c FIXME: bring the information from the history file
+@c and history nodes here. Rewrite it to be motivated
+@c better (start out by clearly explaining what gets
+@c logged in history, for example).
+You can use the history file (@pxref{history file}) to
+log various @sc{cvs} actions. To retrieve the
+information from the history file, use the @code{cvs
+history} command (@pxref{history}).
+
+Note: you can control what is logged to this file by using the
+@samp{LogHistory} keyword in the @file{CVSROOT/config} file
+(@pxref{config}).
+
+@c
+@c The history database has many problems:
+@c * It is very unclear what field means what. This
+@c could be improved greatly by better documentation,
+@c but there are still non-orthogonalities (for
+@c example, tag does not record the "repository"
+@c field but most records do).
+@c * Confusion about files, directories, and modules.
+@c Some commands record one, some record others.
+@c * File removal is not logged. There is an 'R'
+@c record type documented, but CVS never uses it.
+@c * Tags are only logged for the "cvs rtag" command,
+@c not "cvs tag". The fix for this is not completely
+@c clear (see above about modules vs. files).
+@c * Are there other cases of operations that are not
+@c logged? One would hope for all changes to the
+@c repository to be logged somehow (particularly
+@c operations like tagging, "cvs admin -k", and other
+@c operations which do not record a history that one
+@c can get with "cvs log"). Operations on the working
+@c directory, like export, get, and release, are a
+@c second category also covered by the current "cvs
+@c history".
+@c * The history file does not record the options given
+@c to a command. The most serious manifestation of
+@c this is perhaps that it doesn't record whether a command
+@c was recursive. It is not clear to me whether one
+@c wants to log at a level very close to the command
+@c line, as a sort of way of logging each command
+@c (more or less), or whether one wants
+@c to log more at the level of what was changed (or
+@c something in between), but either way the current
+@c information has pretty big gaps.
+@c * Further details about a tag--like whether it is a
+@c branch tag or, if a non-branch tag, which branch it
+@c is on. One can find out this information about the
+@c tag as it exists _now_, but if the tag has been
+@c moved, one doesn't know what it was like at the time
+@c the history record was written.
+@c * Whether operating on a particular tag, date, or
+@c options was implicit (sticky) or explicit.
+@c
+@c Another item, only somewhat related to the above, is a
+@c way to control what is logged in the history file.
+@c This is probably the only good way to handle
+@c different people having different ideas about
+@c information/space tradeoffs.
+@c
+@c It isn't really clear that it makes sense to try to
+@c patch up the history file format as it exists now to
+@c include all that stuff. It might be better to
+@c design a whole new CVSROOT/nhistory file and "cvs
+@c nhistory" command, or some such, or in some other
+@c way trying to come up with a clean break from the
+@c past, which can address the above concerns. Another
+@c open question is how/whether this relates to
+@c taginfo/loginfo/etc.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node user-defined logging
+@section User-defined logging
+
+@c FIXME: probably should centralize this information
+@c here, at least to some extent. Maybe by moving the
+@c loginfo, etc., nodes here and replacing
+@c the "user-defined logging" node with one node for
+@c each method.
+You can customize @sc{cvs} to log various kinds of
+actions, in whatever manner you choose. These
+mechanisms operate by executing a script at various
+times. The script might append a message to a file
+listing the information and the programmer who created
+it, or send mail to a group of developers, or, perhaps,
+post a message to a particular newsgroup. To log
+commits, use the @file{loginfo} file (@pxref{loginfo}), and
+to log tagging operations, use the @file{taginfo} file
+(@pxref{taginfo}).
+
+@c FIXME: What is difference between doing it in the
+@c modules file and using loginfo/taginfo? Why should
+@c user use one or the other?
+To log commits, checkouts, exports, and tags,
+respectively, you can also use the @samp{-i},
+@samp{-o}, @samp{-e}, and @samp{-t} options in the
+modules file. For a more flexible way of giving
+notifications to various users, which requires less in
+the way of keeping centralized scripts up to date, use
+the @code{cvs watch add} command (@pxref{Getting
+Notified}); this command is useful even if you are not
+using @code{cvs watch on}.
+
+@c ---------------------------------------------------------------------
+@node Binary files
+@chapter Handling binary files
+@cindex Binary files
+
+The most common use for @sc{cvs} is to store text
+files. With text files, @sc{cvs} can merge revisions,
+display the differences between revisions in a
+human-visible fashion, and other such operations.
+However, if you are willing to give up a few of these
+abilities, @sc{cvs} can store binary files. For
+example, one might store a web site in @sc{cvs}
+including both text files and binary images.
+
+@menu
+* Binary why:: More details on issues with binary files
+* Binary howto:: How to store them
+@end menu
+
+@node Binary why
+@section The issues with binary files
+
+While the need to manage binary files may seem obvious
+if the files that you customarily work with are binary,
+putting them into version control does present some
+additional issues.
+
+One basic function of version control is to show the
+differences between two revisions. For example, if
+someone else checked in a new version of a file, you
+may wish to look at what they changed and determine
+whether their changes are good. For text files,
+@sc{cvs} provides this functionality via the @code{cvs
+diff} command. For binary files, it may be possible to
+extract the two revisions and then compare them with a
+tool external to @sc{cvs} (for example, word processing
+software often has such a feature). If there is no
+such tool, one must track changes via other mechanisms,
+such as urging people to write good log messages, and
+hoping that the changes they actually made were the
+changes that they intended to make.
+
+Another ability of a version control system is the
+ability to merge two revisions. For @sc{cvs} this
+happens in two contexts. The first is when users make
+changes in separate working directories
+(@pxref{Multiple developers}). The second is when one
+merges explicitly with the @samp{update -j} command
+(@pxref{Branching and merging}).
+
+In the case of text
+files, @sc{cvs} can merge changes made independently,
+and signal a conflict if the changes conflict. With
+binary files, the best that @sc{cvs} can do is present
+the two different copies of the file, and leave it to
+the user to resolve the conflict. The user may choose
+one copy or the other, or may run an external merge
+tool which knows about that particular file format, if
+one exists.
+Note that having the user merge relies primarily on the
+user to not accidentally omit some changes, and thus is
+potentially error prone.
+
+If this process is thought to be undesirable, the best
+choice may be to avoid merging. To avoid the merges
+that result from separate working directories, see the
+discussion of reserved checkouts (file locking) in
+@ref{Multiple developers}. To avoid the merges
+resulting from branches, restrict use of branches.
+
+@node Binary howto
+@section How to store binary files
+
+There are two issues with using @sc{cvs} to store
+binary files. The first is that @sc{cvs} by default
+converts line endings between the canonical form in
+which they are stored in the repository (linefeed
+only), and the form appropriate to the operating system
+in use on the client (for example, carriage return
+followed by line feed for Windows NT).
+
+The second is that a binary file might happen to
+contain data which looks like a keyword (@pxref{Keyword
+substitution}), so keyword expansion must be turned
+off.
+
+@c FIXME: the third is that one can't do merges with
+@c binary files. xref to Multiple Developers and the
+@c reserved checkout issues.
+
+The @samp{-kb} option available with some @sc{cvs}
+commands insures that neither line ending conversion
+nor keyword expansion will be done.
+
+Here is an example of how you can create a new file
+using the @samp{-kb} flag:
+
+@example
+$ echo '$@splitrcskeyword{Id}$' > kotest
+$ cvs add -kb -m"A test file" kotest
+$ cvs ci -m"First checkin; contains a keyword" kotest
+@end example
+
+If a file accidentally gets added without @samp{-kb},
+one can use the @code{cvs admin} command to recover.
+For example:
+
+@example
+$ echo '$@splitrcskeyword{Id}$' > kotest
+$ cvs add -m"A test file" kotest
+$ cvs ci -m"First checkin; contains a keyword" kotest
+$ cvs admin -kb kotest
+$ cvs update -A kotest
+# @r{For non-unix systems:}
+# @r{Copy in a good copy of the file from outside CVS}
+$ cvs commit -m "make it binary" kotest
+@end example
+
+@c Trying to describe this for both unix and non-unix
+@c in the same description is very confusing. Might
+@c want to split the two, or just ditch the unix "shortcut"
+@c (unixheads don't do much with binary files, anyway).
+@c This used to say "(Try the above example, and do a
+@c @code{cat kotest} after every command)". But that
+@c only really makes sense for the unix case.
+When you check in the file @file{kotest} the file is
+not preserved as a binary file, because you did not
+check it in as a binary file. The @code{cvs
+admin -kb} command sets the default keyword
+substitution method for this file, but it does not
+alter the working copy of the file that you have. If you need to
+cope with line endings (that is, you are using
+@sc{cvs} on a non-unix system), then you need to
+check in a new copy of the file, as shown by the
+@code{cvs commit} command above.
+On unix, the @code{cvs update -A} command suffices.
+@c FIXME: should also describe what the *other users*
+@c need to do, if they have checked out copies which
+@c have been corrupted by lack of -kb. I think maybe
+@c "cvs update -kb" or "cvs
+@c update -A" would suffice, although the user who
+@c reported this suggested removing the file, manually
+@c removing it from CVS/Entries, and then "cvs update"
+(Note that you can use @code{cvs log} to determine the default keyword
+substitution method for a file and @code{cvs status} to determine
+the keyword substitution method for a working copy.)
+
+However, in using @code{cvs admin -k} to change the
+keyword expansion, be aware that the keyword expansion
+mode is not version controlled. This means that, for
+example, that if you have a text file in old releases,
+and a binary file with the same name in new releases,
+@sc{cvs} provides no way to check out the file in text
+or binary mode depending on what version you are
+checking out. There is no good workaround for this
+problem.
+
+You can also set a default for whether @code{cvs add}
+and @code{cvs import} treat a file as binary based on
+its name; for example you could say that files who
+names end in @samp{.exe} are binary. @xref{Wrappers}.
+There is currently no way to have @sc{cvs} detect
+whether a file is binary based on its contents. The
+main difficulty with designing such a feature is that
+it is not clear how to distinguish between binary and
+non-binary files, and the rules to apply would vary
+considerably with the operating system.
+@c For example, it would be good on MS-DOS-family OSes
+@c for anything containing ^Z to be binary. Having
+@c characters with the 8th bit set imply binary is almost
+@c surely a bad idea in the context of ISO-8859-* and
+@c other such character sets. On VMS or the Mac, we
+@c could use the OS's file typing. This is a
+@c commonly-desired feature, and something of this sort
+@c may make sense. But there are a lot of pitfalls here.
+@c
+@c Another, probably better, way to tell is to read the
+@c file in text mode, write it to a temp file in text
+@c mode, and then do a binary mode compare of the two
+@c files. If they differ, it is a binary file. This
+@c might have problems on VMS (or some other system
+@c with several different text modes), but in general
+@c should be relatively portable. The only other
+@c downside I can think of is that it would be fairly
+@c slow, but that is perhaps a small price to pay for
+@c not having your files corrupted. Another issue is
+@c what happens if you import a text file with bare
+@c linefeeds on Windows. Such files will show up on
+@c Windows sometimes (I think some native windows
+@c programs even write them, on occasion). Perhaps it
+@c is reasonable to treat such files as binary; after
+@c all it is something of a presumption to assume that
+@c the user would want the linefeeds converted to CRLF.
+
+@c ---------------------------------------------------------------------
+@node Multiple developers
+@chapter Multiple developers
+@cindex Multiple developers
+@cindex Team of developers
+@cindex File locking
+@cindex Locking files
+@cindex Working copy
+@cindex Reserved checkouts
+@cindex Unreserved checkouts
+@cindex RCS-style locking
+
+When more than one person works on a software project
+things often get complicated. Often, two people try to
+edit the same file simultaneously. One solution, known
+as @dfn{file locking} or @dfn{reserved checkouts}, is
+to allow only one person to edit each file at a time.
+This is the only solution with some version control
+systems, including @sc{rcs} and @sc{sccs}. Currently
+the usual way to get reserved checkouts with @sc{cvs}
+is the @code{cvs admin -l} command (@pxref{admin
+options}). This is not as nicely integrated into
+@sc{cvs} as the watch features, described below, but it
+seems that most people with a need for reserved
+checkouts find it adequate.
+@c Or "find it better than worrying about implementing
+@c nicely integrated reserved checkouts" or ...?
+
+As of @sc{cvs} version 1.12.10, another technique for getting most of the
+effect of reserved checkouts is to enable advisory locks. To enable advisory
+locks, have all developers put "edit -c", "commit -c" in their
+.cvsrc file, and turn on watches in the repository. This
+prevents them from doing a @code{cvs edit} if anyone is
+already editting the file. It also may
+be possible to use plain watches together with suitable
+procedures (not enforced by software), to avoid having
+two people edit at the same time.
+
+@c Our unreserved checkout model might not
+@c be quite the same as others. For example, I
+@c think that some systems will tend to create a branch
+@c in the case where CVS prints "up-to-date check failed".
+@c It isn't clear to me whether we should try to
+@c explore these subtleties; it could easily just
+@c confuse people.
+The default model with @sc{cvs} is known as
+@dfn{unreserved checkouts}. In this model, developers
+can edit their own @dfn{working copy} of a file
+simultaneously. The first person that commits his
+changes has no automatic way of knowing that another
+has started to edit it. Others will get an error
+message when they try to commit the file. They must
+then use @sc{cvs} commands to bring their working copy
+up to date with the repository revision. This process
+is almost automatic.
+
+@c FIXME? should probably use the word "watch" here, to
+@c tie this into the text below and above.
+@sc{cvs} also supports mechanisms which facilitate
+various kinds of communication, without actually
+enforcing rules like reserved checkouts do.
+
+The rest of this chapter describes how these various
+models work, and some of the issues involved in
+choosing between them.
+
+@ignore
+Here is a draft reserved checkout design or discussion
+of the issues. This seems like as good a place as any
+for this.
+
+Might want a cvs lock/cvs unlock--in which the names
+differ from edit/unedit because the network must be up
+for these to work. unedit gives an error if there is a
+reserved checkout in place (so that people don't
+accidentally leave locks around); unlock gives an error
+if one is not in place (this is more arguable; perhaps
+it should act like unedit in that case).
+
+On the other hand, might want it so that emacs,
+scripts, etc., can get ready to edit a file without
+having to know which model is in use. In that case we
+would have a "cvs watch lock" (or .cvsrc?) (that is,
+three settings, "on", "off", and "lock"). Having cvs
+watch lock set would cause a get to record in the CVS
+directory which model is in use, and cause "cvs edit"
+to change behaviors. We'd want a way to query which
+setting is in effect (this would be handy even if it is
+only "on" or "off" as presently). If lock is in
+effect, then commit would require a lock before
+allowing a checkin; chmod wouldn't suffice (might be
+debatable--see chmod comment below, in watches--but it
+is the way people expect RCS to work and I can't think
+of any significant downside. On the other hand, maybe
+it isn't worth bothering, because people who are used
+to RCS wouldn't think to use chmod anyway).
+
+Implementation: use file attributes or use RCS
+locking. The former avoids more dependence on RCS
+behaviors we will need to re-implement as we librarify
+RCS, and makes it easier to import/export RCS files (in
+that context, want to ignore the locker field). But
+note that RCS locks are per-branch, which is the
+correct behavior (this is also an issue for the "watch
+on" features; they should be per-branch too).
+
+Here are a few more random notes about implementation
+details, assuming "cvs watch lock" and
+
+CVS/Watched file? Or try to fit this into CVS/Entries somehow?
+Cases: (1) file is checked out (unreserved or with watch on) by old
+version of @sc{cvs}, now we do something with new one, (2) file is checked
+out by new version, now we do something with old one.
+
+Remote protocol would have a "Watched" analogous to "Mode". Of course
+it would apply to all Updated-like requests. How do we keep this
+setting up to date? I guess that there wants to be a Watched request,
+and the server would send a new one if it isn't up to date? (Ugh--hard
+to implement and slows down "cvs -q update"--is there an easier way?)
+
+"cvs edit"--checks CVS/Watched, and if watch lock, then sends
+"edit-lock" request. Which comes back with a Checked-in with
+appropriate Watched (off, on, lock, locked, or some such?), or error
+message if already locked.
+
+"cvs commit"--only will commit if off/on/locked. lock is not OK.
+
+Doc:
+note that "cvs edit" must be connected to network if watch lock is in
+effect.
+
+Talk about what to do if someone has locked a file and you want to
+edit that file. (breaking locks, or lack thereof).
+
+
+One other idea (which could work along with the
+existing "cvs admin -l" reserved checkouts, as well as
+the above):
+
+"cvs editors" could show who has the file locked, if
+someone does.
+
+@end ignore
+
+@menu
+* File status:: A file can be in several states
+* Updating a file:: Bringing a file up-to-date
+* Conflicts example:: An informative example
+* Informing others:: To cooperate you must inform
+* Concurrency:: Simultaneous repository access
+* Watches:: Mechanisms to track who is editing files
+* Choosing a model:: Reserved or unreserved checkouts?
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node File status
+@section File status
+@cindex File status
+@cindex Status of a file
+
+@c Shouldn't this start with an example or something,
+@c introducing the unreserved checkout model? Before we
+@c dive into listing states?
+Based on what operations you have performed on a
+checked out file, and what operations others have
+performed to that file in the repository, one can
+classify a file in a number of states. The states, as
+reported by the @code{status} command, are:
+
+@c The order of items is chosen to group logically
+@c similar outputs together.
+@c People who want alphabetical can use the index...
+@table @asis
+@cindex Up-to-date
+@item Up-to-date
+The file is identical with the latest revision in the
+repository for the branch in use.
+@c FIXME: should we clarify "in use"? The answer is
+@c sticky tags, and trying to distinguish branch sticky
+@c tags from non-branch sticky tags seems rather awkward
+@c here.
+@c FIXME: What happens with non-branch sticky tags? Is
+@c a stuck file "Up-to-date" or "Needs checkout" or what?
+
+@item Locally Modified
+@cindex Locally Modified
+You have edited the file, and not yet committed your changes.
+
+@item Locally Added
+@cindex Locally Added
+You have added the file with @code{add}, and not yet
+committed your changes.
+@c There are many cases involving the file being
+@c added/removed/modified in the working directory, and
+@c added/removed/modified in the repository, which we
+@c don't try to describe here. I'm not sure that "cvs
+@c status" produces a non-confusing output in most of
+@c those cases.
+
+@item Locally Removed
+@cindex Locally Removed
+You have removed the file with @code{remove}, and not yet
+committed your changes.
+
+@item Needs Checkout
+@cindex Needs Checkout
+Someone else has committed a newer revision to the
+repository. The name is slightly misleading; you will
+ordinarily use @code{update} rather than
+@code{checkout} to get that newer revision.
+
+@item Needs Patch
+@cindex Needs Patch
+@c See also newb-123j0 in sanity.sh (although that case
+@c should probably be changed rather than documented).
+Like Needs Checkout, but the @sc{cvs} server will send
+a patch rather than the entire file. Sending a patch or
+sending an entire file accomplishes the same thing.
+
+@item Needs Merge
+@cindex Needs Merge
+Someone else has committed a newer revision to the repository, and you
+have also made modifications to the file.
+
+@item Unresolved Conflict
+@cindex Unresolved Conflict
+@c FIXCVS - This file status needs to be changed to some more informative
+@c text that distinguishes it more clearly from each of the Locally Added,
+@c File had conflicts on merge, and Unknown status types, but an exact and
+@c succinct wording escapes me at the moment.
+A file with the same name as this new file has been added to the repository
+from a second workspace. This file will need to be moved out of the way
+to allow an @code{update} to complete.
+
+@item File had conflicts on merge
+@cindex File had conflicts on merge
+@c is it worth saying that this message was "Unresolved
+@c Conflict" in CVS 1.9 and earlier? I'm inclined to
+@c think that is unnecessarily confusing to new users.
+This is like Locally Modified, except that a previous
+@code{update} command gave a conflict. If you have not
+already done so, you need to
+resolve the conflict as described in @ref{Conflicts example}.
+
+@item Unknown
+@cindex Unknown
+@sc{cvs} doesn't know anything about this file. For
+example, you have created a new file and have not run
+@code{add}.
+@c
+@c "Entry Invalid" and "Classify Error" are also in the
+@c status.c. The latter definitely indicates a CVS bug
+@c (should it be worded more like "internal error" so
+@c people submit bug reports if they see it?). The former
+@c I'm not as sure; I haven't tracked down whether/when it
+@c appears in "cvs status" output.
+
+@end table
+
+To help clarify the file status, @code{status} also
+reports the @code{Working revision} which is the
+revision that the file in the working directory derives
+from, and the @code{Repository revision} which is the
+latest revision in the repository for the branch in
+use.
+The @samp{Commit Identifier} reflects the unique commitid
+of the @code{commit}.
+@c FIXME: should we clarify "in use"? The answer is
+@c sticky tags, and trying to distinguish branch sticky
+@c tags from non-branch sticky tags seems rather awkward
+@c here.
+@c FIXME: What happens with non-branch sticky tags?
+@c What is the Repository Revision there? See the
+@c comment at vn_rcs in cvs.h, which is kind of
+@c confused--we really need to document better what this
+@c field contains.
+@c Q: Should we document "New file!" and other such
+@c outputs or are they self-explanatory?
+@c FIXME: what about the date to the right of "Working
+@c revision"? It doesn't appear with client/server and
+@c seems unnecessary (redundant with "ls -l") so
+@c perhaps it should be removed for non-client/server too?
+@c FIXME: Need some examples.
+@c FIXME: Working revision can also be something like
+@c "-1.3" for a locally removed file. Not at all
+@c self-explanatory (and it is possible that CVS should
+@c be changed rather than documenting this).
+
+@c Would be nice to have an @example showing output
+@c from cvs status, with comments showing the xref
+@c where each part of the output is described. This
+@c might fit in nicely if it is desirable to split this
+@c node in two; one to introduce "cvs status" and one
+@c to list each of the states.
+The options to @code{status} are listed in
+@ref{Invoking CVS}. For information on its @code{Sticky tag}
+and @code{Sticky date} output, see @ref{Sticky tags}.
+For information on its @code{Sticky options} output,
+see the @samp{-k} option in @ref{update options}.
+
+You can think of the @code{status} and @code{update}
+commands as somewhat complementary. You use
+@code{update} to bring your files up to date, and you
+can use @code{status} to give you some idea of what an
+@code{update} would do (of course, the state of the
+repository might change before you actually run
+@code{update}). In fact, if you want a command to
+display file status in a more brief format than is
+displayed by the @code{status} command, you can invoke
+
+@cindex update, to display file status
+@example
+$ cvs -n -q update
+@end example
+
+The @samp{-n} option means to not actually do the
+update, but merely to display statuses; the @samp{-q}
+option avoids printing the name of each directory. For
+more information on the @code{update} command, and
+these options, see @ref{Invoking CVS}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Updating a file
+@section Bringing a file up to date
+@cindex Bringing a file up to date
+@cindex Updating a file
+@cindex Merging a file
+@cindex Update, introduction
+
+When you want to update or merge a file, use the @code{cvs update -d}
+command. For files that are not up to date this is roughly equivalent
+to a @code{checkout} command: the newest revision of the file is
+extracted from the repository and put in your working directory. The
+@code{-d} option, not necessary with @code{checkout}, tells @sc{cvs}
+that you wish it to create directories added by other developers.
+
+Your modifications to a file are never lost when you
+use @code{update}. If no newer revision exists,
+running @code{update} has no effect. If you have
+edited the file, and a newer revision is available,
+@sc{cvs} will merge all changes into your working copy.
+
+For instance, imagine that you checked out revision 1.4 and started
+editing it. In the meantime someone else committed revision 1.5, and
+shortly after that revision 1.6. If you run @code{update} on the file
+now, @sc{cvs} will incorporate all changes between revision 1.4 and 1.6 into
+your file.
+
+@cindex Overlap
+If any of the changes between 1.4 and 1.6 were made too
+close to any of the changes you have made, an
+@dfn{overlap} occurs. In such cases a warning is
+printed, and the resulting file includes both
+versions of the lines that overlap, delimited by
+special markers.
+@xref{update}, for a complete description of the
+@code{update} command.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Conflicts example
+@section Conflicts example
+@cindex Merge, an example
+@cindex Example of merge
+@cindex driver.c (merge example)
+
+Suppose revision 1.4 of @file{driver.c} contains this:
+
+@example
+#include <stdio.h>
+
+void main()
+@{
+ parse();
+ if (nerr == 0)
+ gencode();
+ else
+ fprintf(stderr, "No code generated.\n");
+ exit(nerr == 0 ? 0 : 1);
+@}
+@end example
+
+@noindent
+Revision 1.6 of @file{driver.c} contains this:
+
+@example
+#include <stdio.h>
+
+int main(int argc,
+ char **argv)
+@{
+ parse();
+ if (argc != 1)
+ @{
+ fprintf(stderr, "tc: No args expected.\n");
+ exit(1);
+ @}
+ if (nerr == 0)
+ gencode();
+ else
+ fprintf(stderr, "No code generated.\n");
+ exit(!!nerr);
+@}
+@end example
+
+@noindent
+Your working copy of @file{driver.c}, based on revision
+1.4, contains this before you run @samp{cvs update}:
+@c -- Really include "cvs"?
+
+@example
+#include <stdlib.h>
+#include <stdio.h>
+
+void main()
+@{
+ init_scanner();
+ parse();
+ if (nerr == 0)
+ gencode();
+ else
+ fprintf(stderr, "No code generated.\n");
+ exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+@}
+@end example
+
+@noindent
+You run @samp{cvs update}:
+@c -- Really include "cvs"?
+
+@example
+$ cvs update driver.c
+RCS file: /usr/local/cvsroot/yoyodyne/tc/driver.c,v
+retrieving revision 1.4
+retrieving revision 1.6
+Merging differences between 1.4 and 1.6 into driver.c
+rcsmerge warning: overlaps during merge
+cvs update: conflicts found in driver.c
+C driver.c
+@end example
+
+@noindent
+@cindex Conflicts (merge example)
+@sc{cvs} tells you that there were some conflicts.
+Your original working file is saved unmodified in
+@file{.#driver.c.1.4}. The new version of
+@file{driver.c} contains this:
+
+@example
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc,
+ char **argv)
+@{
+ init_scanner();
+ parse();
+ if (argc != 1)
+ @{
+ fprintf(stderr, "tc: No args expected.\n");
+ exit(1);
+ @}
+ if (nerr == 0)
+ gencode();
+ else
+ fprintf(stderr, "No code generated.\n");
+@asis{}<<<<<<< driver.c
+ exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+@asis{}=======
+ exit(!!nerr);
+@asis{}>>>>>>> 1.6
+@}
+@end example
+
+@noindent
+@cindex Markers, conflict
+@cindex Conflict markers
+@cindex <<<<<<<
+@cindex >>>>>>>
+@cindex =======
+
+Note how all non-overlapping modifications are incorporated in your working
+copy, and that the overlapping section is clearly marked with
+@samp{<<<<<<<}, @samp{=======} and @samp{>>>>>>>}.
+
+@cindex Resolving a conflict
+@cindex Conflict resolution
+You resolve the conflict by editing the file, removing the markers and
+the erroneous line. Suppose you end up with this file:
+@c -- Add xref to the pcl-cvs manual when it talks
+@c -- about this.
+@example
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc,
+ char **argv)
+@{
+ init_scanner();
+ parse();
+ if (argc != 1)
+ @{
+ fprintf(stderr, "tc: No args expected.\n");
+ exit(1);
+ @}
+ if (nerr == 0)
+ gencode();
+ else
+ fprintf(stderr, "No code generated.\n");
+ exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+@}
+@end example
+
+@noindent
+You can now go ahead and commit this as revision 1.7.
+
+@example
+$ cvs commit -m "Initialize scanner. Use symbolic exit values." driver.c
+Checking in driver.c;
+/usr/local/cvsroot/yoyodyne/tc/driver.c,v <-- driver.c
+new revision: 1.7; previous revision: 1.6
+done
+@end example
+
+For your protection, @sc{cvs} will refuse to check in a
+file if a conflict occurred and you have not resolved
+the conflict. Currently to resolve a conflict, you
+must change the timestamp on the file. In previous
+versions of @sc{cvs}, you also needed to
+insure that the file contains no conflict markers.
+Because
+your file may legitimately contain conflict markers (that
+is, occurrences of @samp{>>>>>>> } at the start of a
+line that don't mark a conflict), the current
+version of @sc{cvs} will print a warning and proceed to
+check in the file.
+@c The old behavior was really icky; the only way out
+@c was to start hacking on
+@c the @code{CVS/Entries} file or other such workarounds.
+@c
+@c If the timestamp thing isn't considered nice enough,
+@c maybe there should be a "cvs resolved" command
+@c which clears the conflict indication. For a nice user
+@c interface, this should be invoked by an interactive
+@c merge tool like emerge rather than by the user
+@c directly--such a tool can verify that the user has
+@c really dealt with each conflict.
+
+@cindex emerge
+If you use release 1.04 or later of pcl-cvs (a @sc{gnu}
+Emacs front-end for @sc{cvs}) you can use an Emacs
+package called emerge to help you resolve conflicts.
+See the documentation for pcl-cvs.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Informing others
+@section Informing others about commits
+@cindex Informing others
+@cindex Spreading information
+@cindex Mail, automatic mail on commit
+
+It is often useful to inform others when you commit a
+new revision of a file. The @samp{-i} option of the
+@file{modules} file, or the @file{loginfo} file, can be
+used to automate this process. @xref{modules}.
+@xref{loginfo}. You can use these features of @sc{cvs}
+to, for instance, instruct @sc{cvs} to mail a
+message to all developers, or post a message to a local
+newsgroup.
+@c -- More text would be nice here.
+
+@node Concurrency
+@section Several developers simultaneously attempting to run CVS
+
+@cindex Locks, cvs, introduction
+@c For a discussion of *why* CVS creates locks, see
+@c the comment at the start of src/lock.c
+If several developers try to run @sc{cvs} at the same
+time, one may get the following message:
+
+@example
+[11:43:23] waiting for bach's lock in /usr/local/cvsroot/foo
+@end example
+
+@cindex #cvs.rfl, removing
+@cindex #cvs.wfl, removing
+@cindex #cvs.lock, removing
+@sc{cvs} will try again every 30 seconds, and either
+continue with the operation or print the message again,
+if it still needs to wait. If a lock seems to stick
+around for an undue amount of time, find the person
+holding the lock and ask them about the cvs command
+they are running. If they aren't running a cvs
+command, look in the repository directory mentioned in
+the message and remove files which they own whose names
+start with @file{#cvs.rfl},
+@file{#cvs.wfl}, or @file{#cvs.lock}.
+
+Note that these locks are to protect @sc{cvs}'s
+internal data structures and have no relationship to
+the word @dfn{lock} in the sense used by
+@sc{rcs}---which refers to reserved checkouts
+(@pxref{Multiple developers}).
+
+Any number of people can be reading from a given
+repository at a time; only when someone is writing do
+the locks prevent other people from reading or writing.
+
+@cindex Atomic transactions, lack of
+@cindex Transactions, atomic, lack of
+@c the following talks about what one might call commit/update
+@c atomicity.
+@c Probably also should say something about
+@c commit/commit atomicity, that is, "An update will
+@c not get partial versions of more than one commit".
+@c CVS currently has this property and I guess we can
+@c make it a documented feature.
+@c For example one person commits
+@c a/one.c and b/four.c and another commits a/two.c and
+@c b/three.c. Then an update cannot get the new a/one.c
+@c and a/two.c and the old b/four.c and b/three.c.
+One might hope for the following property:
+
+@quotation
+If someone commits some changes in one cvs command,
+then an update by someone else will either get all the
+changes, or none of them.
+@end quotation
+
+@noindent
+but @sc{cvs} does @emph{not} have this property. For
+example, given the files
+
+@example
+a/one.c
+a/two.c
+b/three.c
+b/four.c
+@end example
+
+@noindent
+if someone runs
+
+@example
+cvs ci a/two.c b/three.c
+@end example
+
+@noindent
+and someone else runs @code{cvs update} at the same
+time, the person running @code{update} might get only
+the change to @file{b/three.c} and not the change to
+@file{a/two.c}.
+
+@node Watches
+@section Mechanisms to track who is editing files
+@cindex Watches
+
+For many groups, use of @sc{cvs} in its default mode is
+perfectly satisfactory. Users may sometimes go to
+check in a modification only to find that another
+modification has intervened, but they deal with it and
+proceed with their check in. Other groups prefer to be
+able to know who is editing what files, so that if two
+people try to edit the same file they can choose to
+talk about who is doing what when rather than be
+surprised at check in time. The features in this
+section allow such coordination, while retaining the
+ability of two developers to edit the same file at the
+same time.
+
+@c Some people might ask why CVS does not enforce the
+@c rule on chmod, by requiring a cvs edit before a cvs
+@c commit. The main reason is that it could always be
+@c circumvented--one could edit the file, and
+@c then when ready to check it in, do the cvs edit and put
+@c in the new contents and do the cvs commit. One
+@c implementation note: if we _do_ want to have cvs commit
+@c require a cvs edit, we should store the state on
+@c whether the cvs edit has occurred in the working
+@c directory, rather than having the server try to keep
+@c track of what working directories exist.
+@c FIXME: should the above discussion be part of the
+@c manual proper, somewhere, not just in a comment?
+For maximum benefit developers should use @code{cvs
+edit} (not @code{chmod}) to make files read-write to
+edit them, and @code{cvs release} (not @code{rm}) to
+discard a working directory which is no longer in use,
+but @sc{cvs} is not able to enforce this behavior.
+
+If a development team wants stronger enforcement of
+watches and all team members are using a @sc{cvs} client version 1.12.10 or
+greater to access a @sc{cvs} server version 1.12.10 or greater, they can
+enable advisory locks. To enable advisory locks, have all developers
+put "edit -c" and "commit -c" into all .cvsrc files,
+and make files default to read only by turning on watches
+or putting "cvs -r" into all .cvsrc files.
+This prevents multiple people from editting a file at
+the same time (unless explicitly overriden with @samp{-f}).
+
+@c I'm a little dissatisfied with this presentation,
+@c because "watch on"/"edit"/"editors" are one set of
+@c functionality, and "watch add"/"watchers" is another
+@c which is somewhat orthogonal even though they interact in
+@c various ways. But I think it might be
+@c confusing to describe them separately (e.g. "watch
+@c add" with loginfo). I don't know.
+
+@menu
+* Setting a watch:: Telling CVS to watch certain files
+* Getting Notified:: Telling CVS to notify you
+* Editing files:: How to edit a file which is being watched
+* Watch information:: Information about who is watching and editing
+* Watches Compatibility:: Watches interact poorly with CVS 1.6 or earlier
+@end menu
+
+@node Setting a watch
+@subsection Telling CVS to watch certain files
+
+To enable the watch features, you first specify that
+certain files are to be watched.
+
+@cindex watch on (subcommand)
+@deffn Command {cvs watch on} [@code{-lR}] [@var{files}]@dots{}
+
+@cindex Read-only files, and watches
+Specify that developers should run @code{cvs edit}
+before editing @var{files}. @sc{cvs} will create working
+copies of @var{files} read-only, to remind developers
+to run the @code{cvs edit} command before working on
+them.
+
+If @var{files} includes the name of a directory, @sc{cvs}
+arranges to watch all files added to the corresponding
+repository directory, and sets a default for files
+added in the future; this allows the user to set
+notification policies on a per-directory basis. The
+contents of the directory are processed recursively,
+unless the @code{-l} option is given.
+The @code{-R} option can be used to force recursion if the @code{-l}
+option is set in @file{~/.cvsrc} (@pxref{~/.cvsrc}).
+
+If @var{files} is omitted, it defaults to the current directory.
+
+@cindex watch off (subcommand)
+@end deffn
+
+@deffn Command {cvs watch off} [@code{-lR}] [@var{files}]@dots{}
+
+Do not create @var{files} read-only on checkout; thus,
+developers will not be reminded to use @code{cvs edit}
+and @code{cvs unedit}.
+@ignore
+@sc{cvs} will check out @var{files}
+read-write as usual, unless other permissions override
+due to the @code{PreservePermissions} option being
+enabled in the @file{config} administrative file
+(@pxref{Special Files}, @pxref{config})
+@end ignore
+
+The @var{files} and options are processed as for @code{cvs
+watch on}.
+
+@end deffn
+
+@node Getting Notified
+@subsection Telling CVS to notify you
+
+You can tell @sc{cvs} that you want to receive
+notifications about various actions taken on a file.
+You can do this without using @code{cvs watch on} for
+the file, but generally you will want to use @code{cvs
+watch on}, to remind developers to use the @code{cvs edit}
+command.
+
+@cindex watch add (subcommand)
+@deffn Command {cvs watch add} [@code{-lR}] [@code{-a} @var{action}]@dots{} [@var{files}]@dots{}
+
+Add the current user to the list of people to receive notification of
+work done on @var{files}.
+
+The @code{-a} option specifies what kinds of events @sc{cvs} should notify
+the user about. @var{action} is one of the following:
+
+@table @code
+
+@item edit
+Another user has applied the @code{cvs edit} command (described
+below) to a watched file.
+
+@item commit
+Another user has committed changes to one of the named @var{files}.
+
+@item unedit
+Another user has abandoned editing a file (other than by committing changes).
+They can do this in several ways, by:
+
+@itemize @bullet
+
+@item
+applying the @code{cvs unedit} command (described below) to the file
+
+@item
+applying the @code{cvs release} command (@pxref{release}) to the file's parent directory
+(or recursively to a directory more than one level up)
+
+@item
+deleting the file and allowing @code{cvs update} to recreate it
+
+@end itemize
+
+@item all
+All of the above.
+
+@item none
+None of the above. (This is useful with @code{cvs edit},
+described below.)
+
+@end table
+
+The @code{-a} option may appear more than once, or not at all. If
+omitted, the action defaults to @code{all}.
+
+The @var{files} and options are processed as for
+@code{cvs watch on}.
+
+@end deffn
+
+
+@cindex watch remove (subcommand)
+@deffn Command {cvs watch remove} [@code{-lR}] [@code{-a} @var{action}]@dots{} [@var{files}]@dots{}
+
+Remove a notification request established using @code{cvs watch add};
+the arguments are the same. If the @code{-a} option is present, only
+watches for the specified actions are removed.
+
+@end deffn
+
+@cindex notify (admin file)
+When the conditions exist for notification, @sc{cvs}
+calls the @file{notify} administrative file. Edit
+@file{notify} as one edits the other administrative
+files (@pxref{Intro administrative files}). This
+file follows the usual conventions for administrative
+files (@pxref{syntax}), where each line is a regular
+expression followed by a command to execute. The
+command should contain a single occurrence of @samp{%s}
+which will be replaced by the user to notify; the rest
+of the information regarding the notification will be
+supplied to the command on standard input. The
+standard thing to put in the @code{notify} file is the
+single line:
+
+@example
+ALL mail %s -s "CVS notification"
+@end example
+
+@noindent
+This causes users to be notified by electronic mail.
+@c FIXME: should it be this hard to set up this
+@c behavior (and the result when one fails to do so,
+@c silent failure to notify, so non-obvious)? Should
+@c CVS give a warning if no line in notify matches (and
+@c document the use of "DEFAULT :" for the case where
+@c skipping the notification is indeed desired)?
+
+@cindex users (admin file)
+Note that if you set this up in the straightforward
+way, users receive notifications on the server machine.
+One could of course write a @file{notify} script which
+directed notifications elsewhere, but to make this
+easy, @sc{cvs} allows you to associate a notification
+address for each user. To do so create a file
+@file{users} in @file{CVSROOT} with a line for each
+user in the format @var{user}:@var{value}. Then
+instead of passing the name of the user to be notified
+to @file{notify}, @sc{cvs} will pass the @var{value}
+(normally an email address on some other machine).
+
+@sc{cvs} does not notify you for your own changes.
+Currently this check is done based on whether the user
+name of the person taking the action which triggers
+notification matches the user name of the person
+getting notification. In fact, in general, the watches
+features only track one edit by each user. It probably
+would be more useful if watches tracked each working
+directory separately, so this behavior might be worth
+changing.
+@c "behavior might be worth changing" is an effort to
+@c point to future directions while also not promising
+@c that "they" (as in "why don't they fix CVS to....")
+@c will do this.
+@c one implementation issue is identifying whether a
+@c working directory is same or different. Comparing
+@c pathnames/hostnames is hopeless, but having the server
+@c supply a serial number which the client stores in the
+@c CVS directory as a magic cookie should work.
+
+@node Editing files
+@subsection How to edit a file which is being watched
+
+@cindex Checkout, as term for getting ready to edit
+Since a file which is being watched is checked out
+read-only, you cannot simply edit it. To make it
+read-write, and inform others that you are planning to
+edit it, use the @code{cvs edit} command. Some systems
+call this a @dfn{checkout}, but @sc{cvs} uses that term
+for obtaining a copy of the sources (@pxref{Getting the
+source}), an operation which those systems call a
+@dfn{get} or a @dfn{fetch}.
+@c Issue to think about: should we transition CVS
+@c towards the "get" terminology? "cvs get" is already a
+@c synonym for "cvs checkout" and that section of the
+@c manual refers to "Getting the source". If this is
+@c done, needs to be done gingerly (for example, we should
+@c still accept "checkout" in .cvsrc files indefinitely
+@c even if the CVS's messages are changed from "cvs checkout: "
+@c to "cvs get: ").
+@c There is a concern about whether "get" is not as
+@c good for novices because it is a more general term
+@c than "checkout" (and thus arguably harder to assign
+@c a technical meaning for).
+
+@cindex edit (subcommand)
+@deffn Command {cvs edit} [@code{-lR}] [@code{-a} @var{action}]@dots{} [@var{files}]@dots{}
+
+Prepare to edit the working files @var{files}. @sc{cvs} makes the
+@var{files} read-write, and notifies users who have requested
+@code{edit} notification for any of @var{files}.
+
+The @code{cvs edit} command accepts the same options as the
+@code{cvs watch add} command, and establishes a temporary watch for the
+user on @var{files}; @sc{cvs} will remove the watch when @var{files} are
+@code{unedit}ed or @code{commit}ted. If the user does not wish to
+receive notifications, she should specify @code{-a none}.
+
+The @var{files} and the options are processed as for the @code{cvs
+watch} commands.
+
+There are two additional options that @code{cvs edit} understands as of
+@sc{cvs} client and server versions 1.12.10 but @code{cvs watch} does not.
+The first is @code{-c}, which causes @code{cvs edit} to fail if anyone else
+is editting the file. This is probably only useful when @samp{edit -c} and
+@samp{commit -c} are specified in all developers' @file{.cvsrc} files. This
+behavior may be overriden this via the @code{-f} option, which overrides
+@code{-c} and allows multiple edits to succeed.
+
+@ignore
+@strong{Caution: If the @code{PreservePermissions}
+option is enabled in the repository (@pxref{config}),
+@sc{cvs} will not change the permissions on any of the
+@var{files}. The reason for this change is to ensure
+that using @samp{cvs edit} does not interfere with the
+ability to store file permissions in the @sc{cvs}
+repository.}
+@end ignore
+
+@end deffn
+
+Normally when you are done with a set of changes, you
+use the @code{cvs commit} command, which checks in your
+changes and returns the watched files to their usual
+read-only state. But if you instead decide to abandon
+your changes, or not to make any changes, you can use
+the @code{cvs unedit} command.
+
+@cindex unedit (subcommand)
+@cindex Abandoning work
+@cindex Reverting to repository version
+@deffn Command {cvs unedit} [@code{-lR}] [@var{files}]@dots{}
+
+Abandon work on the working files @var{files}, and revert them to the
+repository versions on which they are based. @sc{cvs} makes those
+@var{files} read-only for which users have requested notification using
+@code{cvs watch on}. @sc{cvs} notifies users who have requested @code{unedit}
+notification for any of @var{files}.
+
+The @var{files} and options are processed as for the
+@code{cvs watch} commands.
+
+If watches are not in use, the @code{unedit} command
+probably does not work, and the way to revert to the
+repository version is with the command @code{cvs update -C file}
+(@pxref{update}).
+The meaning is
+not precisely the same; the latter may also
+bring in some changes which have been made in the
+repository since the last time you updated.
+@c It would be a useful enhancement to CVS to make
+@c unedit work in the non-watch case as well.
+@end deffn
+
+When using client/server @sc{cvs}, you can use the
+@code{cvs edit} and @code{cvs unedit} commands even if
+@sc{cvs} is unable to successfully communicate with the
+server; the notifications will be sent upon the next
+successful @sc{cvs} command.
+
+@node Watch information
+@subsection Information about who is watching and editing
+
+@cindex watchers (subcommand)
+@deffn Command {cvs watchers} [@code{-lR}] [@var{files}]@dots{}
+
+List the users currently watching changes to @var{files}. The report
+includes the files being watched, and the mail address of each watcher.
+
+The @var{files} and options are processed as for the
+@code{cvs watch} commands.
+
+@end deffn
+
+
+@cindex editors (subcommand)
+@deffn Command {cvs editors} [@code{-lR}] [@var{files}]@dots{}
+
+List the users currently working on @var{files}. The report
+includes the mail address of each user, the time when the user began
+working with the file, and the host and path of the working directory
+containing the file.
+
+The @var{files} and options are processed as for the
+@code{cvs watch} commands.
+
+@end deffn
+
+@node Watches Compatibility
+@subsection Using watches with old versions of CVS
+
+@cindex CVS 1.6, and watches
+If you use the watch features on a repository, it
+creates @file{CVS} directories in the repository and
+stores the information about watches in that directory.
+If you attempt to use @sc{cvs} 1.6 or earlier with the
+repository, you get an error message such as the
+following (all on one line):
+
+@example
+cvs update: cannot open CVS/Entries for reading:
+No such file or directory
+@end example
+
+@noindent
+and your operation will likely be aborted. To use the
+watch features, you must upgrade all copies of @sc{cvs}
+which use that repository in local or server mode. If
+you cannot upgrade, use the @code{watch off} and
+@code{watch remove} commands to remove all watches, and
+that will restore the repository to a state which
+@sc{cvs} 1.6 can cope with.
+
+@node Choosing a model
+@section Choosing between reserved or unreserved checkouts
+@cindex Choosing, reserved or unreserved checkouts
+
+Reserved and unreserved checkouts each have pros and
+cons. Let it be said that a lot of this is a matter of
+opinion or what works given different groups' working
+styles, but here is a brief description of some of the
+issues. There are many ways to organize a team of
+developers. @sc{cvs} does not try to enforce a certain
+organization. It is a tool that can be used in several
+ways.
+
+Reserved checkouts can be very counter-productive. If
+two persons want to edit different parts of a file,
+there may be no reason to prevent either of them from
+doing so. Also, it is common for someone to take out a
+lock on a file, because they are planning to edit it,
+but then forget to release the lock.
+
+@c "many groups"? specifics? cites to papers on this?
+@c some way to weasel-word it a bit more so we don't
+@c need facts :-)?
+People, especially people who are familiar with
+reserved checkouts, often wonder how often conflicts
+occur if unreserved checkouts are used, and how
+difficult they are to resolve. The experience with
+many groups is that they occur rarely and usually are
+relatively straightforward to resolve.
+
+The rarity of serious conflicts may be surprising, until one realizes
+that they occur only when two developers disagree on the proper design
+for a given section of code; such a disagreement suggests that the
+team has not been communicating properly in the first place. In order
+to collaborate under @emph{any} source management regimen, developers
+must agree on the general design of the system; given this agreement,
+overlapping changes are usually straightforward to merge.
+
+In some cases unreserved checkouts are clearly
+inappropriate. If no merge tool exists for the kind of
+file you are managing (for example word processor files
+or files edited by Computer Aided Design programs), and
+it is not desirable to change to a program which uses a
+mergeable data format, then resolving conflicts is
+going to be unpleasant enough that you generally will
+be better off to simply avoid the conflicts instead, by
+using reserved checkouts.
+
+The watches features described above in @ref{Watches}
+can be considered to be an intermediate model between
+reserved checkouts and unreserved checkouts. When you
+go to edit a file, it is possible to find out who else
+is editing it. And rather than having the system
+simply forbid both people editing the file, it can tell
+you what the situation is and let you figure out
+whether it is a problem in that particular case or not.
+Therefore, for some groups watches can be
+considered the best of both the reserved checkout and unreserved
+checkout worlds.
+
+As of @sc{cvs} client and server versions 1.12.10, you may also enable
+advisory locks by putting @samp{edit -c} and @samp{commit -c} in all
+developers' @file{.cvsrc} files. After this is done, @code{cvs edit}
+will fail if there are any other editors, and @code{cvs commit} will
+fail if the committer has not registered to edit the file via @code{cvs edit}.
+This is most effective in conjunction with files checked out read-only by
+default, which may be enabled by turning on watches in the repository or by
+putting @samp{cvs -r} in all @file{.cvsrc} files.
+
+
+@c ---------------------------------------------------------------------
+@node Revision management
+@chapter Revision management
+@cindex Revision management
+
+@c -- This chapter could be expanded a lot.
+@c -- Experiences are very welcome!
+
+If you have read this far, you probably have a pretty
+good grasp on what @sc{cvs} can do for you. This
+chapter talks a little about things that you still have
+to decide.
+
+If you are doing development on your own using @sc{cvs}
+you could probably skip this chapter. The questions
+this chapter takes up become more important when more
+than one person is working in a repository.
+
+@menu
+* When to commit:: Some discussion on the subject
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node When to commit
+@section When to commit?
+@cindex When to commit
+@cindex Committing, when to
+@cindex Policy
+
+Your group should decide which policy to use regarding
+commits. Several policies are possible, and as your
+experience with @sc{cvs} grows you will probably find
+out what works for you.
+
+If you commit files too quickly you might commit files
+that do not even compile. If your partner updates his
+working sources to include your buggy file, he will be
+unable to compile the code. On the other hand, other
+persons will not be able to benefit from the
+improvements you make to the code if you commit very
+seldom, and conflicts will probably be more common.
+
+It is common to only commit files after making sure
+that they can be compiled. Some sites require that the
+files pass a test suite. Policies like this can be
+enforced using the commitinfo file
+(@pxref{commitinfo}), but you should think twice before
+you enforce such a convention. By making the
+development environment too controlled it might become
+too regimented and thus counter-productive to the real
+goal, which is to get software written.
+
+@c ---------------------------------------------------------------------
+@node Keyword substitution
+@chapter Keyword substitution
+@cindex Keyword substitution
+@cindex Keyword expansion
+@cindex Identifying files
+
+@comment Be careful when editing this chapter.
+@comment Remember that this file is kept under
+@comment version control, so we must not accidentally
+@comment include a valid keyword in the running text.
+
+As long as you edit source files inside a working
+directory you can always find out the state of
+your files via @samp{cvs status} and @samp{cvs log}.
+But as soon as you export the files from your
+development environment it becomes harder to identify
+which revisions they are.
+
+@sc{cvs} can use a mechanism known as @dfn{keyword
+substitution} (or @dfn{keyword expansion}) to help
+identifying the files. Embedded strings of the form
+@code{$@var{keyword}$} and
+@code{$@var{keyword}:@dots{}$} in a file are replaced
+with strings of the form
+@code{$@var{keyword}:@var{value}$} whenever you obtain
+a new revision of the file.
+
+@menu
+* Keyword list:: Keywords
+* Using keywords:: Using keywords
+* Avoiding substitution:: Avoiding substitution
+* Substitution modes:: Substitution modes
+* Configuring keyword expansion:: Configuring keyword expansion
+* Log keyword:: Problems with the $@splitrcskeyword{Log}$ keyword.
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Keyword list
+@section Keyword List
+@cindex Keyword List
+
+@c FIXME: need some kind of example here I think,
+@c perhaps in a
+@c "Keyword intro" node. The intro in the "Keyword
+@c substitution" node itself seems OK, but to launch
+@c into a list of the keywords somehow seems too abrupt.
+
+This is a list of the keywords:
+
+@table @code
+@cindex Author keyword
+@item $@splitrcskeyword{Author}$
+The login name of the user who checked in the revision.
+
+@cindex CVSHeader keyword
+@item $@splitrcskeyword{CVSHeader}$
+A standard header (similar to $@splitrcskeyword{Header}$, but with
+the CVS root stripped off). It contains the relative
+pathname of the @sc{rcs} file to the CVS root, the
+revision number, the date (UTC), the author, the state,
+and the locker (if locked). Files will normally never
+be locked when you use @sc{cvs}.
+
+Note that this keyword has only been recently
+introduced to @sc{cvs} and may cause problems with
+existing installations if $@splitrcskeyword{CVSHeader}$ is already
+in the files for a different purpose. This keyword may
+be excluded using the @code{KeywordExpand=eCVSHeader}
+in the @file{CVSROOT/config} file.
+See @ref{Configuring keyword expansion} for more details.
+
+@cindex Date keyword
+@item $@splitrcskeyword{Date}$
+The date and time (UTC) the revision was checked in.
+
+@cindex Header keyword
+@item $@splitrcskeyword{Header}$
+A standard header containing the full pathname of the
+@sc{rcs} file, the revision number, the date (UTC), the
+author, the state, and the locker (if locked). Files
+will normally never be locked when you use @sc{cvs}.
+
+@cindex Id keyword
+@item $@splitrcskeyword{Id}$
+Same as @code{$@splitrcskeyword{Header}$}, except that the @sc{rcs}
+filename is without a path.
+
+@cindex Name keyword
+@item $@splitrcskeyword{Name}$
+Tag name used to check out this file. The keyword is
+expanded only if one checks out with an explicit tag
+name. For example, when running the command @code{cvs
+co -r first}, the keyword expands to @samp{Name: first}.
+
+@cindex Locker keyword
+@item $@splitrcskeyword{Locker}$
+The login name of the user who locked the revision
+(empty if not locked, which is the normal case unless
+@code{cvs admin -l} is in use).
+
+@cindex Log keyword
+@cindex MaxCommentLeaderLength
+@cindex UseArchiveCommentLeader
+@cindex Log keyword, configuring substitution behavior
+@item $@splitrcskeyword{Log}$
+The log message supplied during commit, preceded by a
+header containing the @sc{rcs} filename, the revision
+number, the author, and the date (UTC). Existing log
+messages are @emph{not} replaced. Instead, the new log
+message is inserted after @code{$@splitrcskeyword{Log}:@dots{}$}.
+By default, each new line is prefixed with the same string which
+precedes the @code{$@splitrcskeyword{Log}$} keyword, unless it exceeds the
+@code{MaxCommentLeaderLength} set in @file{CVSROOT/config}.
+
+For example, if the file contains:
+
+@example
+ /* Here is what people have been up to:
+ *
+ * $@splitrcskeyword{Log}: frob.c,v $
+ * Revision 1.1 1997/01/03 14:23:51 joe
+ * Add the superfrobnicate option
+ *
+ */
+@end example
+
+@noindent
+then additional lines which are added when expanding
+the @code{$@splitrcskeyword{Log}$} keyword will be preceded by @samp{ * }.
+Unlike previous versions of @sc{cvs} and @sc{rcs}, the
+@dfn{comment leader} from the @sc{rcs} file is not used.
+The @code{$@splitrcskeyword{Log}$} keyword is useful for
+accumulating a complete change log in a source file,
+but for several reasons it can be problematic.
+
+If the prefix of the @code{$@splitrcskeyword{Log}$} keyword turns out to be
+longer than @code{MaxCommentLeaderLength}, CVS will skip expansion of this
+keyword unless @code{UseArchiveCommentLeader} is also set in
+@file{CVSROOT/config} and a @samp{comment leader} is set in the RCS archive
+file, in which case the comment leader will be used instead. For more on
+setting the comment leader in the RCS archive file, @xref{admin}. For more
+on configuring the default @code{$@splitrcskeyword{Log}$} substitution
+behavior, @xref{config}.
+
+@xref{Log keyword}.
+
+@cindex RCSfile keyword
+@item $@splitrcskeyword{RCSfile}$
+The name of the RCS file without a path.
+
+@cindex Revision keyword
+@item $@splitrcskeyword{Revision}$
+The revision number assigned to the revision.
+
+@cindex Source keyword
+@item $@splitrcskeyword{Source}$
+The full pathname of the RCS file.
+
+@cindex State keyword
+@item $@splitrcskeyword{State}$
+The state assigned to the revision. States can be
+assigned with @code{cvs admin -s}---see @ref{admin options}.
+
+@cindex Local keyword
+@item Local keyword
+The @code{LocalKeyword} option in the @file{CVSROOT/config} file
+may be used to specify a local keyword which is to be
+used as an alias for one of the keywords: $@splitrcskeyword{Id}$,
+$@splitrcskeyword{Header}$, or $@splitrcskeyword{CVSHeader}$. For
+example, if the @file{CVSROOT/config} file contains
+a line with @code{LocalKeyword=MYBSD=CVSHeader}, then a
+file with the local keyword $@splitrcskeyword{MYBSD}$ will be
+expanded as if it were a $@splitrcskeyword{CVSHeader}$ keyword. If
+the src/frob.c file contained this keyword, it might
+look something like this:
+
+@example
+ /*
+ * $@splitrcskeyword{MYBSD}: src/frob.c,v 1.1 2003/05/04 09:27:45 john Exp $
+ */
+@end example
+
+Many repositories make use of a such a ``local
+keyword'' feature. An old patch to @sc{cvs} provided
+the @code{LocalKeyword} feature using a @code{tag=}
+option and called this the ``custom tag'' or ``local
+tag'' feature. It was used in conjunction with the
+what they called the @code{tagexpand=} option. In
+@sc{cvs} this other option is known as the
+@code{KeywordExpand} option.
+See @ref{Configuring keyword expansion} for more
+details.
+
+Examples from popular projects include:
+$@splitrcskeyword{FreeBSD}$, $@splitrcskeyword{NetBSD}$,
+$@splitrcskeyword{OpenBSD}$, $@splitrcskeyword{XFree86}$,
+$@splitrcskeyword{Xorg}$.
+
+The advantage of this is that you can include your
+local version information in a file using this local
+keyword without disrupting the upstream version
+information (which may be a different local keyword or
+a standard keyword). Allowing bug reports and the like
+to more properly identify the source of the original
+bug to the third-party and reducing the number of
+conflicts that arise during an import of a new version.
+
+All keyword expansion except the local keyword may be
+disabled using the @code{KeywordExpand} option in
+the @file{CVSROOT/config} file---see
+@ref{Configuring keyword expansion} for more details.
+
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Using keywords
+@section Using keywords
+
+To include a keyword string you simply include the
+relevant text string, such as @code{$@splitrcskeyword{Id}$}, inside the
+file, and commit the file. @sc{cvs} will automatically (Or,
+more accurately, as part of the update run that
+automatically happens after a commit.)
+expand the string as part of the commit operation.
+
+It is common to embed the @code{$@splitrcskeyword{Id}$} string in
+the source files so that it gets passed through to
+generated files. For example, if you are managing
+computer program source code, you might include a
+variable which is initialized to contain that string.
+Or some C compilers may provide a @code{#pragma ident}
+directive. Or a document management system might
+provide a way to pass a string through to generated
+files.
+
+@c Would be nice to give an example, but doing this in
+@c portable C is not possible and the problem with
+@c picking any one language (VMS HELP files, Ada,
+@c troff, whatever) is that people use CVS for all
+@c kinds of files.
+
+@cindex Ident (shell command)
+The @code{ident} command (which is part of the @sc{rcs}
+package) can be used to extract keywords and their
+values from a file. This can be handy for text files,
+but it is even more useful for extracting keywords from
+binary files.
+
+@example
+$ ident samp.c
+samp.c:
+ $@splitrcskeyword{Id}: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
+$ gcc samp.c
+$ ident a.out
+a.out:
+ $@splitrcskeyword{Id}: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
+@end example
+
+@cindex What (shell command)
+S@sc{ccs} is another popular revision control system.
+It has a command, @code{what}, which is very similar to
+@code{ident} and used for the same purpose. Many sites
+without @sc{rcs} have @sc{sccs}. Since @code{what}
+looks for the character sequence @code{@@(#)} it is
+easy to include keywords that are detected by either
+command. Simply prefix the keyword with the
+magic @sc{sccs} phrase, like this:
+
+@example
+static char *id="@@(#) $@splitrcskeyword{Id}: ab.c,v 1.5 1993/10/19 14:57:32 ceder Exp $";
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Avoiding substitution
+@section Avoiding substitution
+
+Keyword substitution has its disadvantages. Sometimes
+you might want the literal text string
+@samp{$@splitrcskeyword{Author}$} to appear inside a file without
+@sc{cvs} interpreting it as a keyword and expanding it
+into something like @samp{$@splitrcskeyword{Author}: ceder $}.
+
+There is unfortunately no way to selectively turn off
+keyword substitution. You can use @samp{-ko}
+(@pxref{Substitution modes}) to turn off keyword
+substitution entirely.
+
+In many cases you can avoid using keywords in
+the source, even though they appear in the final
+product. For example, the source for this manual
+contains @samp{$@@asis@{@}Author$} whenever the text
+@samp{$@splitrcskeyword{Author}$} should appear. In @code{nroff}
+and @code{troff} you can embed the null-character
+@code{\&} inside the keyword for a similar effect.
+
+It is also possible to specify an explicit list of
+keywords to include or exclude using the
+@code{KeywordExpand} option in the
+@file{CVSROOT/config} file--see @ref{Configuring keyword expansion}
+for more details. This feature is intended primarily
+for use with the @code{LocalKeyword} option--see
+@ref{Keyword list}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Substitution modes
+@section Substitution modes
+@cindex Keyword substitution, changing modes
+@cindex -k (keyword substitution)
+@cindex Kflag
+
+@c FIXME: This could be made more coherent, by expanding it
+@c with more examples or something.
+Each file has a stored default substitution mode, and
+each working directory copy of a file also has a
+substitution mode. The former is set by the @samp{-k}
+option to @code{cvs add} and @code{cvs admin}; the
+latter is set by the @samp{-k} or @samp{-A} options to @code{cvs
+checkout} or @code{cvs update}.
+@code{cvs diff} and @code{cvs rdiff} also
+have @samp{-k} options.
+For some examples,
+see @ref{Binary files}, and @ref{Merging and keywords}.
+@c The fact that -A is overloaded to mean both reset
+@c sticky options and reset sticky tags/dates is
+@c somewhat questionable. Perhaps there should be
+@c separate options to reset sticky options (e.g. -k
+@c A") and tags/dates (someone suggested -r HEAD could
+@c do this instead of setting a sticky tag of "HEAD"
+@c as in the status quo but I haven't thought much
+@c about that idea. Of course -r .reset or something
+@c could be coined if this needs to be a new option).
+@c On the other hand, having -A mean "get things back
+@c into the state after a fresh checkout" has a certain
+@c appeal, and maybe there is no sufficient reason for
+@c creeping featurism in this area.
+
+The modes available are:
+
+@table @samp
+@item -kkv
+Generate keyword strings using the default form, e.g.
+@code{$@splitrcskeyword{Revision}: 5.7 $} for the @code{Revision}
+keyword.
+
+@item -kkvl
+Like @samp{-kkv}, except that a locker's name is always
+inserted if the given revision is currently locked.
+The locker's name is only relevant if @code{cvs admin
+-l} is in use.
+
+@item -kk
+Generate only keyword names in keyword strings; omit
+their values. For example, for the @code{Revision}
+keyword, generate the string @code{$@splitrcskeyword{Revision}$}
+instead of @code{$@splitrcskeyword{Revision}: 5.7 $}. This option
+is useful to ignore differences due to keyword
+substitution when comparing different revisions of a
+file (@pxref{Merging and keywords}).
+
+@item -ko
+Generate the old keyword string, present in the working
+file just before it was checked in. For example, for
+the @code{Revision} keyword, generate the string
+@code{$@splitrcskeyword{Revision}: 1.1 $} instead of
+@code{$@splitrcskeyword{Revision}: 5.7 $} if that is how the
+string appeared when the file was checked in.
+
+@item -kb
+Like @samp{-ko}, but also inhibit conversion of line
+endings between the canonical form in which they are
+stored in the repository (linefeed only), and the form
+appropriate to the operating system in use on the
+client. For systems, like unix, which use linefeed
+only to terminate lines, this is very similar to
+@samp{-ko}. For more information on binary files, see
+@ref{Binary files}. In @sc{cvs} version 1.12.2 and later
+@samp{-kb}, as set by @code{cvs add}, @code{cvs admin}, or
+@code{cvs import} may not be overridden by a @samp{-k} option
+specified on the command line.
+
+@item -kv
+Generate only keyword values for keyword strings. For
+example, for the @code{Revision} keyword, generate the string
+@code{5.7} instead of @code{$@splitrcskeyword{Revision}: 5.7 $}.
+This can help generate files in programming languages
+where it is hard to strip keyword delimiters like
+@code{$@splitrcskeyword{Revision}: $} from a string. However,
+further keyword substitution cannot be performed once
+the keyword names are removed, so this option should be
+used with care.
+
+One often would like to use @samp{-kv} with @code{cvs
+export}---@pxref{export}. But be aware that doesn't
+handle an export containing binary files correctly.
+
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Configuring keyword expansion
+@section Configuring Keyword Expansion
+@cindex Configuring keyword expansion
+
+In a repository that includes third-party software on
+vendor branches, it is sometimes helpful to configure
+CVS to use a local keyword instead of the standard
+$@splitrcskeyword{Id}$ or $@splitrcskeyword{Header}$ keywords. Examples from
+real projects include $@splitrcskeyword{Xorg}$, $@splitrcskeyword{XFree86}$,
+$@splitrcskeyword{FreeBSD}$, $@splitrcskeyword{NetBSD}$,
+$@splitrcskeyword{OpenBSD}$, and even $@splitrcskeyword{dotat}$.
+The advantage of this is that
+you can include your local version information in a
+file using this local keyword (sometimes called a
+``custom tag'' or a ``local tag'') without disrupting
+the upstream version information (which may be a
+different local keyword or a standard keyword). In
+these cases, it is typically desirable to disable the
+expansion of all keywords except the configured local
+keyword.
+
+The @code{KeywordExpand} option in the
+@file{CVSROOT/config} file is intended to allow for the
+either the explicit exclusion of a keyword or list of
+keywords, or for the explicit inclusion of a keyword or
+a list of keywords. This list may include the
+@code{LocalKeyword} that has been configured.
+
+The @code{KeywordExpand} option is followed by
+@code{=} and the next character may either be @code{i}
+to start an inclusion list or @code{e} to start an
+exclusion list. If the following lines were added to
+the @file{CVSROOT/config} file:
+
+@example
+ # Add a "MyBSD" keyword and restrict keyword
+ # expansion
+ LocalKeyword=MyBSD=CVSHeader
+ KeywordExpand=iMyBSD
+@end example
+
+then only the $@splitrcskeyword{MyBSD}$ keyword would be expanded.
+A list may be used. The this example:
+
+@example
+ # Add a "MyBSD" keyword and restrict keyword
+ # expansion to the MyBSD, Name and Date keywords.
+ LocalKeyword=MyBSD=CVSHeader
+ KeywordExpand=iMyBSD,Name,Date
+@end example
+
+would allow $@splitrcskeyword{MyBSD}$, $@splitrcskeyword{Name}$, and
+$@splitrcskeyword{Date}$ to be expanded.
+
+It is also possible to configure an exclusion list
+using the following:
+
+@example
+ # Do not expand the non-RCS keyword CVSHeader
+ KeywordExpand=eCVSHeader
+@end example
+
+This allows @sc{cvs} to ignore the recently introduced
+$@splitrcskeyword{CVSHeader}$ keyword and retain all of the
+others. The exclusion entry could also contain the
+standard RCS keyword list, but this could be confusing
+to users that expect RCS keywords to be expanded, so
+care should be taken to properly set user expectations
+for a repository that is configured in that manner.
+
+If there is a desire to not have any RCS keywords
+expanded and not use the @code{-ko} flags everywhere,
+an administrator may disable all keyword expansion
+using the @file{CVSROOT/config} line:
+
+@example
+ # Do not expand any RCS keywords
+ KeywordExpand=i
+@end example
+
+this could be confusing to users that expect RCS
+keywords like $@splitrcskeyword{Id}$ to be expanded properly,
+so care should be taken to properly set user
+expectations for a repository so configured.
+
+It should be noted that a patch to provide both the
+@code{KeywordExpand} and @code{LocalKeyword} features
+has been around a long time. However, that patch
+implemented these features using @code{tag=} and
+@code{tagexpand=} keywords and those keywords are NOT
+recognized.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Log keyword
+@section Problems with the $@splitrcskeyword{Log}$ keyword.
+
+The @code{$@splitrcskeyword{Log}$} keyword is somewhat
+controversial. As long as you are working on your
+development system the information is easily accessible
+even if you do not use the @code{$@splitrcskeyword{Log}$}
+keyword---just do a @code{cvs log}. Once you export
+the file the history information might be useless
+anyhow.
+
+A more serious concern is that @sc{cvs} is not good at
+handling @code{$@splitrcskeyword{Log}$} entries when a branch is
+merged onto the main trunk. Conflicts often result
+from the merging operation.
+@c Might want to check whether the CVS implementation
+@c of RCS_merge has this problem the same way rcsmerge
+@c does. I would assume so....
+
+People also tend to "fix" the log entries in the file
+(correcting spelling mistakes and maybe even factual
+errors). If that is done the information from
+@code{cvs log} will not be consistent with the
+information inside the file. This may or may not be a
+problem in real life.
+
+It has been suggested that the @code{$@splitrcskeyword{Log}$}
+keyword should be inserted @emph{last} in the file, and
+not in the files header, if it is to be used at all.
+That way the long list of change messages will not
+interfere with everyday source file browsing.
+
+@c ---------------------------------------------------------------------
+@node Tracking sources
+@chapter Tracking third-party sources
+@cindex Third-party sources
+@cindex Tracking sources
+
+@c FIXME: Need discussion of added and removed files.
+@c FIXME: This doesn't really adequately introduce the
+@c concepts of "vendor" and "you". They don't *have*
+@c to be separate organizations or separate people.
+@c We want a description which is somewhat more based on
+@c the technical issues of which sources go where, but
+@c also with enough examples of how this relates to
+@c relationships like customer-supplier, developer-QA,
+@c maintainer-contributor, or whatever, to make it
+@c seem concrete.
+If you modify a program to better fit your site, you
+probably want to include your modifications when the next
+release of the program arrives. @sc{cvs} can help you with
+this task.
+
+@cindex Vendor
+@cindex Vendor branch
+@cindex Branch, vendor-
+In the terminology used in @sc{cvs}, the supplier of the
+program is called a @dfn{vendor}. The unmodified
+distribution from the vendor is checked in on its own
+branch, the @dfn{vendor branch}. @sc{cvs} reserves branch
+1.1.1 for this use.
+
+When you modify the source and commit it, your revision
+will end up on the main trunk. When a new release is
+made by the vendor, you commit it on the vendor branch
+and copy the modifications onto the main trunk.
+
+Use the @code{import} command to create and update
+the vendor branch. When you import a new file,
+(usually) the vendor branch is made the `head' revision, so
+anyone that checks out a copy of the file gets that
+revision. When a local modification is committed it is
+placed on the main trunk, and made the `head'
+revision.
+
+@menu
+* First import:: Importing for the first time
+* Update imports:: Updating with the import command
+* Reverting local changes:: Reverting to the latest vendor release
+* Binary files in imports:: Binary files require special handling
+* Keywords in imports:: Keyword substitution might be undesirable
+* Multiple vendor branches:: What if you get sources from several places?
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node First import
+@section Importing for the first time
+@cindex Importing modules
+
+@c Should mention naming conventions for vendor tags,
+@c release tags, and perhaps directory names.
+Use the @code{import} command to check in the sources
+for the first time. When you use the @code{import}
+command to track third-party sources, the @dfn{vendor
+tag} and @dfn{release tags} are useful. The
+@dfn{vendor tag} is a symbolic name for the branch
+(which is always 1.1.1, unless you use the @samp{-b
+@var{branch}} flag---see @ref{Multiple vendor branches}.). The
+@dfn{release tags} are symbolic names for a particular
+release, such as @samp{FSF_0_04}.
+
+@c I'm not completely sure this belongs here. But
+@c we need to say it _somewhere_ reasonably obvious; it
+@c is a common misconception among people first learning CVS
+Note that @code{import} does @emph{not} change the
+directory in which you invoke it. In particular, it
+does not set up that directory as a @sc{cvs} working
+directory; if you want to work with the sources import
+them first and then check them out into a different
+directory (@pxref{Getting the source}).
+
+@cindex wdiff (import example)
+Suppose you have the sources to a program called
+@code{wdiff} in a directory @file{wdiff-0.04},
+and are going to make private modifications that you
+want to be able to use even when new releases are made
+in the future. You start by importing the source to
+your repository:
+
+@example
+$ cd wdiff-0.04
+$ cvs import -m "Import of FSF v. 0.04" fsf/wdiff FSF_DIST WDIFF_0_04
+@end example
+
+The vendor tag is named @samp{FSF_DIST} in the above
+example, and the only release tag assigned is
+@samp{WDIFF_0_04}.
+@c FIXME: Need to say where fsf/wdiff comes from.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Update imports
+@section Updating with the import command
+
+When a new release of the source arrives, you import it into the
+repository with the same @code{import} command that you used to set up
+the repository in the first place. The only difference is that you
+specify a different release tag this time:
+
+@example
+$ tar xfz wdiff-0.05.tar.gz
+$ cd wdiff-0.05
+$ cvs import -m "Import of FSF v. 0.05" fsf/wdiff FSF_DIST WDIFF_0_05
+@end example
+
+@strong{WARNING: If you use a release tag that already exists in one of the
+repository archives, files removed by an import may not be detected.}
+
+For files that have not been modified locally, the newly created
+revision becomes the head revision. If you have made local
+changes, @code{import} will warn you that you must merge the changes
+into the main trunk, and tell you to use @samp{checkout -j} to do so:
+
+@c FIXME: why "wdiff" here and "fsf/wdiff" in the
+@c "import"? I think the assumption is that one has
+@c "wdiff fsf/wdiff" or some such in modules, but it
+@c would be better to not use modules in this example.
+@example
+$ cvs checkout -jFSF_DIST:yesterday -jFSF_DIST wdiff
+@end example
+
+@noindent
+The above command will check out the latest revision of
+@samp{wdiff}, merging the changes made on the vendor branch @samp{FSF_DIST}
+since yesterday into the working copy. If any conflicts arise during
+the merge they should be resolved in the normal way (@pxref{Conflicts
+example}). Then, the modified files may be committed.
+
+However, it is much better to use the two release tags rather than using
+a date on the branch as suggested above:
+
+@example
+$ cvs checkout -jWDIFF_0_04 -jWDIFF_0_05 wdiff
+@end example
+
+@noindent
+The reason this is better is that
+using a date, as suggested above, assumes that you do
+not import more than one release of a product per day.
+More importantly, using the release tags allows @sc{cvs} to detect files
+that were removed between the two vendor releases and mark them for
+removal. Since @code{import} has no way to detect removed files, you
+should do a merge like this even if @code{import} doesn't tell you to.
+
+@node Reverting local changes
+@section Reverting to the latest vendor release
+
+You can also revert local changes completely and return
+to the latest vendor release by changing the `head'
+revision back to the vendor branch on all files. For
+example, if you have a checked-out copy of the sources
+in @file{~/work.d/wdiff}, and you want to revert to the
+vendor's version for all the files in that directory,
+you would type:
+
+@example
+$ cd ~/work.d/wdiff
+$ cvs admin -bFSF_DIST .
+@end example
+
+@noindent
+You must specify the @samp{-bFSF_DIST} without any space
+after the @samp{-b}. @xref{admin options}.
+
+@node Binary files in imports
+@section How to handle binary files with cvs import
+
+Use the @samp{-k} wrapper option to tell import which
+files are binary. @xref{Wrappers}.
+
+@node Keywords in imports
+@section How to handle keyword substitution with cvs import
+
+The sources which you are importing may contain
+keywords (@pxref{Keyword substitution}). For example,
+the vendor may use @sc{cvs} or some other system
+which uses similar keyword expansion syntax. If you
+just import the files in the default fashion, then
+the keyword expansions supplied by the vendor will
+be replaced by keyword expansions supplied by your
+own copy of @sc{cvs}. It may be more convenient to
+maintain the expansions supplied by the vendor, so
+that this information can supply information about
+the sources that you imported from the vendor.
+
+To maintain the keyword expansions supplied by the
+vendor, supply the @samp{-ko} option to @code{cvs
+import} the first time you import the file.
+This will turn off keyword expansion
+for that file entirely, so if you want to be more
+selective you'll have to think about what you want
+and use the @samp{-k} option to @code{cvs update} or
+@code{cvs admin} as appropriate.
+@c Supplying -ko to import if the file already existed
+@c has no effect. Not clear to me whether it should
+@c or not.
+
+@node Multiple vendor branches
+@section Multiple vendor branches
+
+All the examples so far assume that there is only one
+vendor from which you are getting sources. In some
+situations you might get sources from a variety of
+places. For example, suppose that you are dealing with
+a project where many different people and teams are
+modifying the software. There are a variety of ways to
+handle this, but in some cases you have a bunch of
+source trees lying around and what you want to do more
+than anything else is just to all put them in @sc{cvs} so
+that you at least have them in one place.
+
+For handling situations in which there may be more than
+one vendor, you may specify the @samp{-b} option to
+@code{cvs import}. It takes as an argument the vendor
+branch to import to. The default is @samp{-b 1.1.1}.
+
+For example, suppose that there are two teams, the red
+team and the blue team, that are sending you sources.
+You want to import the red team's efforts to branch
+1.1.1 and use the vendor tag RED. You want to import
+the blue team's efforts to branch 1.1.3 and use the
+vendor tag BLUE. So the commands you might use are:
+
+@example
+$ cvs import dir RED RED_1-0
+$ cvs import -b 1.1.3 dir BLUE BLUE_1-5
+@end example
+
+Note that if your vendor tag does not match your
+@samp{-b} option, @sc{cvs} will not detect this case! For
+example,
+
+@example
+$ cvs import -b 1.1.3 dir RED RED_1-0
+@end example
+
+@noindent
+Be careful; this kind of mismatch is sure to sow
+confusion or worse. I can't think of a useful purpose
+for the ability to specify a mismatch here, but if you
+discover such a use, don't. @sc{cvs} is likely to make this
+an error in some future release.
+
+@c Probably should say more about the semantics of
+@c multiple branches. What about the default branch?
+@c What about joining (perhaps not as useful with
+@c multiple branches, or perhaps it is. Either way
+@c should be mentioned).
+
+@c I'm not sure about the best location for this. In
+@c one sense, it might belong right after we've introduced
+@c CVS's basic version control model, because people need
+@c to figure out builds right away. The current location
+@c is based on the theory that it kind of akin to the
+@c "Revision management" section.
+@node Builds
+@chapter How your build system interacts with CVS
+@cindex Builds
+@cindex make
+
+As mentioned in the introduction, @sc{cvs} does not
+contain software for building your software from source
+code. This section describes how various aspects of
+your build system might interact with @sc{cvs}.
+
+@c Is there a way to discuss this without reference to
+@c tools other than CVS? I'm not sure there is; I
+@c wouldn't think that people who learn CVS first would
+@c even have this concern.
+One common question, especially from people who are
+accustomed to @sc{rcs}, is how to make their build get
+an up to date copy of the sources. The answer to this
+with @sc{cvs} is two-fold. First of all, since
+@sc{cvs} itself can recurse through directories, there
+is no need to modify your @file{Makefile} (or whatever
+configuration file your build tool uses) to make sure
+each file is up to date. Instead, just use two
+commands, first @code{cvs -q update} and then
+@code{make} or whatever the command is to invoke your
+build tool. Secondly, you do not necessarily
+@emph{want} to get a copy of a change someone else made
+until you have finished your own work. One suggested
+approach is to first update your sources, then
+implement, build and
+test the change you were thinking of, and then commit
+your sources (updating first if necessary). By
+periodically (in between changes, using the approach
+just described) updating your entire tree, you ensure
+that your sources are sufficiently up to date.
+
+@cindex Bill of materials
+One common need is to record which versions of which
+source files went into a particular build. This kind
+of functionality is sometimes called @dfn{bill of
+materials} or something similar. The best way to do
+this with @sc{cvs} is to use the @code{tag} command to
+record which versions went into a given build
+(@pxref{Tags}).
+
+Using @sc{cvs} in the most straightforward manner
+possible, each developer will have a copy of the entire
+source tree which is used in a particular build. If
+the source tree is small, or if developers are
+geographically dispersed, this is the preferred
+solution. In fact one approach for larger projects is
+to break a project down into smaller
+@c I say subsystem instead of module because they may or
+@c may not use the modules file.
+separately-compiled subsystems, and arrange a way of
+releasing them internally so that each developer need
+check out only those subsystems which they are
+actively working on.
+
+Another approach is to set up a structure which allows
+developers to have their own copies of some files, and
+for other files to access source files from a central
+location. Many people have come up with some such a
+@c two such people are paul@sander.cupertino.ca.us (for
+@c a previous employer)
+@c and gunnar.tornblom@se.abb.com (spicm and related tools),
+@c but as far as I know
+@c no one has nicely packaged or released such a system (or
+@c instructions for constructing one).
+system using features such as the symbolic link feature
+found in many operating systems, or the @code{VPATH}
+feature found in many versions of @code{make}. One build
+tool which is designed to help with this kind of thing
+is Odin (see
+@code{ftp://ftp.cs.colorado.edu/pub/distribs/odin}).
+@c Should we be saying more about Odin? Or how you use
+@c it with CVS? Also, the Prime Time Freeware for Unix
+@c disk (see http://www.ptf.com/) has Odin (with a nice
+@c paragraph summarizing it on the web), so that might be a
+@c semi-"official" place to point people.
+@c
+@c Of course, many non-CVS systems have this kind of
+@c functionality, for example OSF's ODE
+@c (http://www.osf.org/ode/) or mk
+@c (http://www.grin.net/~pzi/mk-3.18.4.docs/mk_toc.html
+@c He has changed providers in the past; a search engine search
+@c for "Peter Ziobrzynski" probably won't get too many
+@c spurious hits :-). A more stable URL might be
+@c ftp://ftp.uu.net/pub/cmvc/mk). But I'm not sure
+@c there is any point in mentioning them here unless they
+@c can work with CVS.
+
+@c ---------------------------------------------------------------------
+@node Special Files
+@chapter Special Files
+
+@cindex Special files
+@cindex Device nodes
+@cindex Ownership, saving in CVS
+@cindex Permissions, saving in CVS
+@cindex Hard links
+@cindex Symbolic links
+
+In normal circumstances, @sc{cvs} works only with regular
+files. Every file in a project is assumed to be
+persistent; it must be possible to open, read and close
+them; and so on. @sc{cvs} also ignores file permissions and
+ownerships, leaving such issues to be resolved by the
+developer at installation time. In other words, it is
+not possible to "check in" a device into a repository;
+if the device file cannot be opened, @sc{cvs} will refuse to
+handle it. Files also lose their ownerships and
+permissions during repository transactions.
+
+@ignore
+If the configuration variable @code{PreservePermissions}
+(@pxref{config}) is set in the repository, @sc{cvs} will
+save the following file characteristics in the
+repository:
+
+@itemize @bullet
+@item user and group ownership
+@item permissions
+@item major and minor device numbers
+@item symbolic links
+@item hard link structure
+@end itemize
+
+Using the @code{PreservePermissions} option affects the
+behavior of @sc{cvs} in several ways. First, some of the
+new operations supported by @sc{cvs} are not accessible to
+all users. In particular, file ownership and special
+file characteristics may only be changed by the
+superuser. When the @code{PreservePermissions}
+configuration variable is set, therefore, users will
+have to be `root' in order to perform @sc{cvs} operations.
+
+When @code{PreservePermissions} is in use, some @sc{cvs}
+operations (such as @samp{cvs status}) will not
+recognize a file's hard link structure, and so will
+emit spurious warnings about mismatching hard links.
+The reason is that @sc{cvs}'s internal structure does not
+make it easy for these operations to collect all the
+necessary data about hard links, so they check for file
+conflicts with inaccurate data.
+
+A more subtle difference is that @sc{cvs} considers a file
+to have changed only if its contents have changed
+(specifically, if the modification time of the working
+file does not match that of the repository's file).
+Therefore, if only the permissions, ownership or hard
+linkage have changed, or if a device's major or minor
+numbers have changed, @sc{cvs} will not notice. In order to
+commit such a change to the repository, you must force
+the commit with @samp{cvs commit -f}. This also means
+that if a file's permissions have changed and the
+repository file is newer than the working copy,
+performing @samp{cvs update} will silently change the
+permissions on the working copy.
+
+Changing hard links in a @sc{cvs} repository is particularly
+delicate. Suppose that file @file{foo} is linked to
+file @file{old}, but is later relinked to file
+@file{new}. You can wind up in the unusual situation
+where, although @file{foo}, @file{old} and @file{new}
+have all had their underlying link patterns changed,
+only @file{foo} and @file{new} have been modified, so
+@file{old} is not considered a candidate for checking
+in. It can be very easy to produce inconsistent
+results this way. Therefore, we recommend that when it
+is important to save hard links in a repository, the
+prudent course of action is to @code{touch} any file
+whose linkage or status has changed since the last
+checkin. Indeed, it may be wise to @code{touch *}
+before each commit in a directory with complex hard
+link structures.
+
+It is worth noting that only regular files may
+be merged, for reasons that hopefully are obvious. If
+@samp{cvs update} or @samp{cvs checkout -j} attempts to
+merge a symbolic link with a regular file, or two
+device files for different kinds of devices, @sc{cvs} will
+report a conflict and refuse to perform the merge. At
+the same time, @samp{cvs diff} will not report any
+differences between these files, since no meaningful
+textual comparisons can be made on files which contain
+no text.
+
+The @code{PreservePermissions} features do not work
+with client/server @sc{cvs}. Another limitation is
+that hard links must be to other files within the same
+directory; hard links across directories are not
+supported.
+@end ignore
+
+@c ---------------------------------------------------------------------
+@c ----- START MAN 1 -----
+@node CVS commands
+@appendix Guide to CVS commands
+
+This appendix describes the overall structure of
+@sc{cvs} commands, and describes some commands in
+detail (others are described elsewhere; for a quick
+reference to @sc{cvs} commands, @pxref{Invoking CVS}).
+@c The idea is that we want to move the commands which
+@c are described here into the main body of the manual,
+@c in the process reorganizing the manual to be
+@c organized around what the user wants to do, not
+@c organized around CVS commands.
+@c
+@c Note that many users do expect a manual which is
+@c organized by command. At least some users do.
+@c One good addition to the "organized by command"
+@c section (if any) would be "see also" links.
+@c The awk manual might be a good example; it has a
+@c reference manual which is more verbose than Invoking
+@c CVS but probably somewhat less verbose than CVS
+@c Commands.
+
+@menu
+* Structure:: Overall structure of CVS commands
+* Exit status:: Indicating CVS's success or failure
+* ~/.cvsrc:: Default options with the ~/.cvsrc file
+* Global options:: Options you give to the left of cvs_command
+* Common options:: Options you give to the right of cvs_command
+* Date input formats:: Acceptable formats for date specifications
+* admin:: Administration
+* annotate:: What revision modified each line of a file?
+* checkout:: Checkout sources for editing
+* commit:: Check files into the repository
+* diff:: Show differences between revisions
+* export:: Export sources from CVS, similar to checkout
+* history:: Show status of files and users
+* import:: Import sources into CVS, using vendor branches
+* log:: Show log messages for files
+* ls & rls:: List files in the repository
+* rdiff:: 'patch' format diffs between releases
+* release:: Indicate that a directory is no longer in use
+* server & pserver:: Act as a server for a client on stdin/stdout
+* update:: Bring work tree in sync with repository
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Structure
+@appendixsec Overall structure of CVS commands
+@cindex Structure
+@cindex CVS command structure
+@cindex Command structure
+@cindex Format of CVS commands
+
+The overall format of all @sc{cvs} commands is:
+
+@example
+cvs [ cvs_options ] cvs_command [ command_options ] [ command_args ]
+@end example
+
+@table @code
+@item cvs
+The name of the @sc{cvs} program.
+
+@item cvs_options
+Some options that affect all sub-commands of @sc{cvs}. These are
+described below.
+
+@item cvs_command
+One of several different sub-commands. Some of the commands have
+aliases that can be used instead; those aliases are noted in the
+reference manual for that command. There are only two situations
+where you may omit @samp{cvs_command}: @samp{cvs -H} elicits a
+list of available commands, and @samp{cvs -v} displays version
+information on @sc{cvs} itself.
+
+@item command_options
+Options that are specific for the command.
+
+@item command_args
+Arguments to the commands.
+@end table
+
+There is unfortunately some confusion between
+@code{cvs_options} and @code{command_options}.
+When given as a @code{cvs_option}, some options only
+affect some of the commands. When given as a
+@code{command_option} it may have a different meaning, and
+be accepted by more commands. In other words, do not
+take the above categorization too seriously. Look at
+the documentation instead.
+
+@node Exit status
+@appendixsec CVS's exit status
+@cindex Exit status, of CVS
+
+@sc{cvs} can indicate to the calling environment whether it
+succeeded or failed by setting its @dfn{exit status}.
+The exact way of testing the exit status will vary from
+one operating system to another. For example in a unix
+shell script the @samp{$?} variable will be 0 if the
+last command returned a successful exit status, or
+greater than 0 if the exit status indicated failure.
+
+If @sc{cvs} is successful, it returns a successful status;
+if there is an error, it prints an error message and
+returns a failure status. The one exception to this is
+the @code{cvs diff} command. It will return a
+successful status if it found no differences, or a
+failure status if there were differences or if there
+was an error. Because this behavior provides no good
+way to detect errors, in the future it is possible that
+@code{cvs diff} will be changed to behave like the
+other @sc{cvs} commands.
+@c It might seem like checking whether cvs -q diff
+@c produces empty or non-empty output can tell whether
+@c there were differences or not. But it seems like
+@c there are cases with output but no differences
+@c (testsuite basica-8b). It is not clear to me how
+@c useful it is for a script to be able to check
+@c whether there were differences.
+@c FIXCVS? In previous versions of CVS, cvs diff
+@c returned 0 for no differences, 1 for differences, or
+@c 2 for errors. Is this behavior worth trying to
+@c bring back (but what does it mean for VMS?)?
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node ~/.cvsrc
+@appendixsec Default options and the ~/.cvsrc file
+@cindex .cvsrc file
+@cindex Option defaults
+
+There are some @code{command_options} that are used so
+often that you might have set up an alias or some other
+means to make sure you always specify that option. One
+example (the one that drove the implementation of the
+@file{.cvsrc} support, actually) is that many people find the
+default output of the @samp{diff} command to be very
+hard to read, and that either context diffs or unidiffs
+are much easier to understand.
+
+The @file{~/.cvsrc} file is a way that you can add
+default options to @code{cvs_commands} within cvs,
+instead of relying on aliases or other shell scripts.
+
+The format of the @file{~/.cvsrc} file is simple. The
+file is searched for a line that begins with the same
+name as the @code{cvs_command} being executed. If a
+match is found, then the remainder of the line is split
+up (at whitespace characters) into separate options and
+added to the command arguments @emph{before} any
+options from the command line.
+
+If a command has two names (e.g., @code{checkout} and
+@code{co}), the official name, not necessarily the one
+used on the command line, will be used to match against
+the file. So if this is the contents of the user's
+@file{~/.cvsrc} file:
+
+@example
+log -N
+diff -uN
+rdiff -u
+update -Pd
+checkout -P
+release -d
+@end example
+
+@noindent
+the command @samp{cvs checkout foo} would have the
+@samp{-P} option added to the arguments, as well as
+@samp{cvs co foo}.
+
+With the example file above, the output from @samp{cvs
+diff foobar} will be in unidiff format. @samp{cvs diff
+-c foobar} will provide context diffs, as usual.
+Getting "old" format diffs would be slightly more
+complicated, because @code{diff} doesn't have an option
+to specify use of the "old" format, so you would need
+@samp{cvs -f diff foobar}.
+
+In place of the command name you can use @code{cvs} to
+specify global options (@pxref{Global options}). For
+example the following line in @file{.cvsrc}
+
+@example
+cvs -z6
+@end example
+
+@noindent
+causes @sc{cvs} to use compression level 6.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Global options
+@appendixsec Global options
+@cindex Options, global
+@cindex Global options
+@cindex Left-hand options
+
+The available @samp{cvs_options} (that are given to the
+left of @samp{cvs_command}) are:
+
+@table @code
+@item --allow-root=@var{rootdir}
+May be invoked multiple times to specify one legal @sc{cvsroot} directory with
+each invocation. Also causes CVS to preparse the configuration file for each
+specified root, which can be useful when configuring write proxies, See
+@ref{Password authentication server} & @ref{Write proxies}.
+
+@cindex Authentication, stream
+@cindex Stream authentication
+@item -a
+Authenticate all communication between the client and
+the server. Only has an effect on the @sc{cvs} client.
+As of this writing, this is only implemented when using
+a GSSAPI connection (@pxref{GSSAPI authenticated}).
+Authentication prevents certain sorts of attacks
+involving hijacking the active @sc{tcp} connection.
+Enabling authentication does not enable encryption.
+
+@cindex RCSBIN, overriding
+@cindex Overriding RCSBIN
+@item -b @var{bindir}
+In @sc{cvs} 1.9.18 and older, this specified that
+@sc{rcs} programs are in the @var{bindir} directory.
+Current versions of @sc{cvs} do not run @sc{rcs}
+programs; for compatibility this option is accepted,
+but it does nothing.
+
+@cindex TMPDIR, environment variable
+@cindex temporary file directory, set via command line
+@cindex temporary file directory, set via environment variable
+@cindex temporary file directory, set via config
+@cindex temporary files, location of
+@item -T @var{tempdir}
+Use @var{tempdir} as the directory where temporary files are
+located.
+
+The @sc{cvs} client and server store temporary files in a temporary directory.
+The path to this temporary directory is set via, in order of precedence:
+
+@itemize @bullet
+@item
+The argument to the global @samp{-T} option.
+
+@item
+The value set for @code{TmpDir} in the config file (server only -
+@pxref{config}).
+
+@item
+The contents of the @code{$TMPDIR} environment variable (@code{%TMPDIR%} on
+Windows - @pxref{Environment variables}).
+
+@item
+/tmp
+
+@end itemize
+
+Temporary directories should always be specified as an absolute pathname.
+When running a CVS client, @samp{-T} affects only the local process;
+specifying @samp{-T} for the client has no effect on the server and
+vice versa.
+
+@cindex CVSROOT, overriding
+@cindex Overriding CVSROOT
+@item -d @var{cvs_root_directory}
+Use @var{cvs_root_directory} as the root directory
+pathname of the repository. Overrides the setting of
+the @code{$CVSROOT} environment variable. @xref{Repository}.
+
+@cindex EDITOR, overriding
+@cindex Overriding EDITOR
+@item -e @var{editor}
+Use @var{editor} to enter revision log information. Overrides the
+setting of the @code{$CVSEDITOR} and @code{$EDITOR}
+environment variables. For more information, see
+@ref{Committing your changes}.
+
+@item -f
+Do not read the @file{~/.cvsrc} file. This
+option is most often used because of the
+non-orthogonality of the @sc{cvs} option set. For
+example, the @samp{cvs log} option @samp{-N} (turn off
+display of tag names) does not have a corresponding
+option to turn the display on. So if you have
+@samp{-N} in the @file{~/.cvsrc} entry for @samp{log},
+you may need to use @samp{-f} to show the tag names.
+
+@item -H
+@itemx --help
+Display usage information about the specified @samp{cvs_command}
+(but do not actually execute the command). If you don't specify
+a command name, @samp{cvs -H} displays overall help for
+@sc{cvs}, including a list of other help options.
+@c It seems to me it is better to document it this way
+@c rather than trying to update this documentation
+@c every time that we add a --help-foo option. But
+@c perhaps that is confusing...
+
+@cindex Read-only repository mode
+@item -R
+Turns on read-only repository mode. This allows one to check out from a
+read-only repository, such as within an anoncvs server, or from a @sc{cd-rom}
+repository.
+
+Same effect as if the @code{CVSREADONLYFS} environment
+variable is set. Using @samp{-R} can also considerably
+speed up checkouts over NFS.
+
+@cindex Read-only mode
+@item -n
+Do not change any files. Attempt to execute the
+@samp{cvs_command}, but only to issue reports; do not remove,
+update, or merge any existing files, or create any new files.
+
+Note that @sc{cvs} will not necessarily produce exactly
+the same output as without @samp{-n}. In some cases
+the output will be the same, but in other cases
+@sc{cvs} will skip some of the processing that would
+have been required to produce the exact same output.
+
+@item -Q
+Cause the command to be really quiet; the command will only
+generate output for serious problems.
+
+@item -q
+Cause the command to be somewhat quiet; informational messages,
+such as reports of recursion through subdirectories, are
+suppressed.
+
+@cindex Read-only files, and -r
+@item -r
+Make new working files read-only. Same effect
+as if the @code{$CVSREAD} environment variable is set
+(@pxref{Environment variables}). The default is to
+make working files writable, unless watches are on
+(@pxref{Watches}).
+
+@item -s @var{variable}=@var{value}
+Set a user variable (@pxref{Variables}).
+
+@cindex Trace
+@item -t
+Trace program execution; display messages showing the steps of
+@sc{cvs} activity. Particularly useful with @samp{-n} to explore the
+potential impact of an unfamiliar command.
+
+@item -v
+@item --version
+Display version and copyright information for @sc{cvs}.
+
+@cindex CVSREAD, overriding
+@cindex Overriding CVSREAD
+@item -w
+Make new working files read-write. Overrides the
+setting of the @code{$CVSREAD} environment variable.
+Files are created read-write by default, unless @code{$CVSREAD} is
+set or @samp{-r} is given.
+@c Note that -w only overrides -r and CVSREAD; it has
+@c no effect on files which are readonly because of
+@c "cvs watch on". My guess is that is the way it
+@c should be (or should "cvs -w get" on a watched file
+@c be the same as a get and a cvs edit?), but I'm not
+@c completely sure whether to document it this way.
+
+@item -x
+@cindex Encryption
+Encrypt all communication between the client and the
+server. Only has an effect on the @sc{cvs} client. As
+of this writing, this is only implemented when using a
+GSSAPI connection (@pxref{GSSAPI authenticated}) or a
+Kerberos connection (@pxref{Kerberos authenticated}).
+Enabling encryption implies that message traffic is
+also authenticated. Encryption support is not
+available by default; it must be enabled using a
+special configure option, @file{--enable-encryption},
+when you build @sc{cvs}.
+
+@item -z @var{level}
+@cindex Compression
+@cindex Gzip
+Request compression @var{level} for network traffic.
+@sc{cvs} interprets @var{level} identically to the @code{gzip} program.
+Valid levels are 1 (high speed, low compression) to
+9 (low speed, high compression), or 0 to disable
+compression (the default). Data sent to the server will
+be compressed at the requested level and the client will request
+the server use the same compression level for data returned. The
+server will use the closest level allowed by the server administrator to
+compress returned data. This option only has an effect when passed to
+the @sc{cvs} client.
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Common options
+@appendixsec Common command options
+@cindex Common options
+@cindex Right-hand options
+
+This section describes the @samp{command_options} that
+are available across several @sc{cvs} commands. These
+options are always given to the right of
+@samp{cvs_command}. Not all
+commands support all of these options; each option is
+only supported for commands where it makes sense.
+However, when a command has one of these options you
+can almost always count on the same behavior of the
+option as in other commands. (Other command options,
+which are listed with the individual commands, may have
+different behavior from one @sc{cvs} command to the other).
+
+@strong{Note: the @samp{history} command is an exception; it supports
+many options that conflict even with these standard options.}
+
+@table @code
+@cindex Dates
+@cindex Time
+@cindex Specifying dates
+@item -D @var{date_spec}
+Use the most recent revision no later than @var{date_spec}.
+@var{date_spec} is a single argument, a date description
+specifying a date in the past.
+
+The specification is @dfn{sticky} when you use it to make a
+private copy of a source file; that is, when you get a working
+file using @samp{-D}, @sc{cvs} records the date you specified, so that
+further updates in the same directory will use the same date
+(for more information on sticky tags/dates, @pxref{Sticky tags}).
+
+@samp{-D} is available with the @code{annotate}, @code{checkout},
+@code{diff}, @code{export}, @code{history}, @code{ls},
+@code{rdiff}, @code{rls}, @code{rtag}, @code{tag}, and @code{update} commands.
+(The @code{history} command uses this option in a
+slightly different way; @pxref{history options}).
+
+For a complete description of the date formats accepted by @sc{cvs},
+@ref{Date input formats}.
+@c What other formats should we accept? I don't want
+@c to start accepting a whole mess of non-standard
+@c new formats (there are a lot which are in wide use in
+@c one context or another), but practicality does
+@c dictate some level of flexibility.
+@c * POSIX.2 (e.g. touch, ls output, date) and other
+@c POSIX and/or de facto unix standards (e.g. at). The
+@c practice here is too inconsistent to be of any use.
+@c * VMS dates. This is not a formal standard, but
+@c there is a published specification (see SYS$ASCTIM
+@c and SYS$BINTIM in the _VMS System Services Reference
+@c Manual_), it is implemented consistently in VMS
+@c utilities, and VMS users will expect CVS running on
+@c VMS to support this format (and if we're going to do
+@c that, better to make CVS support it on all
+@c platforms. Maybe).
+@c
+@c One more note: In output, CVS should consistently
+@c use one date format, and that format should be one that
+@c it accepts in input as well. The former isn't
+@c really true (see survey below), and I'm not
+@c sure that either of those formats is accepted in
+@c input.
+@c
+@c cvs log
+@c current 1996/01/02 13:45:31
+@c Internet 02 Jan 1996 13:45:31 UT
+@c ISO 1996-01-02 13:45:31
+@c cvs ann
+@c current 02-Jan-96
+@c Internet-like 02 Jan 96
+@c ISO 96-01-02
+@c cvs status
+@c current Tue Jun 11 02:54:53 1996
+@c Internet [Tue,] 11 Jun 1996 02:54:53
+@c ISO 1996-06-11 02:54:53
+@c note: date possibly should be omitted entirely for
+@c other reasons.
+@c cvs editors
+@c current Tue Jun 11 02:54:53 1996 GMT
+@c cvs history
+@c current 06/11 02:54 +0000
+@c any others?
+@c There is a good chance the proper solution has to
+@c involve at least some level of letting the user
+@c decide which format (with the default being the
+@c formats CVS has always used; changing these might be
+@c _very_ disruptive since scripts may very well be
+@c parsing them).
+@c
+@c Another random bit of prior art concerning dates is
+@c the strptime function which takes templates such as
+@c "%m/%d/%y", and apparent a variant of getdate()
+@c which also honors them. See
+@c X/Open CAE Specification, System Interfaces and
+@c Headers Issue 4, Version 2 (September 1994), in the
+@c entry for getdate() on page 231
+
+Remember to quote the argument to the @samp{-D}
+flag so that your shell doesn't interpret spaces as
+argument separators. A command using the @samp{-D}
+flag can look like this:
+
+@example
+$ cvs diff -D "1 hour ago" cvs.texinfo
+@end example
+
+@cindex Forcing a tag match
+@item -f
+When you specify a particular date or tag to @sc{cvs} commands, they
+normally ignore files that do not contain the tag (or did not
+exist prior to the date) that you specified. Use the @samp{-f} option
+if you want files retrieved even when there is no match for the
+tag or date. (The most recent revision of the file
+will be used).
+
+Note that even with @samp{-f}, a tag that you specify
+must exist (that is, in some file, not necessary in
+every file). This is so that @sc{cvs} will continue to
+give an error if you mistype a tag name.
+
+@need 800
+@samp{-f} is available with these commands:
+@code{annotate}, @code{checkout}, @code{export},
+@code{rdiff}, @code{rtag}, and @code{update}.
+
+@strong{WARNING: The @code{commit} and @code{remove}
+commands also have a
+@samp{-f} option, but it has a different behavior for
+those commands. See @ref{commit options}, and
+@ref{Removing files}.}
+
+@item -k @var{kflag}
+Override the default processing of RCS keywords other than
+@samp{-kb}. @xref{Keyword substitution}, for the meaning of
+@var{kflag}. Used with the @code{checkout} and @code{update}
+commands, your @var{kflag} specification is
+@dfn{sticky}; that is, when you use this option
+with a @code{checkout} or @code{update} command,
+@sc{cvs} associates your selected @var{kflag} with any files
+it operates on, and continues to use that @var{kflag} with future
+commands on the same files until you specify otherwise.
+
+The @samp{-k} option is available with the @code{add},
+@code{checkout}, @code{diff}, @code{export}, @code{import},
+@code{rdiff}, and @code{update} commands.
+
+@strong{WARNING: Prior to CVS version 1.12.2, the @samp{-k} flag
+overrode the @samp{-kb} indication for a binary file. This could
+sometimes corrupt binary files. @xref{Merging and keywords}, for
+more.}
+
+@item -l
+Local; run only in current working directory, rather than
+recursing through subdirectories.
+
+Available with the following commands: @code{annotate}, @code{checkout},
+@code{commit}, @code{diff}, @code{edit}, @code{editors}, @code{export},
+@code{log}, @code{rdiff}, @code{remove}, @code{rtag},
+@code{status}, @code{tag}, @code{unedit}, @code{update}, @code{watch},
+and @code{watchers}.
+
+@cindex Editor, avoiding invocation of
+@cindex Avoiding editor invocation
+@item -m @var{message}
+Use @var{message} as log information, instead of
+invoking an editor.
+
+Available with the following commands: @code{add},
+@code{commit} and @code{import}.
+
+@item -n
+Do not run any tag program. (A program can be
+specified to run in the modules
+database (@pxref{modules}); this option bypasses it).
+
+@strong{Note: this is not the same as the @samp{cvs -n}
+program option, which you can specify to the left of a cvs command!}
+
+Available with the @code{checkout}, @code{commit}, @code{export},
+and @code{rtag} commands.
+
+@item -P
+Prune empty directories. See @ref{Removing directories}.
+
+@item -p
+Pipe the files retrieved from the repository to standard output,
+rather than writing them in the current directory. Available
+with the @code{checkout} and @code{update} commands.
+
+@item -R
+Process directories recursively. This is the default for all @sc{cvs}
+commands, with the exception of @code{ls} & @code{rls}.
+
+Available with the following commands: @code{annotate}, @code{checkout},
+@code{commit}, @code{diff}, @code{edit}, @code{editors}, @code{export},
+@code{ls}, @code{rdiff}, @code{remove}, @code{rls}, @code{rtag},
+@code{status}, @code{tag}, @code{unedit}, @code{update}, @code{watch},
+and @code{watchers}.
+
+@item -r @var{tag}
+@item -r @var{tag}[:@var{date}]
+@cindex HEAD, special tag
+@cindex BASE, special tag
+Use the revision specified by the @var{tag} argument (and the @var{date}
+argument for the commands which accept it) instead of the
+default @dfn{head} revision. As well as arbitrary tags defined
+with the @code{tag} or @code{rtag} command, two special tags are
+always available: @samp{HEAD} refers to the most recent version
+available in the repository, and @samp{BASE} refers to the
+revision you last checked out into the current working directory.
+
+@c FIXME: What does HEAD really mean? I believe that
+@c the current answer is the head of the default branch
+@c for all cvs commands except diff. For diff, it
+@c seems to be (a) the head of the trunk (or the default
+@c branch?) if there is no sticky tag, (b) the head of the
+@c branch for the sticky tag, if there is a sticky tag.
+@c (b) is ugly as it differs
+@c from what HEAD means for other commands, but people
+@c and/or scripts are quite possibly used to it.
+@c See "head" tests in sanity.sh.
+@c Probably the best fix is to introduce two new
+@c special tags, ".thead" for the head of the trunk,
+@c and ".bhead" for the head of the current branch.
+@c Then deprecate HEAD. This has the advantage of
+@c not surprising people with a change to HEAD, and a
+@c side benefit of also phasing out the poorly-named
+@c HEAD (see discussion of reserved tag names in node
+@c "Tags"). Of course, .thead and .bhead should be
+@c carefully implemented (with the implementation the
+@c same for "diff" as for everyone else), test cases
+@c written (similar to the ones in "head"), new tests
+@c cases written for things like default branches, &c.
+
+The tag specification is sticky when you use this
+with @code{checkout} or @code{update} to make your own
+copy of a file: @sc{cvs} remembers the tag and continues to use it on
+future update commands, until you specify otherwise (for more information
+on sticky tags/dates, @pxref{Sticky tags}).
+
+The tag can be either a symbolic or numeric tag, as
+described in @ref{Tags}, or the name of a branch, as
+described in @ref{Branching and merging}.
+When @var{tag} is the name of a
+branch, some commands accept the optional @var{date} argument to specify
+the revision as of the given date on the branch.
+When a command expects a specific revision,
+the name of a branch is interpreted as the most recent
+revision on that branch.
+
+Specifying the @samp{-q} global option along with the
+@samp{-r} command option is often useful, to suppress
+the warning messages when the @sc{rcs} file
+does not contain the specified tag.
+
+@strong{Note: this is not the same as the overall @samp{cvs -r} option,
+which you can specify to the left of a @sc{cvs} command!}
+
+@samp{-r @var{tag}} is available with the @code{commit} and @code{history}
+commands.
+
+@samp{-r @var{tag}[:@var{date}]} is available with the @code{annotate},
+@code{checkout}, @code{diff}, @code{export}, @code{rdiff}, @code{rtag},
+and @code{update} commands.
+
+@item -W
+Specify file names that should be filtered. You can
+use this option repeatedly. The spec can be a file
+name pattern of the same type that you can specify in
+the @file{.cvswrappers} file.
+Available with the following commands: @code{import},
+and @code{update}.
+
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@include getdate-cvs.texi
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node admin
+@appendixsec admin---Administration
+@cindex Admin (subcommand)
+
+@itemize @bullet
+@item
+Requires: repository, working directory.
+@item
+Changes: repository.
+@item
+Synonym: rcs
+@end itemize
+
+This is the @sc{cvs} interface to assorted
+administrative facilities. Some of them have
+questionable usefulness for @sc{cvs} but exist for
+historical purposes. Some of the questionable options
+are likely to disappear in the future. This command
+@emph{does} work recursively, so extreme care should be
+used.
+
+@cindex cvsadmin
+@cindex UserAdminOptions, in CVSROOT/config
+On unix, if there is a group named @code{cvsadmin},
+only members of that group can run @code{cvs admin}
+commands, except for those specified using the
+@code{UserAdminOptions} configuration option in the
+@file{CVSROOT/config} file. Options specified using
+@code{UserAdminOptions} can be run by any user. See
+@ref{config} for more on @code{UserAdminOptions}.
+
+The @code{cvsadmin} group should exist on the server,
+or any system running the non-client/server @sc{cvs}.
+To disallow @code{cvs admin} for all users, create a
+group with no users in it. On NT, the @code{cvsadmin}
+feature does not exist and all users
+can run @code{cvs admin}.
+
+@menu
+* admin options:: admin options
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node admin options
+@appendixsubsec admin options
+
+Some of these options have questionable usefulness for
+@sc{cvs} but exist for historical purposes. Some even
+make it impossible to use @sc{cvs} until you undo the
+effect!
+
+@table @code
+@item -A@var{oldfile}
+Might not work together with @sc{cvs}. Append the
+access list of @var{oldfile} to the access list of the
+@sc{rcs} file.
+
+@item -a@var{logins}
+Might not work together with @sc{cvs}. Append the
+login names appearing in the comma-separated list
+@var{logins} to the access list of the @sc{rcs} file.
+
+@item -b[@var{rev}]
+Set the default branch to @var{rev}. In @sc{cvs}, you
+normally do not manipulate default branches; sticky
+tags (@pxref{Sticky tags}) are a better way to decide
+which branch you want to work on. There is one reason
+to run @code{cvs admin -b}: to revert to the vendor's
+version when using vendor branches (@pxref{Reverting
+local changes}).
+There can be no space between @samp{-b} and its argument.
+@c Hmm, we don't document the usage where rev is
+@c omitted. Maybe that usage can/should be deprecated
+@c (and replaced with -bHEAD or something?) (so we can toss
+@c the optional argument). Note that -bHEAD does not
+@c work, as of 17 Sep 1997, but probably will once "cvs
+@c admin" is internal to CVS.
+
+@cindex Comment leader
+@item -c@var{string}
+Sets the comment leader to @var{string}. The comment
+leader is not used by current versions of @sc{cvs} or
+@sc{rcs} 5.7. Therefore, you can almost surely not
+worry about it. @xref{Keyword substitution}.
+
+@item -e[@var{logins}]
+Might not work together with @sc{cvs}. Erase the login
+names appearing in the comma-separated list
+@var{logins} from the access list of the RCS file. If
+@var{logins} is omitted, erase the entire access list.
+There can be no space between @samp{-e} and its argument.
+
+@item -I
+Run interactively, even if the standard input is not a
+terminal. This option does not work with the
+client/server @sc{cvs} and is likely to disappear in
+a future release of @sc{cvs}.
+
+@item -i
+Useless with @sc{cvs}. This creates and initializes a
+new @sc{rcs} file, without depositing a revision. With
+@sc{cvs}, add files with the @code{cvs add} command
+(@pxref{Adding files}).
+
+@item -k@var{subst}
+Set the default keyword
+substitution to @var{subst}. @xref{Keyword
+substitution}. Giving an explicit @samp{-k} option to
+@code{cvs update}, @code{cvs export}, or @code{cvs
+checkout} overrides this default.
+
+@item -l[@var{rev}]
+Lock the revision with number @var{rev}. If a branch
+is given, lock the latest revision on that branch. If
+@var{rev} is omitted, lock the latest revision on the
+default branch. There can be no space between
+@samp{-l} and its argument.
+
+This can be used in conjunction with the
+@file{rcslock.pl} script in the @file{contrib}
+directory of the @sc{cvs} source distribution to
+provide reserved checkouts (where only one user can be
+editing a given file at a time). See the comments in
+that file for details (and see the @file{README} file
+in that directory for disclaimers about the unsupported
+nature of contrib). According to comments in that
+file, locking must set to strict (which is the default).
+
+@item -L
+Set locking to strict. Strict locking means that the
+owner of an RCS file is not exempt from locking for
+checkin. For use with @sc{cvs}, strict locking must be
+set; see the discussion under the @samp{-l} option above.
+
+@cindex Changing a log message
+@cindex Replacing a log message
+@cindex Correcting a log message
+@cindex Fixing a log message
+@cindex Log message, correcting
+@item -m@var{rev}:@var{msg}
+Replace the log message of revision @var{rev} with
+@var{msg}.
+
+@c The rcs -M option, to suppress sending mail, has never been
+@c documented as a cvs admin option.
+
+@item -N@var{name}[:[@var{rev}]]
+Act like @samp{-n}, except override any previous
+assignment of @var{name}. For use with magic branches,
+see @ref{Magic branch numbers}.
+
+@item -n@var{name}[:[@var{rev}]]
+Associate the symbolic name @var{name} with the branch
+or revision @var{rev}. It is normally better to use
+@samp{cvs tag} or @samp{cvs rtag} instead. Delete the
+symbolic name if both @samp{:} and @var{rev} are
+omitted; otherwise, print an error message if
+@var{name} is already associated with another number.
+If @var{rev} is symbolic, it is expanded before
+association. A @var{rev} consisting of a branch number
+followed by a @samp{.} stands for the current latest
+revision in the branch. A @samp{:} with an empty
+@var{rev} stands for the current latest revision on the
+default branch, normally the trunk. For example,
+@samp{cvs admin -n@var{name}:} associates @var{name} with the
+current latest revision of all the RCS files;
+this contrasts with @samp{cvs admin -n@var{name}:$} which
+associates @var{name} with the revision numbers
+extracted from keyword strings in the corresponding
+working files.
+
+@cindex Deleting revisions
+@cindex Outdating revisions
+@cindex Saving space
+@item -o@var{range}
+Deletes (@dfn{outdates}) the revisions given by
+@var{range}.
+
+Note that this command can be quite dangerous unless
+you know @emph{exactly} what you are doing (for example
+see the warnings below about how the
+@var{rev1}:@var{rev2} syntax is confusing).
+
+If you are short on disc this option might help you.
+But think twice before using it---there is no way short
+of restoring the latest backup to undo this command!
+If you delete different revisions than you planned,
+either due to carelessness or (heaven forbid) a @sc{cvs}
+bug, there is no opportunity to correct the error
+before the revisions are deleted. It probably would be
+a good idea to experiment on a copy of the repository
+first.
+
+Specify @var{range} in one of the following ways:
+
+@table @code
+@item @var{rev1}::@var{rev2}
+Collapse all revisions between rev1 and rev2, so that
+@sc{cvs} only stores the differences associated with going
+from rev1 to rev2, not intermediate steps. For
+example, after @samp{-o 1.3::1.5} one can retrieve
+revision 1.3, revision 1.5, or the differences to get
+from 1.3 to 1.5, but not the revision 1.4, or the
+differences between 1.3 and 1.4. Other examples:
+@samp{-o 1.3::1.4} and @samp{-o 1.3::1.3} have no
+effect, because there are no intermediate revisions to
+remove.
+
+@item ::@var{rev}
+Collapse revisions between the beginning of the branch
+containing @var{rev} and @var{rev} itself. The
+branchpoint and @var{rev} are left intact. For
+example, @samp{-o ::1.3.2.6} deletes revision 1.3.2.1,
+revision 1.3.2.5, and everything in between, but leaves
+1.3 and 1.3.2.6 intact.
+
+@item @var{rev}::
+Collapse revisions between @var{rev} and the end of the
+branch containing @var{rev}. Revision @var{rev} is
+left intact but the head revision is deleted.
+
+@item @var{rev}
+Delete the revision @var{rev}. For example, @samp{-o
+1.3} is equivalent to @samp{-o 1.2::1.4}.
+
+@item @var{rev1}:@var{rev2}
+Delete the revisions from @var{rev1} to @var{rev2},
+inclusive, on the same branch. One will not be able to
+retrieve @var{rev1} or @var{rev2} or any of the
+revisions in between. For example, the command
+@samp{cvs admin -oR_1_01:R_1_02 .} is rarely useful.
+It means to delete revisions up to, and including, the
+tag R_1_02. But beware! If there are files that have not
+changed between R_1_02 and R_1_03 the file will have
+@emph{the same} numerical revision number assigned to
+the tags R_1_02 and R_1_03. So not only will it be
+impossible to retrieve R_1_02; R_1_03 will also have to
+be restored from the tapes! In most cases you want to
+specify @var{rev1}::@var{rev2} instead.
+
+@item :@var{rev}
+Delete revisions from the beginning of the
+branch containing @var{rev} up to and including
+@var{rev}.
+
+@item @var{rev}:
+Delete revisions from revision @var{rev}, including
+@var{rev} itself, to the end of the branch containing
+@var{rev}.
+@end table
+
+None of the revisions to be deleted may have
+branches or locks.
+
+If any of the revisions to be deleted have symbolic
+names, and one specifies one of the @samp{::} syntaxes,
+then @sc{cvs} will give an error and not delete any
+revisions. If you really want to delete both the
+symbolic names and the revisions, first delete the
+symbolic names with @code{cvs tag -d}, then run
+@code{cvs admin -o}. If one specifies the
+non-@samp{::} syntaxes, then @sc{cvs} will delete the
+revisions but leave the symbolic names pointing to
+nonexistent revisions. This behavior is preserved for
+compatibility with previous versions of @sc{cvs}, but
+because it isn't very useful, in the future it may
+change to be like the @samp{::} case.
+
+Due to the way @sc{cvs} handles branches @var{rev}
+cannot be specified symbolically if it is a branch.
+@xref{Magic branch numbers}, for an explanation.
+@c FIXME: is this still true? I suspect not.
+
+Make sure that no-one has checked out a copy of the
+revision you outdate. Strange things will happen if he
+starts to edit it and tries to check it back in. For
+this reason, this option is not a good way to take back
+a bogus commit; commit a new revision undoing the bogus
+change instead (@pxref{Merging two revisions}).
+
+@item -q
+Run quietly; do not print diagnostics.
+
+@item -s@var{state}[:@var{rev}]
+Useful with @sc{cvs}. Set the state attribute of the
+revision @var{rev} to @var{state}. If @var{rev} is a
+branch number, assume the latest revision on that
+branch. If @var{rev} is omitted, assume the latest
+revision on the default branch. Any identifier is
+acceptable for @var{state}. A useful set of states is
+@samp{Exp} (for experimental), @samp{Stab} (for
+stable), and @samp{Rel} (for released). By default,
+the state of a new revision is set to @samp{Exp} when
+it is created. The state is visible in the output from
+@var{cvs log} (@pxref{log}), and in the
+@samp{$@splitrcskeyword{Log}$} and @samp{$@splitrcskeyword{State}$} keywords
+(@pxref{Keyword substitution}). Note that @sc{cvs}
+uses the @code{dead} state for its own purposes (@pxref{Attic}); to
+take a file to or from the @code{dead} state use
+commands like @code{cvs remove} and @code{cvs add}
+(@pxref{Adding and removing}), not @code{cvs admin -s}.
+
+@item -t[@var{file}]
+Useful with @sc{cvs}. Write descriptive text from the
+contents of the named @var{file} into the RCS file,
+deleting the existing text. The @var{file} pathname
+may not begin with @samp{-}. The descriptive text can be seen in the
+output from @samp{cvs log} (@pxref{log}).
+There can be no space between @samp{-t} and its argument.
+
+If @var{file} is omitted,
+obtain the text from standard input, terminated by
+end-of-file or by a line containing @samp{.} by itself.
+Prompt for the text if interaction is possible; see
+@samp{-I}.
+
+@item -t-@var{string}
+Similar to @samp{-t@var{file}}. Write descriptive text
+from the @var{string} into the @sc{rcs} file, deleting
+the existing text.
+There can be no space between @samp{-t} and its argument.
+
+@c The rcs -T option, do not update last-mod time for
+@c minor changes, has never been documented as a
+@c cvs admin option.
+
+@item -U
+Set locking to non-strict. Non-strict locking means
+that the owner of a file need not lock a revision for
+checkin. For use with @sc{cvs}, strict locking must be
+set; see the discussion under the @samp{-l} option
+above.
+
+@item -u[@var{rev}]
+See the option @samp{-l} above, for a discussion of
+using this option with @sc{cvs}. Unlock the revision
+with number @var{rev}. If a branch is given, unlock
+the latest revision on that branch. If @var{rev} is
+omitted, remove the latest lock held by the caller.
+Normally, only the locker of a revision may unlock it;
+somebody else unlocking a revision breaks the lock.
+This causes the original locker to be sent a @code{commit}
+notification (@pxref{Getting Notified}).
+There can be no space between @samp{-u} and its argument.
+
+@item -V@var{n}
+In previous versions of @sc{cvs}, this option meant to
+write an @sc{rcs} file which would be acceptable to
+@sc{rcs} version @var{n}, but it is now obsolete and
+specifying it will produce an error.
+@c Note that -V without an argument has never been
+@c documented as a cvs admin option.
+
+@item -x@var{suffixes}
+In previous versions of @sc{cvs}, this was documented
+as a way of specifying the names of the @sc{rcs}
+files. However, @sc{cvs} has always required that the
+@sc{rcs} files used by @sc{cvs} end in @samp{,v}, so
+this option has never done anything useful.
+
+@c The rcs -z option, to specify the timezone, has
+@c never been documented as a cvs admin option.
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node annotate
+@appendixsec annotate---What revision modified each line of a file?
+@cindex annotate (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: annotate [options] files@dots{}
+@item
+Requires: repository.
+@item
+Changes: nothing.
+@end itemize
+
+For each file in @var{files}, print the head revision
+of the trunk, together with information on the last
+modification for each line.
+
+@menu
+* annotate options:: annotate options
+* annotate example:: annotate example
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node annotate options
+@appendixsubsec annotate options
+
+These standard options are supported by @code{annotate}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -l
+Local directory only, no recursion.
+
+@item -R
+Process directories recursively.
+
+@item -f
+Use head revision if tag/date not found.
+
+@item -F
+Annotate binary files.
+
+@item -r @var{tag}[:@var{date}]
+Annotate file as of specified revision/tag or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Common options}.
+
+@item -D @var{date}
+Annotate file as of specified date.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node annotate example
+@appendixsubsec annotate example
+
+For example:
+
+@example
+$ cvs annotate ssfile
+Annotations for ssfile
+***************
+1.1 (mary 27-Mar-96): ssfile line 1
+1.2 (joe 28-Mar-96): ssfile line 2
+@end example
+
+The file @file{ssfile} currently contains two lines.
+The @code{ssfile line 1} line was checked in by
+@code{mary} on March 27. Then, on March 28, @code{joe}
+added a line @code{ssfile line 2}, without modifying
+the @code{ssfile line 1} line. This report doesn't
+tell you anything about lines which have been deleted
+or replaced; you need to use @code{cvs diff} for that
+(@pxref{diff}).
+
+The options to @code{cvs annotate} are listed in
+@ref{Invoking CVS}, and can be used to select the files
+and revisions to annotate. The options are described
+in more detail there and in @ref{Common options}.
+
+@c FIXME: maybe an example using the options? Just
+@c what it means to select a revision might be worth a
+@c few words of explanation ("you want to see who
+@c changed this line *before* 1.4"...).
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node checkout
+@appendixsec checkout---Check out sources for editing
+@cindex checkout (subcommand)
+@cindex co (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: checkout [options] modules@dots{}
+@item
+Requires: repository.
+@item
+Changes: working directory.
+@item
+Synonyms: co, get
+@end itemize
+
+Create or update a working directory containing copies of the
+source files specified by @var{modules}. You must execute
+@code{checkout} before using most of the other @sc{cvs}
+commands, since most of them operate on your working
+directory.
+
+The @var{modules} are either
+symbolic names for some
+collection of source directories and files, or paths to
+directories or files in the repository. The symbolic
+names are defined in the @samp{modules} file.
+@xref{modules}.
+@c Needs an example, particularly of the non-"modules"
+@c case but probably of both.
+
+@c FIXME: this seems like a very odd place to introduce
+@c people to how CVS works. The bit about unreserved
+@c checkouts is also misleading as it depends on how
+@c things are set up.
+Depending on the modules you specify, @code{checkout} may
+recursively create directories and populate them with
+the appropriate source files. You can then edit these
+source files at any time (regardless of whether other
+software developers are editing their own copies of the
+sources); update them to include new changes applied by
+others to the source repository; or commit your work as
+a permanent change to the source repository.
+
+Note that @code{checkout} is used to create
+directories. The top-level directory created is always
+added to the directory where @code{checkout} is
+invoked, and usually has the same name as the specified
+module. In the case of a module alias, the created
+sub-directory may have a different name, but you can be
+sure that it will be a sub-directory, and that
+@code{checkout} will show the relative path leading to
+each file as it is extracted into your private work
+area (unless you specify the @samp{-Q} global option).
+
+The files created by @code{checkout} are created
+read-write, unless the @samp{-r} option to @sc{cvs}
+(@pxref{Global options}) is specified, the
+@code{CVSREAD} environment variable is specified
+(@pxref{Environment variables}), or a watch is in
+effect for that file (@pxref{Watches}).
+
+Note that running @code{checkout} on a directory that was already
+built by a prior @code{checkout} is also permitted.
+This is similar to specifying the @samp{-d} option
+to the @code{update} command in the sense that new
+directories that have been created in the repository
+will appear in your work area.
+However, @code{checkout} takes a module name whereas
+@code{update} takes a directory name. Also
+to use @code{checkout} this way it must be run from the
+top level directory (where you originally ran
+@code{checkout} from), so before you run
+@code{checkout} to update an existing directory, don't
+forget to change your directory to the top level
+directory.
+
+For the output produced by the @code{checkout} command
+see @ref{update output}.
+
+@menu
+* checkout options:: checkout options
+* checkout examples:: checkout examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node checkout options
+@appendixsubsec checkout options
+
+These standard options are supported by @code{checkout}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -D @var{date}
+Use the most recent revision no later than @var{date}.
+This option is sticky, and implies @samp{-P}. See
+@ref{Sticky tags}, for more information on sticky tags/dates.
+
+@item -f
+Only useful with the @samp{-D} or @samp{-r} flags. If no matching revision is
+found, retrieve the most recent revision (instead of ignoring the file).
+
+@item -k @var{kflag}
+Process keywords according to @var{kflag}. See
+@ref{Keyword substitution}.
+This option is sticky; future updates of
+this file in this working directory will use the same
+@var{kflag}. The @code{status} command can be viewed
+to see the sticky options. See @ref{Invoking CVS}, for
+more information on the @code{status} command.
+
+@item -l
+Local; run only in current working directory.
+
+@item -n
+Do not run any checkout program (as specified
+with the @samp{-o} option in the modules file;
+@pxref{modules}).
+
+@item -P
+Prune empty directories. See @ref{Moving directories}.
+
+@item -p
+Pipe files to the standard output.
+
+@item -R
+Checkout directories recursively. This option is on by default.
+
+@item -r @var{tag}[:@var{date}]
+Checkout the revision specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. This option is sticky, and implies @samp{-P}.
+See @ref{Sticky tags}, for more information on sticky tags/dates. Also,
+see @ref{Common options}.
+@end table
+
+In addition to those, you can use these special command
+options with @code{checkout}:
+
+@table @code
+@item -A
+Reset any sticky tags, dates, or @samp{-k} options.
+See @ref{Sticky tags}, for more information on sticky tags/dates.
+
+@item -c
+Copy the module file, sorted, to the standard output,
+instead of creating or modifying any files or
+directories in your working directory.
+
+@item -d @var{dir}
+Create a directory called @var{dir} for the working
+files, instead of using the module name. In general,
+using this flag is equivalent to using @samp{mkdir
+@var{dir}; cd @var{dir}} followed by the checkout
+command without the @samp{-d} flag.
+
+There is an important exception, however. It is very
+convenient when checking out a single item to have the
+output appear in a directory that doesn't contain empty
+intermediate directories. In this case @emph{only},
+@sc{cvs} tries to ``shorten'' pathnames to avoid those empty
+directories.
+
+For example, given a module @samp{foo} that contains
+the file @samp{bar.c}, the command @samp{cvs co -d dir
+foo} will create directory @samp{dir} and place
+@samp{bar.c} inside. Similarly, given a module
+@samp{bar} which has subdirectory @samp{baz} wherein
+there is a file @samp{quux.c}, the command @samp{cvs co
+-d dir bar/baz} will create directory @samp{dir} and
+place @samp{quux.c} inside.
+
+Using the @samp{-N} flag will defeat this behavior.
+Given the same module definitions above, @samp{cvs co
+-N -d dir foo} will create directories @samp{dir/foo}
+and place @samp{bar.c} inside, while @samp{cvs co -N -d
+dir bar/baz} will create directories @samp{dir/bar/baz}
+and place @samp{quux.c} inside.
+
+@item -j @var{tag}
+With two @samp{-j} options, merge changes from the
+revision specified with the first @samp{-j} option to
+the revision specified with the second @samp{j} option,
+into the working directory.
+
+With one @samp{-j} option, merge changes from the
+ancestor revision to the revision specified with the
+@samp{-j} option, into the working directory. The
+ancestor revision is the common ancestor of the
+revision which the working directory is based on, and
+the revision specified in the @samp{-j} option.
+
+In addition, each -j option can contain an optional
+date specification which, when used with branches, can
+limit the chosen revision to one within a specific
+date. An optional date is specified by adding a colon
+(:) to the tag:
+@samp{-j@var{Symbolic_Tag}:@var{Date_Specifier}}.
+
+@xref{Branching and merging}.
+
+@item -N
+Only useful together with @samp{-d @var{dir}}. With
+this option, @sc{cvs} will not ``shorten'' module paths
+in your working directory when you check out a single
+module. See the @samp{-d} flag for examples and a
+discussion.
+
+@item -s
+Like @samp{-c}, but include the status of all modules,
+and sort it by the status string. @xref{modules}, for
+info about the @samp{-s} option that is used inside the
+modules file to set the module status.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node checkout examples
+@appendixsubsec checkout examples
+
+Get a copy of the module @samp{tc}:
+
+@example
+$ cvs checkout tc
+@end example
+
+Get a copy of the module @samp{tc} as it looked one day
+ago:
+
+@example
+$ cvs checkout -D yesterday tc
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node commit
+@appendixsec commit---Check files into the repository
+@cindex commit (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: commit [-lnRf] [-m 'log_message' |
+-F file] [-r revision] [files@dots{}]
+@item
+Requires: working directory, repository.
+@item
+Changes: repository.
+@item
+Synonym: ci
+@end itemize
+
+Use @code{commit} when you want to incorporate changes
+from your working source files into the source
+repository.
+
+If you don't specify particular files to commit, all of
+the files in your working current directory are
+examined. @code{commit} is careful to change in the
+repository only those files that you have really
+changed. By default (or if you explicitly specify the
+@samp{-R} option), files in subdirectories are also
+examined and committed if they have changed; you can
+use the @samp{-l} option to limit @code{commit} to the
+current directory only.
+
+@code{commit} verifies that the selected files are up
+to date with the current revisions in the source
+repository; it will notify you, and exit without
+committing, if any of the specified files must be made
+current first with @code{update} (@pxref{update}).
+@code{commit} does not call the @code{update} command
+for you, but rather leaves that for you to do when the
+time is right.
+
+When all is well, an editor is invoked to allow you to
+enter a log message that will be written to one or more
+logging programs (@pxref{modules}, and @pxref{loginfo})
+and placed in the @sc{rcs} file inside the
+repository. This log message can be retrieved with the
+@code{log} command; see @ref{log}. You can specify the
+log message on the command line with the @samp{-m
+@var{message}} option, and thus avoid the editor invocation,
+or use the @samp{-F @var{file}} option to specify
+that the argument file contains the log message.
+
+At @code{commit}, a unique commitid is placed in the @sc{rcs}
+file inside the repository. All files committed at once
+get the same commitid. The commitid can be retrieved with
+the @code{log} and @code{status} command; see @ref{log},
+@ref{File status}.
+
+@menu
+* commit options:: commit options
+* commit examples:: commit examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node commit options
+@appendixsubsec commit options
+
+These standard options are supported by @code{commit}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -l
+Local; run only in current working directory.
+
+@item -R
+Commit directories recursively. This is on by default.
+
+@item -r @var{revision}
+Commit to @var{revision}. @var{revision} must be
+either a branch, or a revision on the main trunk that
+is higher than any existing revision number
+(@pxref{Assigning revisions}). You
+cannot commit to a specific revision on a branch.
+@c FIXME: Need xref for branch case.
+@end table
+
+@code{commit} also supports these options:
+
+@table @code
+@item -c
+Refuse to commit files unless the user has registered a valid edit on the
+file via @code{cvs edit}. This is most useful when @samp{commit -c}
+and @samp{edit -c} have been placed in all @file{.cvsrc} files.
+A commit can be forced anyways by either regestering an edit retroactively
+via @code{cvs edit} (no changes to the file will be lost) or using the
+@code{-f} option to commit. Support for @code{commit -c} requires both
+client and a server versions 1.12.10 or greater.
+
+@item -F @var{file}
+Read the log message from @var{file}, instead
+of invoking an editor.
+
+@item -f
+Note that this is not the standard behavior of
+the @samp{-f} option as defined in @ref{Common options}.
+
+Force @sc{cvs} to commit a new revision even if you haven't
+made any changes to the file. As of @sc{cvs} version 1.12.10,
+it also causes the @code{-c} option to be ignored. If the current revision
+of @var{file} is 1.7, then the following two commands
+are equivalent:
+
+@example
+$ cvs commit -f @var{file}
+$ cvs commit -r 1.8 @var{file}
+@end example
+
+@c This is odd, but it's how CVS has worked for some
+@c time.
+The @samp{-f} option disables recursion (i.e., it
+implies @samp{-l}). To force @sc{cvs} to commit a new
+revision for all files in all subdirectories, you must
+use @samp{-f -R}.
+
+@item -m @var{message}
+Use @var{message} as the log message, instead of
+invoking an editor.
+@end table
+
+@need 2000
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node commit examples
+@appendixsubsec commit examples
+
+@c FIXME: this material wants to be somewhere
+@c in "Branching and merging".
+
+@appendixsubsubsec Committing to a branch
+
+You can commit to a branch revision (one that has an
+even number of dots) with the @samp{-r} option. To
+create a branch revision, use the @samp{-b} option
+of the @code{rtag} or @code{tag} commands
+(@pxref{Branching and merging}). Then, either @code{checkout} or
+@code{update} can be used to base your sources on the
+newly created branch. From that point on, all
+@code{commit} changes made within these working sources
+will be automatically added to a branch revision,
+thereby not disturbing main-line development in any
+way. For example, if you had to create a patch to the
+1.2 version of the product, even though the 2.0 version
+is already under development, you might do:
+
+@example
+$ cvs rtag -b -r FCS1_2 FCS1_2_Patch product_module
+$ cvs checkout -r FCS1_2_Patch product_module
+$ cd product_module
+[[ hack away ]]
+$ cvs commit
+@end example
+
+@noindent
+This works automatically since the @samp{-r} option is
+sticky.
+
+@appendixsubsubsec Creating the branch after editing
+
+Say you have been working on some extremely
+experimental software, based on whatever revision you
+happened to checkout last week. If others in your
+group would like to work on this software with you, but
+without disturbing main-line development, you could
+commit your change to a new branch. Others can then
+checkout your experimental stuff and utilize the full
+benefit of @sc{cvs} conflict resolution. The scenario might
+look like:
+
+@c FIXME: Should we be recommending tagging the branchpoint?
+@example
+[[ hacked sources are present ]]
+$ cvs tag -b EXPR1
+$ cvs update -r EXPR1
+$ cvs commit
+@end example
+
+The @code{update} command will make the @samp{-r
+EXPR1} option sticky on all files. Note that your
+changes to the files will never be removed by the
+@code{update} command. The @code{commit} will
+automatically commit to the correct branch, because the
+@samp{-r} is sticky. You could also do like this:
+
+@c FIXME: Should we be recommending tagging the branchpoint?
+@example
+[[ hacked sources are present ]]
+$ cvs tag -b EXPR1
+$ cvs commit -r EXPR1
+@end example
+
+@noindent
+but then, only those files that were changed by you
+will have the @samp{-r EXPR1} sticky flag. If you hack
+away, and commit without specifying the @samp{-r EXPR1}
+flag, some files may accidentally end up on the main
+trunk.
+
+To work with you on the experimental change, others
+would simply do
+
+@example
+$ cvs checkout -r EXPR1 whatever_module
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node diff
+@appendixsec diff---Show differences between revisions
+@cindex diff (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: diff [-lR] [-k kflag] [format_options] [(-r rev1[:date1] | -D date1) [-r rev2[:date2] | -D date2]] [files@dots{}]
+@item
+Requires: working directory, repository.
+@item
+Changes: nothing.
+@end itemize
+
+The @code{diff} command is used to compare different
+revisions of files. The default action is to compare
+your working files with the revisions they were based
+on, and report any differences that are found.
+
+If any file names are given, only those files are
+compared. If any directories are given, all files
+under them will be compared.
+
+The exit status for diff is different than for other
+@sc{cvs} commands; for details @ref{Exit status}.
+
+@menu
+* diff options:: diff options
+* diff examples:: diff examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node diff options
+@appendixsubsec diff options
+
+These standard options are supported by @code{diff}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -D @var{date}
+Use the most recent revision no later than @var{date}.
+See @samp{-r} for how this affects the comparison.
+
+@item -k @var{kflag}
+Process keywords according to @var{kflag}. See
+@ref{Keyword substitution}.
+
+@item -l
+Local; run only in current working directory.
+
+@item -R
+Examine directories recursively. This option is on by
+default.
+
+@item -r @var{tag}[:@var{date}]
+Compare with revision specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. Zero, one or two
+@samp{-r} options can be present. With no @samp{-r}
+option, the working file will be compared with the
+revision it was based on. With one @samp{-r}, that
+revision will be compared to your current working file.
+With two @samp{-r} options those two revisions will be
+compared (and your working file will not affect the
+outcome in any way).
+@c We should be a lot more explicit, with examples,
+@c about the difference between "cvs diff" and "cvs
+@c diff -r HEAD". This often confuses new users.
+
+One or both @samp{-r} options can be replaced by a
+@samp{-D @var{date}} option, described above.
+@end table
+
+@c Conceptually, this is a disaster. There are 3
+@c zillion diff formats that we support via the diff
+@c library. It is not obvious to me that we should
+@c document them all. Maybe just the most common ones
+@c like -c and -u, and think about phasing out the
+@c obscure ones.
+@c FIXCVS: also should be a way to specify an external
+@c diff program (which can be different for different
+@c file types) and pass through
+@c arbitrary options, so that the user can do
+@c "--pass=-Z --pass=foo" or something even if CVS
+@c doesn't know about the "-Z foo" option to diff.
+@c This would fit nicely with deprecating/eliminating
+@c the obscure options of the diff library, because it
+@c would let people specify an external GNU diff if
+@c they are into that sort of thing.
+The following options specify the format of the
+output. They have the same meaning as in GNU diff.
+Most options have two equivalent names, one of which is a single letter
+preceded by @samp{-}, and the other of which is a long name preceded by
+@samp{--}.
+
+@table @samp
+@item -@var{lines}
+Show @var{lines} (an integer) lines of context. This option does not
+specify an output format by itself; it has no effect unless it is
+combined with @samp{-c} or @samp{-u}. This option is obsolete. For proper
+operation, @code{patch} typically needs at least two lines of context.
+
+@item -a
+Treat all files as text and compare them line-by-line, even if they
+do not seem to be text.
+
+@item -b
+Ignore trailing white space and consider all other sequences of one or
+more white space characters to be equivalent.
+
+@item -B
+Ignore changes that just insert or delete blank lines.
+
+@item --binary
+Read and write data in binary mode.
+
+@item --brief
+Report only whether the files differ, not the details of the
+differences.
+
+@item -c
+Use the context output format.
+
+@item -C @var{lines}
+@itemx --context@r{[}=@var{lines}@r{]}
+Use the context output format, showing @var{lines} (an integer) lines of
+context, or three if @var{lines} is not given.
+For proper operation, @code{patch} typically needs at least two lines of
+context.
+
+@item --changed-group-format=@var{format}
+Use @var{format} to output a line group containing differing lines from
+both files in if-then-else format. @xref{Line group formats}.
+
+@item -d
+Change the algorithm to perhaps find a smaller set of changes. This makes
+@code{diff} slower (sometimes much slower).
+
+@item -e
+@itemx --ed
+Make output that is a valid @code{ed} script.
+
+@item --expand-tabs
+Expand tabs to spaces in the output, to preserve the alignment of tabs
+in the input files.
+
+@item -f
+Make output that looks vaguely like an @code{ed} script but has changes
+in the order they appear in the file.
+
+@item -F @var{regexp}
+In context and unified format, for each hunk of differences, show some
+of the last preceding line that matches @var{regexp}.
+
+@item --forward-ed
+Make output that looks vaguely like an @code{ed} script but has changes
+in the order they appear in the file.
+
+@item -H
+Use heuristics to speed handling of large files that have numerous
+scattered small changes.
+
+@item --horizon-lines=@var{lines}
+Do not discard the last @var{lines} lines of the common prefix
+and the first @var{lines} lines of the common suffix.
+
+@item -i
+Ignore changes in case; consider upper- and lower-case letters
+equivalent.
+
+@item -I @var{regexp}
+Ignore changes that just insert or delete lines that match @var{regexp}.
+
+@item --ifdef=@var{name}
+Make merged if-then-else output using @var{name}.
+
+@item --ignore-all-space
+Ignore white space when comparing lines.
+
+@item --ignore-blank-lines
+Ignore changes that just insert or delete blank lines.
+
+@item --ignore-case
+Ignore changes in case; consider upper- and lower-case to be the same.
+
+@item --ignore-matching-lines=@var{regexp}
+Ignore changes that just insert or delete lines that match @var{regexp}.
+
+@item --ignore-space-change
+Ignore trailing white space and consider all other sequences of one or
+more white space characters to be equivalent.
+
+@item --initial-tab
+Output a tab rather than a space before the text of a line in normal or
+context format. This causes the alignment of tabs in the line to look
+normal.
+
+@item -L @var{label}
+Use @var{label} instead of the file name in the context format
+and unified format headers.
+
+@item --label=@var{label}
+Use @var{label} instead of the file name in the context format
+and unified format headers.
+
+@item --left-column
+Print only the left column of two common lines in side by side format.
+
+@item --line-format=@var{format}
+Use @var{format} to output all input lines in if-then-else format.
+@xref{Line formats}.
+
+@item --minimal
+Change the algorithm to perhaps find a smaller set of changes. This
+makes @code{diff} slower (sometimes much slower).
+
+@item -n
+Output RCS-format diffs; like @samp{-f} except that each command
+specifies the number of lines affected.
+
+@item -N
+@itemx --new-file
+In directory comparison, if a file is found in only one directory,
+treat it as present but empty in the other directory.
+
+@item --new-group-format=@var{format}
+Use @var{format} to output a group of lines taken from just the second
+file in if-then-else format. @xref{Line group formats}.
+
+@item --new-line-format=@var{format}
+Use @var{format} to output a line taken from just the second file in
+if-then-else format. @xref{Line formats}.
+
+@item --old-group-format=@var{format}
+Use @var{format} to output a group of lines taken from just the first
+file in if-then-else format. @xref{Line group formats}.
+
+@item --old-line-format=@var{format}
+Use @var{format} to output a line taken from just the first file in
+if-then-else format. @xref{Line formats}.
+
+@item -p
+Show which C function each change is in.
+
+@item --rcs
+Output RCS-format diffs; like @samp{-f} except that each command
+specifies the number of lines affected.
+
+@item --report-identical-files
+@itemx -s
+Report when two files are the same.
+
+@item --show-c-function
+Show which C function each change is in.
+
+@item --show-function-line=@var{regexp}
+In context and unified format, for each hunk of differences, show some
+of the last preceding line that matches @var{regexp}.
+
+@item --side-by-side
+Use the side by side output format.
+
+@item --speed-large-files
+Use heuristics to speed handling of large files that have numerous
+scattered small changes.
+
+@item --suppress-common-lines
+Do not print common lines in side by side format.
+
+@item -t
+Expand tabs to spaces in the output, to preserve the alignment of tabs
+in the input files.
+
+@item -T
+Output a tab rather than a space before the text of a line in normal or
+context format. This causes the alignment of tabs in the line to look
+normal.
+
+@item --text
+Treat all files as text and compare them line-by-line, even if they
+do not appear to be text.
+
+@item -u
+Use the unified output format.
+
+@item --unchanged-group-format=@var{format}
+Use @var{format} to output a group of common lines taken from both files
+in if-then-else format. @xref{Line group formats}.
+
+@item --unchanged-line-format=@var{format}
+Use @var{format} to output a line common to both files in if-then-else
+format. @xref{Line formats}.
+
+@item -U @var{lines}
+@itemx --unified@r{[}=@var{lines}@r{]}
+Use the unified output format, showing @var{lines} (an integer) lines of
+context, or three if @var{lines} is not given.
+For proper operation, @code{patch} typically needs at least two lines of
+context.
+
+@item -w
+Ignore white space when comparing lines.
+
+@item -W @var{columns}
+@itemx --width=@var{columns}
+Use an output width of @var{columns} in side by side format.
+
+@item -y
+Use the side by side output format.
+@end table
+
+@menu
+* Line group formats:: Line group formats
+* Line formats:: Line formats
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node Line group formats
+@appendixsubsubsec Line group formats
+
+Line group formats let you specify formats suitable for many
+applications that allow if-then-else input, including programming
+languages and text formatting languages. A line group format specifies
+the output format for a contiguous group of similar lines.
+
+For example, the following command compares the TeX file @file{myfile}
+with the original version from the repository,
+and outputs a merged file in which old regions are
+surrounded by @samp{\begin@{em@}}-@samp{\end@{em@}} lines, and new
+regions are surrounded by @samp{\begin@{bf@}}-@samp{\end@{bf@}} lines.
+
+@example
+cvs diff \
+ --old-group-format='\begin@{em@}
+%<\end@{em@}
+' \
+ --new-group-format='\begin@{bf@}
+%>\end@{bf@}
+' \
+ myfile
+@end example
+
+The following command is equivalent to the above example, but it is a
+little more verbose, because it spells out the default line group formats.
+
+@example
+cvs diff \
+ --old-group-format='\begin@{em@}
+%<\end@{em@}
+' \
+ --new-group-format='\begin@{bf@}
+%>\end@{bf@}
+' \
+ --unchanged-group-format='%=' \
+ --changed-group-format='\begin@{em@}
+%<\end@{em@}
+\begin@{bf@}
+%>\end@{bf@}
+' \
+ myfile
+@end example
+
+Here is a more advanced example, which outputs a diff listing with
+headers containing line numbers in a ``plain English'' style.
+
+@example
+cvs diff \
+ --unchanged-group-format='' \
+ --old-group-format='-------- %dn line%(n=1?:s) deleted at %df:
+%<' \
+ --new-group-format='-------- %dN line%(N=1?:s) added after %de:
+%>' \
+ --changed-group-format='-------- %dn line%(n=1?:s) changed at %df:
+%<-------- to:
+%>' \
+ myfile
+@end example
+
+To specify a line group format, use one of the options
+listed below. You can specify up to four line group formats, one for
+each kind of line group. You should quote @var{format}, because it
+typically contains shell metacharacters.
+
+@table @samp
+@item --old-group-format=@var{format}
+These line groups are hunks containing only lines from the first file.
+The default old group format is the same as the changed group format if
+it is specified; otherwise it is a format that outputs the line group as-is.
+
+@item --new-group-format=@var{format}
+These line groups are hunks containing only lines from the second
+file. The default new group format is same as the changed group
+format if it is specified; otherwise it is a format that outputs the
+line group as-is.
+
+@item --changed-group-format=@var{format}
+These line groups are hunks containing lines from both files. The
+default changed group format is the concatenation of the old and new
+group formats.
+
+@item --unchanged-group-format=@var{format}
+These line groups contain lines common to both files. The default
+unchanged group format is a format that outputs the line group as-is.
+@end table
+
+In a line group format, ordinary characters represent themselves;
+conversion specifications start with @samp{%} and have one of the
+following forms.
+
+@table @samp
+@item %<
+stands for the lines from the first file, including the trailing newline.
+Each line is formatted according to the old line format (@pxref{Line formats}).
+
+@item %>
+stands for the lines from the second file, including the trailing newline.
+Each line is formatted according to the new line format.
+
+@item %=
+stands for the lines common to both files, including the trailing newline.
+Each line is formatted according to the unchanged line format.
+
+@item %%
+stands for @samp{%}.
+
+@item %c'@var{C}'
+where @var{C} is a single character, stands for @var{C}.
+@var{C} may not be a backslash or an apostrophe.
+For example, @samp{%c':'} stands for a colon, even inside
+the then-part of an if-then-else format, which a colon would
+normally terminate.
+
+@item %c'\@var{O}'
+where @var{O} is a string of 1, 2, or 3 octal digits,
+stands for the character with octal code @var{O}.
+For example, @samp{%c'\0'} stands for a null character.
+
+@item @var{F}@var{n}
+where @var{F} is a @code{printf} conversion specification and @var{n} is one
+of the following letters, stands for @var{n}'s value formatted with @var{F}.
+
+@table @samp
+@item e
+The line number of the line just before the group in the old file.
+
+@item f
+The line number of the first line in the group in the old file;
+equals @var{e} + 1.
+
+@item l
+The line number of the last line in the group in the old file.
+
+@item m
+The line number of the line just after the group in the old file;
+equals @var{l} + 1.
+
+@item n
+The number of lines in the group in the old file; equals @var{l} - @var{f} + 1.
+
+@item E, F, L, M, N
+Likewise, for lines in the new file.
+
+@end table
+
+The @code{printf} conversion specification can be @samp{%d},
+@samp{%o}, @samp{%x}, or @samp{%X}, specifying decimal, octal,
+lower case hexadecimal, or upper case hexadecimal output
+respectively. After the @samp{%} the following options can appear in
+sequence: a @samp{-} specifying left-justification; an integer
+specifying the minimum field width; and a period followed by an
+optional integer specifying the minimum number of digits.
+For example, @samp{%5dN} prints the number of new lines in the group
+in a field of width 5 characters, using the @code{printf} format @code{"%5d"}.
+
+@item (@var{A}=@var{B}?@var{T}:@var{E})
+If @var{A} equals @var{B} then @var{T} else @var{E}.
+@var{A} and @var{B} are each either a decimal constant
+or a single letter interpreted as above.
+This format spec is equivalent to @var{T} if
+@var{A}'s value equals @var{B}'s; otherwise it is equivalent to @var{E}.
+
+For example, @samp{%(N=0?no:%dN) line%(N=1?:s)} is equivalent to
+@samp{no lines} if @var{N} (the number of lines in the group in the
+new file) is 0, to @samp{1 line} if @var{N} is 1, and to @samp{%dN lines}
+otherwise.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node Line formats
+@appendixsubsubsec Line formats
+
+Line formats control how each line taken from an input file is
+output as part of a line group in if-then-else format.
+
+For example, the following command outputs text with a one-column
+change indicator to the left of the text. The first column of output
+is @samp{-} for deleted lines, @samp{|} for added lines, and a space
+for unchanged lines. The formats contain newline characters where
+newlines are desired on output.
+
+@example
+cvs diff \
+ --old-line-format='-%l
+' \
+ --new-line-format='|%l
+' \
+ --unchanged-line-format=' %l
+' \
+ myfile
+@end example
+
+To specify a line format, use one of the following options. You should
+quote @var{format}, since it often contains shell metacharacters.
+
+@table @samp
+@item --old-line-format=@var{format}
+formats lines just from the first file.
+
+@item --new-line-format=@var{format}
+formats lines just from the second file.
+
+@item --unchanged-line-format=@var{format}
+formats lines common to both files.
+
+@item --line-format=@var{format}
+formats all lines; in effect, it sets all three above options simultaneously.
+@end table
+
+In a line format, ordinary characters represent themselves;
+conversion specifications start with @samp{%} and have one of the
+following forms.
+
+@table @samp
+@item %l
+stands for the contents of the line, not counting its trailing
+newline (if any). This format ignores whether the line is incomplete.
+
+@item %L
+stands for the contents of the line, including its trailing newline
+(if any). If a line is incomplete, this format preserves its
+incompleteness.
+
+@item %%
+stands for @samp{%}.
+
+@item %c'@var{C}'
+where @var{C} is a single character, stands for @var{C}.
+@var{C} may not be a backslash or an apostrophe.
+For example, @samp{%c':'} stands for a colon.
+
+@item %c'\@var{O}'
+where @var{O} is a string of 1, 2, or 3 octal digits,
+stands for the character with octal code @var{O}.
+For example, @samp{%c'\0'} stands for a null character.
+
+@item @var{F}n
+where @var{F} is a @code{printf} conversion specification,
+stands for the line number formatted with @var{F}.
+For example, @samp{%.5dn} prints the line number using the
+@code{printf} format @code{"%.5d"}. @xref{Line group formats}, for
+more about printf conversion specifications.
+
+@end table
+
+The default line format is @samp{%l} followed by a newline character.
+
+If the input contains tab characters and it is important that they line
+up on output, you should ensure that @samp{%l} or @samp{%L} in a line
+format is just after a tab stop (e.g.@: by preceding @samp{%l} or
+@samp{%L} with a tab character), or you should use the @samp{-t} or
+@samp{--expand-tabs} option.
+
+Taken together, the line and line group formats let you specify many
+different formats. For example, the following command uses a format
+similar to @code{diff}'s normal format. You can tailor this command
+to get fine control over @code{diff}'s output.
+
+@example
+cvs diff \
+ --old-line-format='< %l
+' \
+ --new-line-format='> %l
+' \
+ --old-group-format='%df%(f=l?:,%dl)d%dE
+%<' \
+ --new-group-format='%dea%dF%(F=L?:,%dL)
+%>' \
+ --changed-group-format='%df%(f=l?:,%dl)c%dF%(F=L?:,%dL)
+%<---
+%>' \
+ --unchanged-group-format='' \
+ myfile
+@end example
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node diff examples
+@appendixsubsec diff examples
+
+The following line produces a Unidiff (@samp{-u} flag)
+between revision 1.14 and 1.19 of
+@file{backend.c}. Due to the @samp{-kk} flag no
+keywords are substituted, so differences that only depend
+on keyword substitution are ignored.
+
+@example
+$ cvs diff -kk -u -r 1.14 -r 1.19 backend.c
+@end example
+
+Suppose the experimental branch EXPR1 was based on a
+set of files tagged RELEASE_1_0. To see what has
+happened on that branch, the following can be used:
+
+@example
+$ cvs diff -r RELEASE_1_0 -r EXPR1
+@end example
+
+A command like this can be used to produce a context
+diff between two releases:
+
+@example
+$ cvs diff -c -r RELEASE_1_0 -r RELEASE_1_1 > diffs
+@end example
+
+If you are maintaining ChangeLogs, a command like the following
+just before you commit your changes may help you write
+the ChangeLog entry. All local modifications that have
+not yet been committed will be printed.
+
+@example
+$ cvs diff -u | less
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node export
+@appendixsec export---Export sources from CVS, similar to checkout
+@cindex export (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: export [-flNnR] (-r rev[:date] | -D date) [-k subst] [-d dir] module@dots{}
+@item
+Requires: repository.
+@item
+Changes: current directory.
+@end itemize
+
+This command is a variant of @code{checkout}; use it
+when you want a copy of the source for module without
+the @sc{cvs} administrative directories. For example, you
+might use @code{export} to prepare source for shipment
+off-site. This command requires that you specify a
+date or tag (with @samp{-D} or @samp{-r}), so that you
+can count on reproducing the source you ship to others
+(and thus it always prunes empty directories).
+
+One often would like to use @samp{-kv} with @code{cvs
+export}. This causes any keywords to be
+expanded such that an import done at some other site
+will not lose the keyword revision information. But be
+aware that doesn't handle an export containing binary
+files correctly. Also be aware that after having used
+@samp{-kv}, one can no longer use the @code{ident}
+command (which is part of the @sc{rcs} suite---see
+ident(1)) which looks for keyword strings. If
+you want to be able to use @code{ident} you must not
+use @samp{-kv}.
+
+@menu
+* export options:: export options
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node export options
+@appendixsubsec export options
+
+These standard options are supported by @code{export}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -D @var{date}
+Use the most recent revision no later than @var{date}.
+
+@item -f
+If no matching revision is found, retrieve the most
+recent revision (instead of ignoring the file).
+
+@item -l
+Local; run only in current working directory.
+
+@item -n
+Do not run any checkout program.
+
+@item -R
+Export directories recursively. This is on by default.
+
+@item -r @var{tag}[:@var{date}]
+Export the revision specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Common options}.
+@end table
+
+In addition, these options (that are common to
+@code{checkout} and @code{export}) are also supported:
+
+@table @code
+@item -d @var{dir}
+Create a directory called @var{dir} for the working
+files, instead of using the module name.
+@xref{checkout options}, for complete details on how
+@sc{cvs} handles this flag.
+
+@item -k @var{subst}
+Set keyword expansion mode (@pxref{Substitution modes}).
+
+@item -N
+Only useful together with @samp{-d @var{dir}}.
+@xref{checkout options}, for complete details on how
+@sc{cvs} handles this flag.
+@end table
+
+@ignore
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@c @node export examples
+@appendixsubsec export examples
+
+Contributed examples are gratefully accepted.
+@c -- Examples here!!
+@end ignore
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node history
+@appendixsec history---Show status of files and users
+@cindex history (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: history [-report] [-flags] [-options args] [files@dots{}]
+@item
+Requires: the file @file{$CVSROOT/CVSROOT/history}
+@item
+Changes: nothing.
+@end itemize
+
+@sc{cvs} can keep a history log that tracks each use of most @sc{cvs}
+commands. You can use @code{history} to display this information in
+various formats.
+
+To enable logging, the @samp{LogHistory} config option must be set to
+some value other than the empty string and the history file specified by
+the @samp{HistoryLogPath} option must be writable by all users who may run
+the @sc{cvs} executable (@pxref{config}).
+
+To enable the @code{history} command, logging must be enabled as above and
+the @samp{HistorySearchPath} config option (@pxref{config}) must be set to
+specify some number of the history logs created thereby and these files must
+be readable by each user who might run the @code{history} command.
+
+Creating a repository via the @code{cvs init} command will enable logging of
+all possible events to a single history log file
+(@file{$CVSROOT/CVSROOT/history}) with read and write permissions for all
+users (@pxref{Creating a repository}).
+
+@strong{Note: @code{history} uses @samp{-f}, @samp{-l},
+@samp{-n}, and @samp{-p} in ways that conflict with the
+normal use inside @sc{cvs} (@pxref{Common options}).}
+
+@menu
+* history options:: history options
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node history options
+@appendixsubsec history options
+
+Several options (shown above as @samp{-report}) control what
+kind of report is generated:
+
+@table @code
+@item -c
+Report on each time commit was used (i.e., each time
+the repository was modified).
+
+@item -e
+Everything (all record types). Equivalent to
+specifying @samp{-x} with all record types. Of course,
+@samp{-e} will also include record types which are
+added in a future version of @sc{cvs}; if you are
+writing a script which can only handle certain record
+types, you'll want to specify @samp{-x}.
+
+@item -m @var{module}
+Report on a particular module. (You can meaningfully
+use @samp{-m} more than once on the command line.)
+
+@item -o
+Report on checked-out modules. This is the default report type.
+
+@item -T
+Report on all tags.
+
+@item -x @var{type}
+Extract a particular set of record types @var{type} from the @sc{cvs}
+history. The types are indicated by single letters,
+which you may specify in combination.
+
+Certain commands have a single record type:
+
+@table @code
+@item F
+release
+@item O
+checkout
+@item E
+export
+@item T
+rtag
+@end table
+
+@noindent
+One of five record types may result from an update:
+
+@table @code
+@item C
+A merge was necessary but collisions were
+detected (requiring manual merging).
+@item G
+A merge was necessary and it succeeded.
+@item U
+A working file was copied from the repository.
+@item P
+A working file was patched to match the repository.
+@item W
+The working copy of a file was deleted during
+update (because it was gone from the repository).
+@end table
+
+@noindent
+One of three record types results from commit:
+
+@table @code
+@item A
+A file was added for the first time.
+@item M
+A file was modified.
+@item R
+A file was removed.
+@end table
+@end table
+
+The options shown as @samp{-flags} constrain or expand
+the report without requiring option arguments:
+
+@table @code
+@item -a
+Show data for all users (the default is to show data
+only for the user executing @code{history}).
+
+@item -l
+Show last modification only.
+
+@item -w
+Show only the records for modifications done from the
+same working directory where @code{history} is
+executing.
+@end table
+
+The options shown as @samp{-options @var{args}} constrain the report
+based on an argument:
+
+@table @code
+@item -b @var{str}
+Show data back to a record containing the string
+@var{str} in either the module name, the file name, or
+the repository path.
+
+@item -D @var{date}
+Show data since @var{date}. This is slightly different
+from the normal use of @samp{-D @var{date}}, which
+selects the newest revision older than @var{date}.
+
+@item -f @var{file}
+Show data for a particular file
+(you can specify several @samp{-f} options on the same command line).
+This is equivalent to specifying the file on the command line.
+
+@item -n @var{module}
+Show data for a particular module
+(you can specify several @samp{-n} options on the same command line).
+
+@item -p @var{repository}
+Show data for a particular source repository (you
+can specify several @samp{-p} options on the same command
+line).
+
+@item -r @var{rev}
+Show records referring to revisions since the revision
+or tag named @var{rev} appears in individual @sc{rcs}
+files. Each @sc{rcs} file is searched for the revision or
+tag.
+
+@item -t @var{tag}
+Show records since tag @var{tag} was last added to the
+history file. This differs from the @samp{-r} flag
+above in that it reads only the history file, not the
+@sc{rcs} files, and is much faster.
+
+@item -u @var{name}
+Show records for user @var{name}.
+
+@item -z @var{timezone}
+Show times in the selected records using the specified
+time zone instead of UTC.
+@end table
+
+@ignore
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@c @node history examples
+@appendixsubsec history examples
+
+Contributed examples will gratefully be accepted.
+@c -- Examples here!
+@end ignore
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node import
+@appendixsec import---Import sources into CVS, using vendor branches
+@cindex import (subcommand)
+
+@c FIXME: This node is way too long for one which has subnodes.
+
+@itemize @bullet
+@item
+Synopsis: import [-options] repository vendortag releasetag@dots{}
+@item
+Requires: Repository, source distribution directory.
+@item
+Changes: repository.
+@end itemize
+
+Use @code{import} to incorporate an entire source
+distribution from an outside source (e.g., a source
+vendor) into your source repository directory. You can
+use this command both for initial creation of a
+repository, and for wholesale updates to the module
+from the outside source. @xref{Tracking sources}, for
+a discussion on this subject.
+
+The @var{repository} argument gives a directory name
+(or a path to a directory) under the @sc{cvs} root directory
+for repositories; if the directory did not exist,
+import creates it.
+
+When you use import for updates to source that has been
+modified in your source repository (since a prior
+import), it will notify you of any files that conflict
+in the two branches of development; use @samp{checkout
+-j} to reconcile the differences, as import instructs
+you to do.
+
+If @sc{cvs} decides a file should be ignored
+(@pxref{cvsignore}), it does not import it and prints
+@samp{I } followed by the filename (@pxref{import output}, for a
+complete description of the output).
+
+If the file @file{$CVSROOT/CVSROOT/cvswrappers} exists,
+any file whose names match the specifications in that
+file will be treated as packages and the appropriate
+filtering will be performed on the file/directory
+before being imported. @xref{Wrappers}.
+
+The outside source is saved in a first-level
+branch, by default 1.1.1. Updates are leaves of this
+branch; for example, files from the first imported
+collection of source will be revision 1.1.1.1, then
+files from the first imported update will be revision
+1.1.1.2, and so on.
+
+At least three arguments are required.
+@var{repository} is needed to identify the collection
+of source. @var{vendortag} is a tag for the entire
+branch (e.g., for 1.1.1). You must also specify at
+least one @var{releasetag} to uniquely identify the files at
+the leaves created each time you execute @code{import}. The
+@var{releasetag} should be new, not previously existing in the
+repository file, and uniquely identify the imported release,
+
+@c I'm not completely sure this belongs here. But
+@c we need to say it _somewhere_ reasonably obvious; it
+@c is a common misconception among people first learning CVS
+Note that @code{import} does @emph{not} change the
+directory in which you invoke it. In particular, it
+does not set up that directory as a @sc{cvs} working
+directory; if you want to work with the sources import
+them first and then check them out into a different
+directory (@pxref{Getting the source}).
+
+@menu
+* import options:: import options
+* import output:: import output
+* import examples:: import examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node import options
+@appendixsubsec import options
+
+This standard option is supported by @code{import}
+(@pxref{Common options}, for a complete description):
+
+@table @code
+@item -m @var{message}
+Use @var{message} as log information, instead of
+invoking an editor.
+@end table
+
+There are the following additional special options.
+
+@table @code
+@item -b @var{branch}
+See @ref{Multiple vendor branches}.
+
+@item -k @var{subst}
+Indicate the keyword expansion mode desired. This
+setting will apply to all files created during the
+import, but not to any files that previously existed in
+the repository. See @ref{Substitution modes}, for a
+list of valid @samp{-k} settings.
+
+@item -I @var{name}
+Specify file names that should be ignored during
+import. You can use this option repeatedly. To avoid
+ignoring any files at all (even those ignored by
+default), specify `-I !'.
+
+@var{name} can be a file name pattern of the same type
+that you can specify in the @file{.cvsignore} file.
+@xref{cvsignore}.
+@c -- Is this really true?
+
+@item -W @var{spec}
+Specify file names that should be filtered during
+import. You can use this option repeatedly.
+
+@var{spec} can be a file name pattern of the same type
+that you can specify in the @file{.cvswrappers}
+file. @xref{Wrappers}.
+
+@item -X
+Modify the algorithm used by @sc{cvs} when importing new files
+so that new files do not immediately appear on the main trunk.
+
+Specifically, this flag causes @sc{cvs} to mark new files as
+if they were deleted on the main trunk, by taking the following
+steps for each file in addition to those normally taken on import:
+creating a new revision on the main trunk indicating that
+the new file is @code{dead}, resetting the new file's default branch,
+and placing the file in the Attic (@pxref{Attic}) directory.
+
+Use of this option can be forced on a repository-wide basis
+by setting the @samp{ImportNewFilesToVendorBranchOnly} option in
+CVSROOT/config (@pxref{config}).
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node import output
+@appendixsubsec import output
+
+@code{import} keeps you informed of its progress by printing a line
+for each file, preceded by one character indicating the status of the file:
+
+@table @code
+@item U @var{file}
+The file already exists in the repository and has not been locally
+modified; a new revision has been created (if necessary).
+
+@item N @var{file}
+The file is a new file which has been added to the repository.
+
+@item C @var{file}
+The file already exists in the repository but has been locally modified;
+you will have to merge the changes.
+
+@item I @var{file}
+The file is being ignored (@pxref{cvsignore}).
+
+@cindex Symbolic link, importing
+@cindex Link, symbolic, importing
+@c FIXME: also (somewhere else) probably
+@c should be documenting what happens if you "cvs add"
+@c a symbolic link. Also maybe what happens if
+@c you manually create symbolic links within the
+@c repository (? - not sure why we'd want to suggest
+@c doing that).
+@item L @var{file}
+The file is a symbolic link; @code{cvs import} ignores symbolic links.
+People periodically suggest that this behavior should
+be changed, but if there is a consensus on what it
+should be changed to, it is not apparent.
+(Various options in the @file{modules} file can be used
+to recreate symbolic links on checkout, update, etc.;
+@pxref{modules}.)
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node import examples
+@appendixsubsec import examples
+
+See @ref{Tracking sources}, and @ref{From files}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node log
+@appendixsec log---Print out log information for files
+@cindex log (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: log [options] [files@dots{}]
+@item
+Requires: repository, working directory.
+@item
+Changes: nothing.
+@end itemize
+
+Display log information for files. @code{log} used to
+call the @sc{rcs} utility @code{rlog}. Although this
+is no longer true in the current sources, this history
+determines the format of the output and the options,
+which are not quite in the style of the other @sc{cvs}
+commands.
+
+@cindex Timezone, in output
+@cindex Zone, time, in output
+The output includes the location of the @sc{rcs} file,
+the @dfn{head} revision (the latest revision on the
+trunk), all symbolic names (tags) and some other
+things. For each revision, the revision number, the
+date, the author, the number of lines added/deleted, the commitid
+and the log message are printed. All dates are displayed
+in local time at the client. This is typically specified in
+the @code{$TZ} environment variable, which can be set to
+govern how @code{log} displays dates.
+
+@strong{Note: @code{log} uses @samp{-R} in a way that conflicts
+with the normal use inside @sc{cvs} (@pxref{Common options}).}
+
+@menu
+* log options:: log options
+* log examples:: log examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node log options
+@appendixsubsec log options
+
+By default, @code{log} prints all information that is
+available. All other options restrict the output. Note that the revision
+selection options (@code{-d}, @code{-r}, @code{-s}, and @code{-w}) have no
+effect, other than possibly causing a search for files in Attic directories,
+when used in conjunction with the options that restrict the output to only
+@code{log} header fields (@code{-b}, @code{-h}, @code{-R}, and @code{-t})
+unless the @code{-S} option is also specified.
+
+@table @code
+@item -b
+Print information about the revisions on the default
+branch, normally the highest branch on the trunk.
+
+@item -d @var{dates}
+Print information about revisions with a checkin
+date/time in the range given by the
+semicolon-separated list of dates. The date formats
+accepted are those accepted by the @samp{-D} option to
+many other @sc{cvs} commands (@pxref{Common options}).
+Dates can be combined into ranges as follows:
+
+@c Should we be thinking about accepting ISO8601
+@c ranges? For example "1972-09-10/1972-09-12".
+@table @code
+@item @var{d1}<@var{d2}
+@itemx @var{d2}>@var{d1}
+Select the revisions that were deposited between
+@var{d1} and @var{d2}.
+
+@item <@var{d}
+@itemx @var{d}>
+Select all revisions dated @var{d} or earlier.
+
+@item @var{d}<
+@itemx >@var{d}
+Select all revisions dated @var{d} or later.
+
+@item @var{d}
+Select the single, latest revision dated @var{d} or
+earlier.
+@end table
+
+The @samp{>} or @samp{<} characters may be followed by
+@samp{=} to indicate an inclusive range rather than an
+exclusive one.
+
+Note that the separator is a semicolon (;).
+
+@item -h
+Print only the name of the @sc{rcs} file, name
+of the file in the working directory, head,
+default branch, access list, locks, symbolic names, and
+suffix.
+
+@item -l
+Local; run only in current working directory. (Default
+is to run recursively).
+
+@item -N
+Do not print the list of tags for this file. This
+option can be very useful when your site uses a lot of
+tags, so rather than "more"'ing over 3 pages of tag
+information, the log information is presented without
+tags at all.
+
+@item -R
+Print only the name of the @sc{rcs} file.
+
+@c Note that using a bare revision (in addition to not
+@c being explicitly documented here) is potentially
+@c confusing; it shows the log message to get from the
+@c previous revision to that revision. "-r1.3 -r1.6"
+@c (equivalent to "-r1.3,1.6") is even worse; it
+@c prints the messages to get from 1.2 to 1.3 and 1.5
+@c to 1.6. By analogy with "cvs diff", users might
+@c expect that it is more like specifying a range.
+@c It is not 100% clear to me how much of this should
+@c be documented (for example, multiple -r options
+@c perhaps could/should be deprecated given the false
+@c analogy with "cvs diff").
+@c In general, this section should be rewritten to talk
+@c about messages to get from revision rev1 to rev2,
+@c rather than messages for revision rev2 (that is, the
+@c messages are associated with a change not a static
+@c revision and failing to make this distinction causes
+@c much confusion).
+@item -r@var{revisions}
+Print information about revisions given in the
+comma-separated list @var{revisions} of revisions and
+ranges. The following table explains the available
+range formats:
+
+@table @code
+@item @var{rev1}:@var{rev2}
+Revisions @var{rev1} to @var{rev2} (which must be on
+the same branch).
+
+@item @var{rev1}::@var{rev2}
+The same, but excluding @var{rev1}.
+
+@item :@var{rev}
+@itemx ::@var{rev}
+Revisions from the beginning of the branch up to
+and including @var{rev}.
+
+@item @var{rev}:
+Revisions starting with @var{rev} to the end of the
+branch containing @var{rev}.
+
+@item @var{rev}::
+Revisions starting just after @var{rev} to the end of the
+branch containing @var{rev}.
+
+@item @var{branch}
+An argument that is a branch means all revisions on
+that branch.
+
+@item @var{branch1}:@var{branch2}
+@itemx @var{branch1}::@var{branch2}
+A range of branches means all revisions
+on the branches in that range.
+
+@item @var{branch}.
+The latest revision in @var{branch}.
+@end table
+
+A bare @samp{-r} with no revisions means the latest
+revision on the default branch, normally the trunk.
+There can be no space between the @samp{-r} option and
+its argument.
+
+@item -S
+Suppress the header if no revisions are selected.
+
+@item -s @var{states}
+Print information about revisions whose state
+attributes match one of the states given in the
+comma-separated list @var{states}. Individual states may
+be any text string, though @sc{cvs} commonly only uses two
+states, @samp{Exp} and @samp{dead}. See @ref{admin options}
+for more information.
+
+@item -t
+Print the same as @samp{-h}, plus the descriptive text.
+
+@item -w@var{logins}
+Print information about revisions checked in by users
+with login names appearing in the comma-separated list
+@var{logins}. If @var{logins} is omitted, the user's
+login is assumed. There can be no space between the
+@samp{-w} option and its argument.
+@end table
+
+@code{log} prints the intersection of the revisions
+selected with the options @samp{-d}, @samp{-s}, and
+@samp{-w}, intersected with the union of the revisions
+selected by @samp{-b} and @samp{-r}.
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node log examples
+@appendixsubsec log examples
+
+@cindex Timezone, in output
+@cindex Zone, time, in output
+Since @code{log} shows dates in local time,
+you might want to see them in Coordinated Universal Time (UTC) or
+some other timezone.
+To do this you can set your @code{$TZ} environment
+variable before invoking @sc{cvs}:
+
+@example
+$ TZ=UTC cvs log foo.c
+$ TZ=EST cvs log bar.c
+@end example
+
+(If you are using a @code{csh}-style shell, like @code{tcsh},
+you would need to prefix the examples above with @code{env}.)
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node ls & rls
+@appendixsec ls & rls
+@cindex ls (subcommand)
+@cindex rls (subcommand)
+
+@itemize @bullet
+@item
+ls [-e | -l] [-RP] [-r tag[:date]] [-D date] [path@dots{}]
+@item
+Requires: repository for @code{rls}, repository & working directory for
+@code{ls}.
+@item
+Changes: nothing.
+@item
+Synonym: @code{dir} & @code{list} are synonyms for @code{ls} and @code{rdir}
+& @code{rlist} are synonyms for @code{rls}.
+@end itemize
+
+The @code{ls} and @code{rls} commands are used to list
+files and directories in the repository.
+
+By default @code{ls} lists the files and directories
+that belong in your working directory, what would be
+there after an @code{update}.
+
+By default @code{rls} lists the files and directories
+on the tip of the trunk in the topmost directory of the
+repository.
+
+Both commands accept an optional list of file and
+directory names, relative to the working directory for
+@code{ls} and the topmost directory of the repository
+for @code{rls}. Neither is recursive by default.
+
+@menu
+* ls & rls options:: ls & rls options
+* rls examples: rls examples
+@end menu
+
+@node ls & rls options
+@appendixsubsec ls & rls options
+
+These standard options are supported by @code{ls} & @code{rls}:
+
+@table @code
+@item -d
+Show dead revisions (with tag when specified).
+
+@item -e
+Display in CVS/Entries format. This format is meant to remain easily parsable
+by automation.
+
+@item -l
+Display all details.
+
+@item -P
+Don't list contents of empty directories when recursing.
+
+@item -R
+List recursively.
+
+@item -r @var{tag}[:@var{date}]
+Show files specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Common options}.
+
+@item -D @var{date}
+Show files from date.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node rls examples
+@appendixsubsec rls examples
+
+@example
+$ cvs rls
+cvs rls: Listing module: `.'
+CVSROOT
+first-dir
+@end example
+
+@example
+$ cvs rls CVSROOT
+cvs rls: Listing module: `CVSROOT'
+checkoutlist
+commitinfo
+config
+cvswrappers
+loginfo
+modules
+notify
+rcsinfo
+taginfo
+verifymsg
+
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node rdiff
+@appendixsec rdiff---'patch' format diffs between releases
+@cindex rdiff (subcommand)
+
+@itemize @bullet
+@item
+rdiff [-flags] [-V vn] (-r tag1[:date1] | -D date1) [-r tag2[:date2] | -D date2] modules@dots{}
+@item
+Requires: repository.
+@item
+Changes: nothing.
+@item
+Synonym: patch
+@end itemize
+
+Builds a Larry Wall format patch(1) file between two
+releases, that can be fed directly into the @code{patch}
+program to bring an old release up-to-date with the new
+release. (This is one of the few @sc{cvs} commands that
+operates directly from the repository, and doesn't
+require a prior checkout.) The diff output is sent to
+the standard output device.
+
+You can specify (using the standard @samp{-r} and
+@samp{-D} options) any combination of one or two
+revisions or dates. If only one revision or date is
+specified, the patch file reflects differences between
+that revision or date and the current head revisions in
+the @sc{rcs} file.
+
+Note that if the software release affected is contained
+in more than one directory, then it may be necessary to
+specify the @samp{-p} option to the @code{patch} command when
+patching the old sources, so that @code{patch} is able to find
+the files that are located in other directories.
+
+@menu
+* rdiff options:: rdiff options
+* rdiff examples:: rdiff examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node rdiff options
+@appendixsubsec rdiff options
+
+These standard options are supported by @code{rdiff}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -D @var{date}
+Use the most recent revision no later than @var{date}.
+
+@item -f
+If no matching revision is found, retrieve the most
+recent revision (instead of ignoring the file).
+
+@item -k @var{kflag}
+Process keywords according to @var{kflag}. See
+@ref{Keyword substitution}.
+
+@item -l
+Local; don't descend subdirectories.
+
+@item -R
+Examine directories recursively. This option is on by default.
+
+@item -r @var{tag}
+Use the revision specified by @var{tag}, or when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Common options}.
+@end table
+
+In addition to the above, these options are available:
+
+@table @code
+@item -c
+Use the context diff format. This is the default format.
+
+@item -s
+Create a summary change report instead of a patch. The
+summary includes information about files that were
+changed or added between the releases. It is sent to
+the standard output device. This is useful for finding
+out, for example, which files have changed between two
+dates or revisions.
+
+@item -t
+A diff of the top two revisions is sent to the standard
+output device. This is most useful for seeing what the
+last change to a file was.
+
+@item -u
+Use the unidiff format for the context diffs.
+Remember that old versions
+of the @code{patch} program can't handle the unidiff
+format, so if you plan to post this patch to the net
+you should probably not use @samp{-u}.
+
+@item -V @var{vn}
+Expand keywords according to the rules current in
+@sc{rcs} version @var{vn} (the expansion format changed with
+@sc{rcs} version 5). Note that this option is no
+longer accepted. @sc{cvs} will always expand keywords the
+way that @sc{rcs} version 5 does.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node rdiff examples
+@appendixsubsec rdiff examples
+
+Suppose you receive mail from @t{foo@@example.net} asking for an
+update from release 1.2 to 1.4 of the tc compiler. You
+have no such patches on hand, but with @sc{cvs} that can
+easily be fixed with a command such as this:
+
+@example
+$ cvs rdiff -c -r FOO1_2 -r FOO1_4 tc | \
+$$ Mail -s 'The patches you asked for' foo@@example.net
+@end example
+
+Suppose you have made release 1.3, and forked a branch
+called @samp{R_1_3fix} for bug fixes. @samp{R_1_3_1}
+corresponds to release 1.3.1, which was made some time
+ago. Now, you want to see how much development has been
+done on the branch. This command can be used:
+
+@example
+$ cvs patch -s -r R_1_3_1 -r R_1_3fix module-name
+cvs rdiff: Diffing module-name
+File ChangeLog,v changed from revision 1.52.2.5 to 1.52.2.6
+File foo.c,v changed from revision 1.52.2.3 to 1.52.2.4
+File bar.h,v changed from revision 1.29.2.1 to 1.2
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node release
+@appendixsec release---Indicate that a Module is no longer in use
+@cindex release (subcommand)
+
+@itemize @bullet
+@item
+release [-d] directories@dots{}
+@item
+Requires: Working directory.
+@item
+Changes: Working directory, history log.
+@end itemize
+
+This command is meant to safely cancel the effect of
+@samp{cvs checkout}. Since @sc{cvs} doesn't lock files, it
+isn't strictly necessary to use this command. You can
+always simply delete your working directory, if you
+like; but you risk losing changes you may have
+forgotten, and you leave no trace in the @sc{cvs} history
+file (@pxref{history file}) that you've abandoned your
+checkout.
+
+Use @samp{cvs release} to avoid these problems. This
+command checks that no uncommitted changes are
+present; that you are executing it from immediately
+above a @sc{cvs} working directory; and that the repository
+recorded for your files is the same as the repository
+defined in the module database.
+
+If all these conditions are true, @samp{cvs release}
+leaves a record of its execution (attesting to your
+intentionally abandoning your checkout) in the @sc{cvs}
+history log.
+
+@menu
+* release options:: release options
+* release output:: release output
+* release examples:: release examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node release options
+@appendixsubsec release options
+
+The @code{release} command supports one command option:
+
+@table @code
+@item -d
+Delete your working copy of the file if the release
+succeeds. If this flag is not given your files will
+remain in your working directory.
+
+@strong{WARNING: The @code{release} command deletes
+all directories and files recursively. This
+has the very serious side-effect that any directory
+that you have created inside your checked-out sources,
+and not added to the repository (using the @code{add}
+command; @pxref{Adding files}) will be silently deleted---even
+if it is non-empty!}
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node release output
+@appendixsubsec release output
+
+Before @code{release} releases your sources it will
+print a one-line message for any file that is not
+up-to-date.
+
+@table @code
+@item U @var{file}
+@itemx P @var{file}
+There exists a newer revision of this file in the
+repository, and you have not modified your local copy
+of the file (@samp{U} and @samp{P} mean the same thing).
+
+@item A @var{file}
+The file has been added to your private copy of the
+sources, but has not yet been committed to the
+repository. If you delete your copy of the sources
+this file will be lost.
+
+@item R @var{file}
+The file has been removed from your private copy of the
+sources, but has not yet been removed from the
+repository, since you have not yet committed the
+removal. @xref{commit}.
+
+@item M @var{file}
+The file is modified in your working directory. There
+might also be a newer revision inside the repository.
+
+@item ? @var{file}
+@var{file} is in your working directory, but does not
+correspond to anything in the source repository, and is
+not in the list of files for @sc{cvs} to ignore (see the
+description of the @samp{-I} option, and
+@pxref{cvsignore}). If you remove your working
+sources, this file will be lost.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node release examples
+@appendixsubsec release examples
+
+Release the @file{tc} directory, and delete your local working copy
+of the files.
+
+@example
+$ cd .. # @r{You must stand immediately above the}
+ # @r{sources when you issue @samp{cvs release}.}
+$ cvs release -d tc
+You have [0] altered files in this repository.
+Are you sure you want to release (and delete) directory `tc': y
+$
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node server & pserver
+@appendixsec server & pserver---Act as a server for a client on stdin/stdout
+@cindex pserver (subcommand)
+@cindex server (subcommand)
+
+@itemize @bullet
+@item
+pserver [-c path]
+
+server [-c path]
+@item
+Requires: repository, client conversation on stdin/stdout
+@item
+Changes: Repository or, indirectly, client working directory.
+@end itemize
+
+The @sc{cvs} @code{server} and @code{pserver} commands are used to provide
+repository access to remote clients and expect a client conversation on
+stdin & stdout. Typically these commands are launched from @code{inetd} or
+via @code{ssh} (@pxref{Remote repositories}).
+
+@code{server} expects that the client has already been authenticated somehow,
+typically via @sc{ssh}, and @code{pserver} attempts to authenticate the client
+itself.
+
+Only one option is available with the @code{server} and @code{pserver}
+commands:
+
+@cindex configuration file
+@table @code
+@item -c path
+Load configuration from @var{path} rather than the default location
+@file{$CVSROOT/CVSROOT/config} (@pxref{config}). @var{path} must be
+@file{/etc/cvs.conf} or prefixed by @file{/etc/cvs/}. This option is
+supported beginning with @sc{cvs} release 1.12.13.
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node update
+@appendixsec update---Bring work tree in sync with repository
+@cindex update (subcommand)
+
+@itemize @bullet
+@item
+update [-ACdflPpR] [-I name] [-j rev [-j rev]] [-k kflag] [-r tag[:date] | -D date] [-W spec] files@dots{}
+@item
+Requires: repository, working directory.
+@item
+Changes: working directory.
+@end itemize
+
+After you've run checkout to create your private copy
+of source from the common repository, other developers
+will continue changing the central source. From time
+to time, when it is convenient in your development
+process, you can use the @code{update} command from
+within your working directory to reconcile your work
+with any revisions applied to the source repository
+since your last checkout or update. Without the @code{-C}
+option, @code{update} will also merge any differences
+between the local copy of files and their base revisions
+into any destination revisions specified with @code{-r},
+@code{-D}, or @code{-A}.
+
+@menu
+* update options:: update options
+* update output:: update output
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node update options
+@appendixsubsec update options
+
+These standard options are available with @code{update}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -D date
+Use the most recent revision no later than @var{date}.
+This option is sticky, and implies @samp{-P}.
+See @ref{Sticky tags}, for more information on sticky tags/dates.
+
+@item -f
+Only useful with the @samp{-D} or @samp{-r} flags. If no matching revision
+is found, retrieve the most recent revision (instead of ignoring the file).
+
+@item -k @var{kflag}
+Process keywords according to @var{kflag}. See
+@ref{Keyword substitution}.
+This option is sticky; future updates of
+this file in this working directory will use the same
+@var{kflag}. The @code{status} command can be viewed
+to see the sticky options. See @ref{Invoking CVS}, for
+more information on the @code{status} command.
+
+@item -l
+Local; run only in current working directory. @xref{Recursive behavior}.
+
+@item -P
+Prune empty directories. See @ref{Moving directories}.
+
+@item -p
+Pipe files to the standard output.
+
+@item -R
+Update directories recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Retrieve the revisions specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. This option is sticky, and implies @samp{-P}.
+See @ref{Sticky tags}, for more information on sticky tags/dates. Also
+see @ref{Common options}.
+@end table
+
+@need 800
+These special options are also available with
+@code{update}.
+
+@table @code
+@item -A
+Reset any sticky tags, dates, or @samp{-k} options.
+See @ref{Sticky tags}, for more information on sticky tags/dates.
+
+@item -C
+Overwrite locally modified files with clean copies from
+the repository (the modified file is saved in
+@file{.#@var{file}.@var{revision}}, however).
+
+@item -d
+Create any directories that exist in the repository if
+they're missing from the working directory. Normally,
+@code{update} acts only on directories and files that
+were already enrolled in your working directory.
+
+This is useful for updating directories that were
+created in the repository since the initial checkout;
+but it has an unfortunate side effect. If you
+deliberately avoided certain directories in the
+repository when you created your working directory
+(either through use of a module name or by listing
+explicitly the files and directories you wanted on the
+command line), then updating with @samp{-d} will create
+those directories, which may not be what you want.
+
+@item -I @var{name}
+Ignore files whose names match @var{name} (in your
+working directory) during the update. You can specify
+@samp{-I} more than once on the command line to specify
+several files to ignore. Use @samp{-I !} to avoid
+ignoring any files at all. @xref{cvsignore}, for other
+ways to make @sc{cvs} ignore some files.
+
+@item -W@var{spec}
+Specify file names that should be filtered during
+update. You can use this option repeatedly.
+
+@var{spec} can be a file name pattern of the same type
+that you can specify in the @file{.cvswrappers}
+file. @xref{Wrappers}.
+
+@item -j@var{revision}
+With two @samp{-j} options, merge changes from the
+revision specified with the first @samp{-j} option to
+the revision specified with the second @samp{j} option,
+into the working directory.
+
+With one @samp{-j} option, merge changes from the
+ancestor revision to the revision specified with the
+@samp{-j} option, into the working directory. The
+ancestor revision is the common ancestor of the
+revision which the working directory is based on, and
+the revision specified in the @samp{-j} option.
+
+Note that using a single @samp{-j @var{tagname}} option rather than
+@samp{-j @var{branchname}} to merge changes from a branch will
+often not remove files which were removed on the branch.
+@xref{Merging adds and removals}, for more.
+
+In addition, each @samp{-j} option can contain an optional
+date specification which, when used with branches, can
+limit the chosen revision to one within a specific
+date. An optional date is specified by adding a colon
+(:) to the tag:
+@samp{-j@var{Symbolic_Tag}:@var{Date_Specifier}}.
+
+@xref{Branching and merging}.
+
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node update output
+@appendixsubsec update output
+
+@code{update} and @code{checkout} keep you informed of
+their progress by printing a line for each file, preceded
+by one character indicating the status of the file:
+
+@table @code
+@item U @var{file}
+The file was brought up to date with respect to the
+repository. This is done for any file that exists in
+the repository but not in your working directory, and for files
+that you haven't changed but are not the most recent
+versions available in the repository.
+
+@item P @var{file}
+Like @samp{U}, but the @sc{cvs} server sends a patch instead of an entire
+file. This accomplishes the same thing as @samp{U} using less bandwidth.
+
+@item A @var{file}
+The file has been added to your private copy of the
+sources, and will be added to the source repository
+when you run @code{commit} on the file. This is a
+reminder to you that the file needs to be committed.
+
+@item R @var{file}
+The file has been removed from your private copy of the
+sources, and will be removed from the source repository
+when you run @code{commit} on the file. This is a
+reminder to you that the file needs to be committed.
+
+@item M @var{file}
+The file is modified in your working directory.
+
+@samp{M} can indicate one of two states for a file
+you're working on: either there were no modifications
+to the same file in the repository, so that your file
+remains as you last saw it; or there were modifications
+in the repository as well as in your copy, but they
+were merged successfully, without conflict, in your
+working directory.
+
+@sc{cvs} will print some messages if it merges your work,
+and a backup copy of your working file (as it looked
+before you ran @code{update}) will be made. The exact
+name of that file is printed while @code{update} runs.
+
+@item C @var{file}
+@cindex .# files
+@cindex __ files (VMS)
+A conflict was detected while trying to merge your
+changes to @var{file} with changes from the source
+repository. @var{file} (the copy in your working
+directory) is now the result of attempting to merge
+the two revisions; an unmodified copy of your file
+is also in your working directory, with the name
+@file{.#@var{file}.@var{revision}} where @var{revision}
+is the revision that your modified file started
+from. Resolve the conflict as described in
+@ref{Conflicts example}.
+@c "some systems" as in out-of-the-box OSes? Not as
+@c far as I know. We need to advise sysadmins as well
+@c as users how to set up this kind of purge, if that is
+@c what they want.
+@c We also might want to think about cleaner solutions,
+@c like having CVS remove the .# file once the conflict
+@c has been resolved or something like that.
+(Note that some systems automatically purge
+files that begin with @file{.#} if they have not been
+accessed for a few days. If you intend to keep a copy
+of your original file, it is a very good idea to rename
+it.) Under @sc{vms}, the file name starts with
+@file{__} rather than @file{.#}.
+
+@item ? @var{file}
+@var{file} is in your working directory, but does not
+correspond to anything in the source repository, and is
+not in the list of files for @sc{cvs} to ignore (see the
+description of the @samp{-I} option, and
+@pxref{cvsignore}).
+@end table
+
+@c ----- END MAN 1 -----
+@c ---------------------------------------------------------------------
+@node Invoking CVS
+@appendix Quick reference to CVS commands
+@cindex Command reference
+@cindex Reference, commands
+@cindex Invoking CVS
+
+This appendix describes how to invoke @sc{cvs}, with
+references to where each command or feature is
+described in detail. For other references run the
+@code{cvs --help} command, or see @ref{Index}.
+
+A @sc{cvs} command looks like:
+
+@example
+cvs [ @var{global_options} ] @var{command} [ @var{command_options} ] [ @var{command_args} ]
+@end example
+
+Global options:
+
+@table @code
+@item --allow-root=@var{rootdir}
+Specify legal @sc{cvsroot} directory (server only) (not
+in @sc{cvs} 1.9 and older). See @ref{Password
+authentication server}.
+
+@item -a
+Authenticate all communication (client only) (not in @sc{cvs}
+1.9 and older). See @ref{Global options}.
+
+@item -b
+Specify RCS location (@sc{cvs} 1.9 and older). See
+@ref{Global options}.
+
+@item -d @var{root}
+Specify the @sc{cvsroot}. See @ref{Repository}.
+
+@item -e @var{editor}
+Edit messages with @var{editor}. See @ref{Committing
+your changes}.
+
+@item -f
+Do not read the @file{~/.cvsrc} file. See @ref{Global
+options}.
+
+@item -H
+@itemx --help
+Print a help message. See @ref{Global options}.
+
+@item -n
+Do not change any files. See @ref{Global options}.
+
+@item -Q
+Be really quiet. See @ref{Global options}.
+
+@item -q
+Be somewhat quiet. See @ref{Global options}.
+
+@item -r
+Make new working files read-only. See @ref{Global options}.
+
+@item -s @var{variable}=@var{value}
+Set a user variable. See @ref{Variables}.
+
+@item -T @var{tempdir}
+Put temporary files in @var{tempdir}. See @ref{Global
+options}.
+
+@item -t
+Trace @sc{cvs} execution. See @ref{Global options}.
+
+@item -v
+@item --version
+Display version and copyright information for @sc{cvs}.
+
+@item -w
+Make new working files read-write. See @ref{Global
+options}.
+
+@item -x
+Encrypt all communication (client only).
+See @ref{Global options}.
+
+@item -z @var{gzip-level}
+@cindex Compression
+@cindex Gzip
+Set the compression level (client only).
+See @ref{Global options}.
+@end table
+
+Keyword expansion modes (@pxref{Substitution modes}):
+
+@example
+-kkv $@splitrcskeyword{Id}: file1,v 1.1 1993/12/09 03:21:13 joe Exp $
+-kkvl $@splitrcskeyword{Id}: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $
+-kk $@splitrcskeyword{Id}$
+-kv file1,v 1.1 1993/12/09 03:21:13 joe Exp
+-ko @i{no expansion}
+-kb @i{no expansion, file is binary}
+@end example
+
+Keywords (@pxref{Keyword list}):
+
+@example
+$@splitrcskeyword{Author}: joe $
+$@splitrcskeyword{Date}: 1993/12/09 03:21:13 $
+$@splitrcskeyword{CVSHeader}: files/file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $
+$@splitrcskeyword{Header}: /home/files/file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $
+$@splitrcskeyword{Id}: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $
+$@splitrcskeyword{Locker}: harry $
+$@splitrcskeyword{Name}: snapshot_1_14 $
+$@splitrcskeyword{RCSfile}: file1,v $
+$@splitrcskeyword{Revision}: 1.1 $
+$@splitrcskeyword{Source}: /home/files/file1,v $
+$@splitrcskeyword{State}: Exp $
+$@splitrcskeyword{Log}: file1,v $
+Revision 1.1 1993/12/09 03:30:17 joe
+Initial revision
+
+@end example
+
+@c The idea behind this table is that we want each item
+@c to be a sentence or two at most. Preferably a
+@c single line.
+@c
+@c In some cases refs to "foo options" are just to get
+@c this thing written quickly, not because the "foo
+@c options" node is really the best place to point.
+Commands, command options, and command arguments:
+
+@table @code
+@c ------------------------------------------------------------
+@item add [@var{options}] [@var{files}@dots{}]
+Add a new file/directory. See @ref{Adding files}.
+
+@table @code
+@item -k @var{kflag}
+Set keyword expansion.
+
+@item -m @var{msg}
+Set file description.
+@end table
+
+@c ------------------------------------------------------------
+@item admin [@var{options}] [@var{files}@dots{}]
+Administration of history files in the repository. See
+@ref{admin}.
+@c This list omits those options which are not
+@c documented as being useful with CVS. That might be
+@c a mistake...
+
+@table @code
+@item -b[@var{rev}]
+Set default branch. See @ref{Reverting local changes}.
+
+@item -c@var{string}
+Set comment leader.
+
+@item -k@var{subst}
+Set keyword substitution. See @ref{Keyword
+substitution}.
+
+@item -l[@var{rev}]
+Lock revision @var{rev}, or latest revision.
+
+@item -m@var{rev}:@var{msg}
+Replace the log message of revision @var{rev} with
+@var{msg}.
+
+@item -o@var{range}
+Delete revisions from the repository. See
+@ref{admin options}.
+
+@item -q
+Run quietly; do not print diagnostics.
+
+@item -s@var{state}[:@var{rev}]
+Set the state. See @ref{admin options} for more information on possible
+states.
+
+@c Does not work for client/server CVS
+@item -t
+Set file description from standard input.
+
+@item -t@var{file}
+Set file description from @var{file}.
+
+@item -t-@var{string}
+Set file description to @var{string}.
+
+@item -u[@var{rev}]
+Unlock revision @var{rev}, or latest revision.
+@end table
+
+@c ------------------------------------------------------------
+@item annotate [@var{options}] [@var{files}@dots{}]
+Show last revision where each line was modified. See
+@ref{annotate}.
+
+@table @code
+@item -D @var{date}
+Annotate the most recent revision no later than
+@var{date}. See @ref{Common options}.
+
+@item -F
+Force annotation of binary files. (Without this option,
+binary files are skipped with a message.)
+
+@item -f
+Use head revision if tag/date not found. See
+@ref{Common options}.
+
+@item -l
+Local; run only in current working directory. @xref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Annotate revisions specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Common options}.
+@end table
+
+@c ------------------------------------------------------------
+@item checkout [@var{options}] @var{modules}@dots{}
+Get a copy of the sources. See @ref{checkout}.
+
+@table @code
+@item -A
+Reset any sticky tags/date/options. See @ref{Sticky
+tags} and @ref{Keyword substitution}.
+
+@item -c
+Output the module database. See @ref{checkout options}.
+
+@item -D @var{date}
+Check out revisions as of @var{date} (is sticky). See
+@ref{Common options}.
+
+@item -d @var{dir}
+Check out into @var{dir}. See @ref{checkout options}.
+
+@item -f
+Use head revision if tag/date not found. See
+@ref{Common options}.
+
+@c Probably want to use rev1/rev2 style like for diff
+@c -r. Here and in on-line help.
+@item -j @var{tag}[:@var{date}]
+Merge in the change specified by @var{tag}, or when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{checkout options}.
+
+@item -k @var{kflag}
+Use @var{kflag} keyword expansion. See
+@ref{Substitution modes}.
+
+@item -l
+Local; run only in current working directory. @xref{Recursive behavior}.
+
+@item -N
+Don't ``shorten'' module paths if -d specified. See
+@ref{checkout options}.
+
+@item -n
+Do not run module program (if any). See @ref{checkout options}.
+
+@item -P
+Prune empty directories. See @ref{Moving directories}.
+
+@item -p
+Check out files to standard output (avoids
+stickiness). See @ref{checkout options}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Checkout the revision already tagged with @var{tag} or, when @var{date} is
+specified and @var{tag} is a branch tag, the version from the branch @var{tag}
+as it existed on @var{date}. This . See @ref{Common options}.
+
+@item -s
+Like -c, but include module status. See @ref{checkout options}.
+@end table
+
+@c ------------------------------------------------------------
+@item commit [@var{options}] [@var{files}@dots{}]
+Check changes into the repository. See @ref{commit}.
+
+@table @code
+@item -c
+Check for valid edits before committing. Requires a @sc{cvs} client and server
+both version 1.12.10 or greater.
+
+@item -F @var{file}
+Read log message from @var{file}. See @ref{commit options}.
+
+@item -f
+@c What is this "disables recursion"? It is from the
+@c on-line help; is it documented in this manual?
+Force the file to be committed; disables recursion.
+See @ref{commit options}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -m @var{msg}
+Use @var{msg} as log message. See @ref{commit options}.
+
+@item -n
+Do not run module program (if any). See @ref{commit options}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{rev}
+Commit to @var{rev}. See @ref{commit options}.
+@c FIXME: should be dragging over text from
+@c commit options, especially if it can be cleaned up
+@c and made concise enough.
+@end table
+
+@c ------------------------------------------------------------
+@item diff [@var{options}] [@var{files}@dots{}]
+Show differences between revisions. See @ref{diff}.
+In addition to the options shown below, accepts a wide
+variety of options to control output style, for example
+@samp{-c} for context diffs.
+
+@table @code
+@item -D @var{date1}
+Diff revision for date against working file. See
+@ref{diff options}.
+
+@item -D @var{date2}
+Diff @var{rev1}/@var{date1} against @var{date2}. See
+@ref{diff options}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -N
+Include diffs for added and removed files. See
+@ref{diff options}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{tag1}[:@var{date1}]
+Diff the revisions specified by @var{tag1} or, when @var{date1} is specified
+and @var{tag1} is a branch tag, the version from the branch @var{tag1} as it
+existed on @var{date1}, against the working file. See @ref{diff options}
+and @ref{Common options}.
+
+@item -r @var{tag2}[:@var{date2}]
+Diff the revisions specified by @var{tag2} or, when @var{date2} is specified
+and @var{tag2} is a branch tag, the version from the branch @var{tag2} as it
+existed on @var{date2}, against @var{rev1}/@var{date1}. See @ref{diff options}
+and @ref{Common options}.
+@end table
+
+@c ------------------------------------------------------------
+@item edit [@var{options}] [@var{files}@dots{}]
+Get ready to edit a watched file. See @ref{Editing files}.
+
+@table @code
+@item -a @var{actions}
+Specify actions for temporary watch, where
+@var{actions} is @code{edit}, @code{unedit},
+@code{commit}, @code{all}, or @code{none}. See
+@ref{Editing files}.
+
+@item -c
+Check edits: Edit fails if someone else is already editting the file.
+Requires a @sc{cvs} client and server both of version 1.12.10 or greater.
+
+@item -f
+Force edit; ignore other edits. Added in CVS 1.12.10.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+@end table
+
+@c ------------------------------------------------------------
+@item editors [@var{options}] [@var{files}@dots{}]
+See who is editing a watched file. See @ref{Watch information}.
+
+@table @code
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+@end table
+
+@c ------------------------------------------------------------
+@item export [@var{options}] @var{modules}@dots{}
+Export files from @sc{cvs}. See @ref{export}.
+
+@table @code
+@item -D @var{date}
+Check out revisions as of @var{date}. See
+@ref{Common options}.
+
+@item -d @var{dir}
+Check out into @var{dir}. See @ref{export options}.
+
+@item -f
+Use head revision if tag/date not found. See
+@ref{Common options}.
+
+@item -k @var{kflag}
+Use @var{kflag} keyword expansion. See
+@ref{Substitution modes}.
+
+@item -l
+Local; run only in current working directory. @xref{Recursive behavior}.
+
+@item -N
+Don't ``shorten'' module paths if -d specified. See
+@ref{export options}.
+
+@item -n
+Do not run module program (if any). See @ref{export options}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Export the revisions specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Common options}.
+@end table
+
+@c ------------------------------------------------------------
+@item history [@var{options}] [@var{files}@dots{}]
+Show repository access history. See @ref{history}.
+
+@table @code
+@item -a
+All users (default is self). See @ref{history options}.
+
+@item -b @var{str}
+Back to record with @var{str} in module/file/repos
+field. See @ref{history options}.
+
+@item -c
+Report on committed (modified) files. See @ref{history options}.
+
+@item -D @var{date}
+Since @var{date}. See @ref{history options}.
+
+@item -e
+Report on all record types. See @ref{history options}.
+
+@item -l
+Last modified (committed or modified report). See @ref{history options}.
+
+@item -m @var{module}
+Report on @var{module} (repeatable). See @ref{history options}.
+
+@item -n @var{module}
+In @var{module}. See @ref{history options}.
+
+@item -o
+Report on checked out modules. See @ref{history options}.
+
+@item -p @var{repository}
+In @var{repository}. See @ref{history options}.
+
+@item -r @var{rev}
+Since revision @var{rev}. See @ref{history options}.
+
+@item -T
+@c What the @#$@# is a TAG? Same as a tag? This
+@c wording is also in the online-line help.
+Produce report on all TAGs. See @ref{history options}.
+
+@item -t @var{tag}
+Since tag record placed in history file (by anyone).
+See @ref{history options}.
+
+@item -u @var{user}
+For user @var{user} (repeatable). See @ref{history options}.
+
+@item -w
+Working directory must match. See @ref{history options}.
+
+@item -x @var{types}
+Report on @var{types}, one or more of
+@code{TOEFWUPCGMAR}. See @ref{history options}.
+
+@item -z @var{zone}
+Output for time zone @var{zone}. See @ref{history options}.
+@end table
+
+@c ------------------------------------------------------------
+@item import [@var{options}] @var{repository} @var{vendor-tag} @var{release-tags}@dots{}
+Import files into @sc{cvs}, using vendor branches. See
+@ref{import}.
+
+@table @code
+@item -b @var{bra}
+Import to vendor branch @var{bra}. See
+@ref{Multiple vendor branches}.
+
+@item -d
+Use the file's modification time as the time of
+import. See @ref{import options}.
+
+@item -k @var{kflag}
+Set default keyword substitution mode. See
+@ref{import options}.
+
+@item -m @var{msg}
+Use @var{msg} for log message. See
+@ref{import options}.
+
+@item -I @var{ign}
+More files to ignore (! to reset). See
+@ref{import options}.
+
+@item -W @var{spec}
+More wrappers. See @ref{import options}.
+@end table
+
+@c ------------------------------------------------------------
+@item init
+Create a @sc{cvs} repository if it doesn't exist. See
+@ref{Creating a repository}.
+
+@c ------------------------------------------------------------
+@item kserver
+Kerberos authenticated server.
+See @ref{Kerberos authenticated}.
+
+@c ------------------------------------------------------------
+@item log [@var{options}] [@var{files}@dots{}]
+Print out history information for files. See @ref{log}.
+
+@table @code
+@item -b
+Only list revisions on the default branch. See @ref{log options}.
+
+@item -d @var{dates}
+Specify dates (@var{d1}<@var{d2} for range, @var{d} for
+latest before). See @ref{log options}.
+
+@item -h
+Only print header. See @ref{log options}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -N
+Do not list tags. See @ref{log options}.
+
+@item -R
+Only print name of RCS file. See @ref{log options}.
+
+@item -r@var{revs}
+Only list revisions @var{revs}. See @ref{log options}.
+
+@item -s @var{states}
+Only list revisions with specified states. See @ref{log options}.
+
+@item -t
+Only print header and descriptive text. See @ref{log
+options}.
+
+@item -w@var{logins}
+Only list revisions checked in by specified logins. See @ref{log options}.
+@end table
+
+@c ------------------------------------------------------------
+@item login
+Prompt for password for authenticating server. See
+@ref{Password authentication client}.
+
+@c ------------------------------------------------------------
+@item logout
+Remove stored password for authenticating server. See
+@ref{Password authentication client}.
+
+@c ------------------------------------------------------------
+@item pserver
+Password authenticated server.
+See @ref{Password authentication server}.
+
+@c ------------------------------------------------------------
+@item rannotate [@var{options}] [@var{modules}@dots{}]
+Show last revision where each line was modified. See
+@ref{annotate}.
+
+@table @code
+@item -D @var{date}
+Annotate the most recent revision no later than
+@var{date}. See @ref{Common options}.
+
+@item -F
+Force annotation of binary files. (Without this option,
+binary files are skipped with a message.)
+
+@item -f
+Use head revision if tag/date not found. See
+@ref{Common options}.
+
+@item -l
+Local; run only in current working directory. @xref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Annotate the revision specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag}
+as it existed on @var{date}. See @ref{Common options}.
+@end table
+
+@c ------------------------------------------------------------
+@item rdiff [@var{options}] @var{modules}@dots{}
+Show differences between releases. See @ref{rdiff}.
+
+@table @code
+@item -c
+Context diff output format (default). See @ref{rdiff options}.
+
+@item -D @var{date}
+Select revisions based on @var{date}. See @ref{Common options}.
+
+@item -f
+Use head revision if tag/date not found. See
+@ref{Common options}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Select the revisions specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{diff options} and @ref{Common options}.
+
+@item -s
+Short patch - one liner per file. See @ref{rdiff options}.
+
+@item -t
+Top two diffs - last change made to the file. See
+@ref{diff options}.
+
+@item -u
+Unidiff output format. See @ref{rdiff options}.
+
+@item -V @var{vers}
+Use RCS Version @var{vers} for keyword expansion (obsolete). See
+@ref{rdiff options}.
+@end table
+
+@c ------------------------------------------------------------
+@item release [@var{options}] @var{directory}
+Indicate that a directory is no longer in use. See
+@ref{release}.
+
+@table @code
+@item -d
+Delete the given directory. See @ref{release options}.
+@end table
+
+@c ------------------------------------------------------------
+@item remove [@var{options}] [@var{files}@dots{}]
+Remove an entry from the repository. See @ref{Removing files}.
+
+@table @code
+@item -f
+Delete the file before removing it. See @ref{Removing files}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+@end table
+
+@c ------------------------------------------------------------
+@item rlog [@var{options}] [@var{files}@dots{}]
+Print out history information for modules. See @ref{log}.
+
+@table @code
+@item -b
+Only list revisions on the default branch. See @ref{log options}.
+
+@item -d @var{dates}
+Specify dates (@var{d1}<@var{d2} for range, @var{d} for
+latest before). See @ref{log options}.
+
+@item -h
+Only print header. See @ref{log options}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -N
+Do not list tags. See @ref{log options}.
+
+@item -R
+Only print name of RCS file. See @ref{log options}.
+
+@item -r@var{revs}
+Only list revisions @var{revs}. See @ref{log options}.
+
+@item -s @var{states}
+Only list revisions with specified states. See @ref{log options}.
+
+@item -t
+Only print header and descriptive text. See @ref{log options}.
+
+@item -w@var{logins}
+Only list revisions checked in by specified logins. See @ref{log options}.
+@end table
+
+@c ------------------------------------------------------------
+@item rtag [@var{options}] @var{tag} @var{modules}@dots{}
+Add a symbolic tag to a module.
+See @ref{Revisions} and @ref{Branching and merging}.
+
+@table @code
+@item -a
+Clear tag from removed files that would not otherwise
+be tagged. See @ref{Tagging add/remove}.
+
+@item -b
+Create a branch named @var{tag}. See @ref{Branching and merging}.
+
+@item -B
+Used in conjunction with -F or -d, enables movement and deletion of
+branch tags. Use with extreme caution.
+
+@item -D @var{date}
+Tag revisions as of @var{date}. See @ref{Tagging by date/tag}.
+
+@item -d
+Delete @var{tag}. See @ref{Modifying tags}.
+
+@item -F
+Move @var{tag} if it already exists. See @ref{Modifying tags}.
+
+@item -f
+Force a head revision match if tag/date not found.
+See @ref{Tagging by date/tag}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -n
+No execution of tag program. See @ref{Common options}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Tag the revision already tagged with @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Tagging by date/tag} and @ref{Common options}.
+@end table
+
+@c ------------------------------------------------------------
+@item server
+Rsh server. See @ref{Connecting via rsh}.
+
+@c ------------------------------------------------------------
+@item status [@var{options}] @var{files}@dots{}
+Display status information in a working directory. See
+@ref{File status}.
+
+@table @code
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive behavior}.
+
+@item -v
+Include tag information for file. See @ref{Tags}.
+@end table
+
+@c ------------------------------------------------------------
+@item tag [@var{options}] @var{tag} [@var{files}@dots{}]
+Add a symbolic tag to checked out version of files.
+See @ref{Revisions} and @ref{Branching and merging}.
+
+@table @code
+@item -b
+Create a branch named @var{tag}. See @ref{Branching and merging}.
+
+@item -c
+Check that working files are unmodified. See
+@ref{Tagging the working directory}.
+
+@item -D @var{date}
+Tag revisions as of @var{date}. See @ref{Tagging by date/tag}.
+
+@item -d
+Delete @var{tag}. See @ref{Modifying tags}.
+
+@item -F
+Move @var{tag} if it already exists. See @ref{Modifying tags}.
+
+@item -f
+Force a head revision match if tag/date not found.
+See @ref{Tagging by date/tag}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Tag the revision already tagged with @var{tag}, or when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Tagging by date/tag} and @ref{Common options}.
+@end table
+
+@c ------------------------------------------------------------
+@item unedit [@var{options}] [@var{files}@dots{}]
+Undo an edit command. See @ref{Editing files}.
+
+@table @code
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive behavior}.
+@end table
+
+@c ------------------------------------------------------------
+@item update [@var{options}] [@var{files}@dots{}]
+Bring work tree in sync with repository. See
+@ref{update}.
+
+@table @code
+@item -A
+Reset any sticky tags/date/options. See @ref{Sticky
+tags} and @ref{Keyword substitution}.
+
+@item -C
+Overwrite locally modified files with clean copies from
+the repository (the modified file is saved in
+@file{.#@var{file}.@var{revision}}, however).
+
+@item -D @var{date}
+Check out revisions as of @var{date} (is sticky). See
+@ref{Common options}.
+
+@item -d
+Create directories. See @ref{update options}.
+
+@item -f
+Use head revision if tag/date not found. See
+@ref{Common options}.
+
+@item -I @var{ign}
+More files to ignore (! to reset). See
+@ref{import options}.
+
+@c Probably want to use rev1/rev2 style like for diff
+@c -r. Here and in on-line help.
+@item -j @var{tag}[:@var{date}]
+Merge in changes from revisions specified by @var{tag} or, when @var{date} is
+specified and @var{tag} is a branch tag, the version from the branch @var{tag}
+as it existed on @var{date}. See @ref{update options}.
+
+@item -k @var{kflag}
+Use @var{kflag} keyword expansion. See
+@ref{Substitution modes}.
+
+@item -l
+Local; run only in current working directory. @xref{Recursive behavior}.
+
+@item -P
+Prune empty directories. See @ref{Moving directories}.
+
+@item -p
+Check out files to standard output (avoids
+stickiness). See @ref{update options}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+
+@item -r @var{tag}[:@var{date}]
+Checkout the revisions specified by @var{tag} or, when @var{date} is specified
+and @var{tag} is a branch tag, the version from the branch @var{tag} as it
+existed on @var{date}. See @ref{Common options}.
+
+@item -W @var{spec}
+More wrappers. See @ref{import options}.
+@end table
+
+@c ------------------------------------------------------------
+@item version
+@cindex version (subcommand)
+
+Display the version of @sc{cvs} being used. If the repository
+is remote, display both the client and server versions.
+
+@c ------------------------------------------------------------
+@item watch [on|off|add|remove] [@var{options}] [@var{files}@dots{}]
+
+on/off: turn on/off read-only checkouts of files. See
+@ref{Setting a watch}.
+
+add/remove: add or remove notification on actions. See
+@ref{Getting Notified}.
+
+@table @code
+@item -a @var{actions}
+Specify actions for temporary watch, where
+@var{actions} is @code{edit}, @code{unedit},
+@code{commit}, @code{all}, or @code{none}. See
+@ref{Editing files}.
+
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+@end table
+
+@c ------------------------------------------------------------
+@item watchers [@var{options}] [@var{files}@dots{}]
+See who is watching a file. See @ref{Watch information}.
+
+@table @code
+@item -l
+Local; run only in current working directory. See @ref{Recursive behavior}.
+
+@item -R
+Operate recursively (default). @xref{Recursive
+behavior}.
+@end table
+
+@end table
+
+@c ---------------------------------------------------------------------
+@node Administrative files
+@appendix Reference manual for Administrative files
+@cindex Administrative files (reference)
+@cindex Files, reference manual
+@cindex Reference manual (files)
+@cindex CVSROOT (file)
+
+Inside the repository, in the directory
+@file{$CVSROOT/CVSROOT}, there are a number of
+supportive files for @sc{cvs}. You can use @sc{cvs} in a limited
+fashion without any of them, but if they are set up
+properly they can help make life easier. For a
+discussion of how to edit them, see @ref{Intro
+administrative files}.
+
+The most important of these files is the @file{modules}
+file, which defines the modules inside the repository.
+
+@menu
+* modules:: Defining modules
+* Wrappers:: Specify binary-ness based on file name
+* Trigger Scripts:: Launch scripts in response to server events
+* rcsinfo:: Templates for the log messages
+* cvsignore:: Ignoring files via cvsignore
+* checkoutlist:: Adding your own administrative files
+* history file:: History information
+* Variables:: Various variables are expanded
+* config:: Miscellaneous CVS configuration
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node modules
+@appendixsec The modules file
+@cindex Modules (admin file)
+@cindex Defining modules (reference manual)
+
+The @file{modules} file records your definitions of
+names for collections of source code. @sc{cvs} will
+use these definitions if you use @sc{cvs} to update the
+modules file (use normal commands like @code{add},
+@code{commit}, etc).
+
+The @file{modules} file may contain blank lines and
+comments (lines beginning with @samp{#}) as well as
+module definitions. Long lines can be continued on the
+next line by specifying a backslash (@samp{\}) as the
+last character on the line.
+
+There are three basic types of modules: alias modules,
+regular modules, and ampersand modules. The difference
+between them is the way that they map files in the
+repository to files in the working directory. In all
+of the following examples, the top-level repository
+contains a directory called @file{first-dir}, which
+contains two files, @file{file1} and @file{file2}, and a
+directory @file{sdir}. @file{first-dir/sdir} contains
+a file @file{sfile}.
+
+@c FIXME: should test all the examples in this section.
+
+@menu
+* Alias modules:: The simplest kind of module
+* Regular modules::
+* Ampersand modules::
+* Excluding directories:: Excluding directories from a module
+* Module options:: Regular and ampersand modules can take options
+* Module program options:: How the modules ``program options'' programs
+ are run.
+@end menu
+
+@node Alias modules
+@appendixsubsec Alias modules
+@cindex Alias modules
+@cindex -a, in modules file
+
+Alias modules are the simplest kind of module:
+
+@table @code
+@item @var{mname} -a @var{aliases}@dots{}
+This represents the simplest way of defining a module
+@var{mname}. The @samp{-a} flags the definition as a
+simple alias: @sc{cvs} will treat any use of @var{mname} (as
+a command argument) as if the list of names
+@var{aliases} had been specified instead.
+@var{aliases} may contain either other module names or
+paths. When you use paths in aliases, @code{checkout}
+creates all intermediate directories in the working
+directory, just as if the path had been specified
+explicitly in the @sc{cvs} arguments.
+@end table
+
+For example, if the modules file contains:
+
+@example
+amodule -a first-dir
+@end example
+
+@noindent
+then the following two commands are equivalent:
+
+@example
+$ cvs co amodule
+$ cvs co first-dir
+@end example
+
+@noindent
+and they each would provide output such as:
+
+@example
+cvs checkout: Updating first-dir
+U first-dir/file1
+U first-dir/file2
+cvs checkout: Updating first-dir/sdir
+U first-dir/sdir/sfile
+@end example
+
+@node Regular modules
+@appendixsubsec Regular modules
+@cindex Regular modules
+
+@table @code
+@item @var{mname} [ options ] @var{dir} [ @var{files}@dots{} ]
+In the simplest case, this form of module definition
+reduces to @samp{@var{mname} @var{dir}}. This defines
+all the files in directory @var{dir} as module mname.
+@var{dir} is a relative path (from @code{$CVSROOT}) to a
+directory of source in the source repository. In this
+case, on checkout, a single directory called
+@var{mname} is created as a working directory; no
+intermediate directory levels are used by default, even
+if @var{dir} was a path involving several directory
+levels.
+@end table
+
+For example, if a module is defined by:
+
+@example
+regmodule first-dir
+@end example
+
+@noindent
+then regmodule will contain the files from first-dir:
+
+@example
+$ cvs co regmodule
+cvs checkout: Updating regmodule
+U regmodule/file1
+U regmodule/file2
+cvs checkout: Updating regmodule/sdir
+U regmodule/sdir/sfile
+$
+@end example
+
+By explicitly specifying files in the module definition
+after @var{dir}, you can select particular files from
+directory @var{dir}. Here is
+an example:
+
+@example
+regfiles first-dir/sdir sfile
+@end example
+
+@noindent
+With this definition, getting the regfiles module
+will create a single working directory
+@file{regfiles} containing the file listed, which
+comes from a directory deeper
+in the @sc{cvs} source repository:
+
+@example
+$ cvs co regfiles
+U regfiles/sfile
+$
+@end example
+
+@node Ampersand modules
+@appendixsubsec Ampersand modules
+@cindex Ampersand modules
+@cindex &, in modules file
+
+A module definition can refer to other modules by
+including @samp{&@var{module}} in its definition.
+@example
+@var{mname} [ options ] @var{&module}@dots{}
+@end example
+
+Then getting the module creates a subdirectory for each such
+module, in the directory containing the module. For
+example, if modules contains
+
+@example
+ampermod &first-dir
+@end example
+
+@noindent
+then a checkout will create an @code{ampermod} directory
+which contains a directory called @code{first-dir},
+which in turns contains all the directories and files
+which live there. For example, the command
+
+@example
+$ cvs co ampermod
+@end example
+
+@noindent
+will create the following files:
+
+@example
+ampermod/first-dir/file1
+ampermod/first-dir/file2
+ampermod/first-dir/sdir/sfile
+@end example
+
+There is one quirk/bug: the messages that @sc{cvs}
+prints omit the @file{ampermod}, and thus do not
+correctly display the location to which it is checking
+out the files:
+
+@example
+$ 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
+$
+@end example
+
+Do not rely on this buggy behavior; it may get fixed in
+a future release of @sc{cvs}.
+
+@c FIXCVS: What happens if regular and & modules are
+@c combined, as in "ampermodule first-dir &second-dir"?
+@c When I tried it, it seemed to just ignore the
+@c "first-dir". I think perhaps it should be an error
+@c (but this needs further investigation).
+@c In addition to discussing what each one does, we
+@c should put in a few words about why you would use one or
+@c the other in various situations.
+
+@node Excluding directories
+@appendixsubsec Excluding directories
+@cindex Excluding directories, in modules file
+@cindex !, in modules file
+
+An alias module may exclude particular directories from
+other modules by using an exclamation mark (@samp{!})
+before the name of each directory to be excluded.
+
+For example, if the modules file contains:
+
+@example
+exmodule -a !first-dir/sdir first-dir
+@end example
+
+@noindent
+then checking out the module @samp{exmodule} will check
+out everything in @samp{first-dir} except any files in
+the subdirectory @samp{first-dir/sdir}.
+@c Note that the "!first-dir/sdir" sometimes must be listed
+@c before "first-dir". That seems like a probable bug, in which
+@c case perhaps it should be fixed (to allow either
+@c order) rather than documented. See modules4 in testsuite.
+
+@node Module options
+@appendixsubsec Module options
+@cindex Options, in modules file
+
+Either regular modules or ampersand modules can contain
+options, which supply additional information concerning
+the module.
+
+@table @code
+@cindex -d, in modules file
+@item -d @var{name}
+Name the working directory something other than the
+module name.
+@c FIXME: Needs a bunch of examples, analogous to the
+@c examples for alias, regular, and ampersand modules
+@c which show where the files go without -d.
+
+@cindex Export program
+@cindex -e, in modules file
+@item -e @var{prog}
+Specify a program @var{prog} to run whenever files in a
+module are exported. @var{prog} runs with a single
+argument, the module name.
+@c FIXME: Is it run on server? client?
+
+@cindex Checkout program
+@cindex -o, in modules file
+@item -o @var{prog}
+Specify a program @var{prog} to run whenever files in a
+module are checked out. @var{prog} runs with a single
+argument, the module name. See @ref{Module program options} for
+information on how @var{prog} is called.
+@c FIXME: Is it run on server? client?
+
+@cindex Status of a module
+@cindex Module status
+@cindex -s, in modules file
+@item -s @var{status}
+Assign a status to the module. When the module file is
+printed with @samp{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.
+
+@cindex Tag program
+@cindex -t, in modules file
+@item -t @var{prog}
+Specify a program @var{prog} to run whenever files in a
+module are tagged with @code{rtag}. @var{prog} runs
+with two arguments: the module name and the symbolic
+tag specified to @code{rtag}. It is not run
+when @code{tag} is executed. Generally you will find
+that the @file{taginfo} file is a better solution (@pxref{taginfo}).
+@c FIXME: Is it run on server? client?
+@c Problems with -t include:
+@c * It is run after the tag not before
+@c * It doesn't get passed all the information that
+@c taginfo does ("mov", &c).
+@c * It only is run for rtag, not tag.
+@end table
+
+You should also see @pxref{Module program options} about how the
+``program options'' programs are run.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+@node Module program options
+@appendixsubsec How the modules file ``program options'' programs are run
+@cindex Modules file program options
+@cindex -t, in modules file
+@cindex -o, in modules file
+@cindex -e, in modules file
+
+@noindent
+For checkout, rtag, and export, the program is server-based, and as such the
+following applies:-
+
+If using remote access methods (pserver, ext, etc.),
+@sc{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.
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Wrappers
+@appendixsec The cvswrappers file
+@cindex cvswrappers (admin file)
+@cindex CVSWRAPPERS, environment variable
+@cindex Wrappers
+
+@c FIXME: need some better way of separating this out
+@c by functionality. -m is
+@c one feature, and -k is a another. And this discussion
+@c should be better motivated (e.g. start with the
+@c problems, then explain how the feature solves it).
+
+Wrappers refers to a @sc{cvs} feature which lets you
+control certain settings based on the name of the file
+which is being operated on. The settings are @samp{-k}
+for binary files, and @samp{-m} for nonmergeable text
+files.
+
+The @samp{-m} option
+specifies the merge methodology that should be used when
+a non-binary file is updated. @code{MERGE} means the usual
+@sc{cvs} behavior: try to merge the files. @code{COPY}
+means that @code{cvs update} will refuse to merge
+files, as it also does for files specified as binary
+with @samp{-kb} (but if the file is specified as
+binary, there is no need to specify @samp{-m 'COPY'}).
+@sc{cvs} will provide the user with the
+two versions of the files, and require the user using
+mechanisms outside @sc{cvs}, to insert any necessary
+changes.
+
+@strong{WARNING: do not use @code{COPY} with
+@sc{cvs} 1.9 or earlier - such versions of @sc{cvs} will
+copy one version of your file over the other, wiping
+out the previous contents.}
+@c Ordinarily we don't document the behavior of old
+@c versions. But this one is so dangerous, I think we
+@c must. I almost renamed it to -m 'NOMERGE' so we
+@c could say "never use -m 'COPY'".
+The @samp{-m} wrapper option only affects behavior when
+merging is done on update; it does not affect how files
+are stored. See @ref{Binary files}, for more on
+binary files.
+
+The basic format of the file @file{cvswrappers} is:
+
+@c FIXME: @example is all wrong for this. Use @deffn or
+@c something more sensible.
+@example
+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.
+@end example
+
+@ignore
+@example
+*.nib -f 'unwrap %s' -t 'wrap %s %s' -m 'COPY'
+*.c -t 'indent %s %s'
+@end example
+@c When does the filter need to be an absolute pathname
+@c and when will something like the above work? I
+@c suspect it relates to the PATH of the server (which
+@c in turn depends on all kinds of stuff, e.g. inetd
+@c for pserver). I'm not sure whether/where to discuss
+@c this.
+@c FIXME: What do the %s's stand for?
+
+@noindent
+The above example of a @file{cvswrappers} file
+states that all files/directories that end with a @code{.nib}
+should be filtered with the @file{wrap} program before
+checking the file into the repository. The file should
+be filtered though the @file{unwrap} program when the
+file is checked out of the repository. The
+@file{cvswrappers} file also states that a @code{COPY}
+methodology should be used when updating the files in
+the repository (that is, no merging should be performed).
+
+@c What pitfalls arise when using indent this way? Is
+@c it a winning thing to do? Would be nice to at least
+@c hint at those issues; we want our examples to tell
+@c how to solve problems, not just to say that cvs can
+@c do certain things.
+The last example line says that all files that end with
+@code{.c} should be filtered with @file{indent}
+before being checked into the repository. Unlike the previous
+example, no filtering of the @code{.c} file is done when
+it is checked out of the repository.
+@noindent
+The @code{-t} filter is called with two arguments,
+the first is the name of the file/directory to filter
+and the second is the pathname to where the resulting
+filtered file should be placed.
+
+@noindent
+The @code{-f} filter is called with one argument,
+which is the name of the file to filter from. The end
+result of this filter will be a file in the users directory
+that they can work on as they normally would.
+
+Note that the @samp{-t}/@samp{-f} features do not
+conveniently handle one portion of @sc{cvs}'s operation:
+determining when files are modified. @sc{cvs} will still
+want a file (or directory) to exist, and it will use
+its modification time to determine whether a file is
+modified. If @sc{cvs} erroneously thinks a file is
+unmodified (for example, a directory is unchanged but
+one of the files within it is changed), you can force
+it to check in the file anyway by specifying the
+@samp{-f} option to @code{cvs commit} (@pxref{commit
+options}).
+@c This is, of course, a serious design flaw in -t/-f.
+@c Probably the whole functionality needs to be
+@c redesigned (starting from requirements) to fix this.
+@end ignore
+
+@c FIXME: We don't document -W or point to where it is
+@c documented. Or .cvswrappers.
+For example, the following command imports a
+directory, treating files whose name ends in
+@samp{.exe} as binary:
+
+@example
+cvs import -I ! -W "*.exe -k 'b'" first-dir vendortag reltag
+@end example
+
+@c Another good example, would be storing files
+@c (e.g. binary files) compressed in the repository.
+@c ::::::::::::::::::
+@c cvswrappers
+@c ::::::::::::::::::
+@c *.t12 -m 'COPY'
+@c *.t[0-9][0-9] -f 'gunzipcp %s' -t 'gzipcp %s %s' -m 'COPY'
+@c
+@c ::::::::::::::::::
+@c gunzipcp
+@c ::::::::::::::::::
+@c :
+@c [ -f $1 ] || exit 1
+@c zcat $1 > /tmp/.#$1.$$
+@c mv /tmp/.#$1.$$ $1
+@c
+@c ::::::::::::::::::
+@c gzipcp
+@c ::::::::::::::::::
+@c :
+@c DIRNAME=`echo $1 | sed -e "s|/.*/||g"`
+@c if [ ! -d $DIRNAME ] ; then
+@c DIRNAME=`echo $1 | sed -e "s|.*/||g"`
+@c fi
+@c gzip -c $DIRNAME > $2
+@c One catch--"cvs diff" will not invoke the wrappers
+@c (probably a CVS bug, although I haven't thought it out).
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Trigger Scripts
+@appendixsec The Trigger Scripts
+@cindex info files
+@cindex trigger scripts
+@cindex script hooks
+
+@c FIXME
+@c Somewhere there needs to be a more "how-to" guide to writing these.
+@c One particular issue that people sometimes are worried about is performance,
+@c and the impact of writing in perl or sh or ____. Performance comparisons
+@c should probably remain outside the scope of this document, but at least
+@c _that_ much could be referenced, perhaps with links to other sources.
+
+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 @sc{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.
+
+@menu
+* syntax:: The common syntax
+* Trigger Script Security:: Trigger script security
+
+* commit files:: The commit support files (commitinfo,
+ verifymsg, loginfo)
+* commitinfo:: Pre-commit checking
+* verifymsg:: How are log messages evaluated?
+* loginfo:: Where should log messages be sent?
+
+* postadmin:: Logging admin commands
+* taginfo:: Verifying/Logging tags
+* posttag:: Logging tags
+* postwatch:: Logging watch commands
+
+* preproxy:: Launch a script on a secondary server prior
+ to becoming a write proxy
+* postproxy:: Launch a script on a secondary server after
+ completing proxy operations
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node syntax
+@appendixsubsec The common syntax
+@cindex info files, common syntax
+@cindex script hooks, common syntax
+@cindex trigger script hooks, common syntax
+@cindex syntax of trigger script hooks
+
+@c FIXME: having this so totally separate from the
+@c Variables node is rather bogus.
+
+The administrative files such as @file{commitinfo},
+@file{loginfo}, @file{rcsinfo}, @file{verifymsg}, etc.,
+all have a common format. The purpose of the files are
+described later on. The common syntax is described
+here.
+
+@cindex Regular expression syntax
+Each line contains the following:
+
+@itemize @bullet
+@cindex @samp{ALL} keyword, in lieu of regular expressions in script hooks
+@cindex @samp{DEFAULT} keyword, in lieu of regular expressions in script hooks
+@item
+A regular expression or the literal string @samp{DEFAULT}. Some script hooks
+also support the literal string @samp{ALL}. Other than the @samp{ALL} and
+@samp{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 @samp{ALL} keyword is supported
+(@pxref{Trigger Scripts}).
+@c FIXME: What we probably should be saying is "POSIX Basic
+@c Regular Expression with the following extensions (`\('
+@c `\|' '+' etc)"
+@c rather than define it with reference to emacs.
+@c The reference to emacs is not strictly speaking
+@c true, as we don't support \=, \s, or \S. Also it isn't
+@c clear we should document and/or promise to continue to
+@c support all the obscure emacs extensions like \<.
+@c Also need to better cite (or include) full
+@c documentation for the syntax.
+@c Also see comment in configure.in about what happens to the
+@c syntax if we pick up a system-supplied regexp matcher.
+
+@item
+A whitespace separator---one or more spaces and/or tabs.
+
+@item
+A file name or command-line template.
+@end itemize
+
+@noindent
+Blank lines are ignored. Lines that start with the
+character @samp{#} are treated as comments. Long lines
+unfortunately can @emph{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 @samp{DEFAULT}
+in lieu of a regular expression is used and all lines containing @samp{ALL} is
+used for the hooks which support the @samp{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
+@samp{ALL} keyword is supported (@pxref{Trigger Scripts}).
+
+@cindex format strings
+@cindex format strings, common syntax
+@cindex info files, common syntax, format strings
+@cindex Common syntax of info files, format strings
+@noindent
+@emph{Note: The following information on format strings is valid
+as long as the line @code{UseNewInfoFmtStrings=yes} appears in
+your repository's config file (@pxref{config}). Otherwise,
+default format strings may be appended to the command line and
+the @samp{loginfo} file, especially, can exhibit slightly
+different behavior. For more information,
+@xref{Updating Commit Files}.}
+
+In the cases where the second segment of the matched line is a
+command line template (e.g. @file{commitinfo}, @file{loginfo},
+& @file{verifymsg}), the command line template may contain format
+strings which will be replaced with specific values before the
+script is run.
+@c FIXCVS then FIXME - it really would make sense to allow %r & maybe even %p
+@c to be used in rcsinfo to construct a path, but I haven't
+@c coded this yet.
+
+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 @samp{%} character followed by an optional
+@samp{@{} (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 @samp{@}} when the open bracket was present.
+
+@emph{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.
+
+@emph{List attributes} will generate an argument for each attribute
+requested for each list item. For example, @samp{%@{sVv@}}
+in a @file{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.
+
+@samp{%%} will be replaced with a literal @samp{%}.
+
+The format strings available to all script hooks are:
+
+@table @t
+@item c
+The canonical name of the command being executed. For instance, in the case of
+a hook run from @code{cvs up}, @sc{cvs} would replace @samp{%c} with the string
+@samp{update} and, in the case of a hook run from @code{cvs ci}, @sc{cvs} would
+replace @samp{%c} with the string @samp{commit}.
+@item n
+The null, or empty, string.
+@item p
+The name of the directory being operated on within the repository.
+@item r
+The name of the repository (the path portion of @code{$CVSROOT}).
+@item 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.
+@end table
+
+Other format strings are file specific. See the docs on the
+particular script hooks for more information
+(@pxref{Trigger Scripts}).
+
+As an example, the following line in a @file{loginfo} file would
+match only the directory @file{module} and any subdirectories of
+@file{module}:
+
+@example
+^module\(/\|$\) (echo; echo %p; echo %@{sVv@}; cat) >>$CVSROOT/CVSROOT/commitlog
+@end example
+
+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:
+
+@example
+
+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.
+@end example
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node Trigger Script Security
+@appendixsubsec Security and the Trigger Scripts
+@cindex info files, security
+@cindex script hooks, security
+@cindex trigger scripts, security
+
+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 @code{-T}, or "taint-check" switch on their @code{#!} line.
+In the most basic terms, this causes Perl to avoid running code that may have
+come from an external source. Please run the @code{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.
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node commit files
+@appendixsubsec The commit support files
+@cindex Commits, administrative support files
+@cindex commit files, see Info files
+
+The @samp{-i} flag in the @file{modules} file can be
+used to run a certain program whenever files are
+committed (@pxref{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.
+
+@table @file
+@item 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. @xref{commitinfo}.
+
+@item 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
+@file{rcsinfo} file, which can hold a log message
+template (@pxref{rcsinfo}). @xref{verifymsg}.
+
+@item 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@dots{} Your
+imagination is the limit! @xref{loginfo}.
+@end table
+
+@menu
+* Updating Commit Files:: Updating legacy repositories to stop using
+ deprecated command line template formats
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node Updating Commit Files
+@appendixsubsubsec Updating legacy repositories to stop using deprecated command line template formats
+@cindex info files, common syntax, updating legacy repositories
+@cindex Syntax of info files, updating legacy repositories
+@cindex Common syntax of info files, updating legacy repositories
+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 @file{commitinfo}, @file{editinfo}, @file{verifymsg},
+@file{loginfo}, and/or @file{taginfo} script hooks, you should have no
+immediate problems with using the current @sc{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
+@file{loginfo} & @file{notify} style format strings (@pxref{syntax})
+and this support is not completely compatible with the old style format
+strings.
+
+The quick upgrade method is to stick a @samp{1} after each format string
+in your old @file{loginfo} file. For example:
+
+@example
+DEFAULT (echo ""; id; echo %@{sVv@}; date; cat) >> $CVSROOT/CVSROOT/commitlog
+@end example
+
+would become:
+
+@example
+DEFAULT (echo ""; id; echo %1@{sVv@}; date; cat) >> $CVSROOT/CVSROOT/commitlog
+@end example
+
+If you were counting on the fact that only the first @samp{%} 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 (@pxref{config}):
+@example
+UseNewInfoFmtStrings=yes
+@end example
+
+Everything should still be running properly, but your users will probably
+start seeing new deprecation warnings.
+
+Dealing with the deprecation warnings now generated by @file{commitinfo},
+@file{editinfo}, @file{verifymsg}, and @file{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:
+@table @code
+@item commitinfo
+@samp{ %r/%p %s}
+@item editinfo
+@samp{ %l}
+@item taginfo
+@samp{ %t %o %p %@{sv@}}
+@item verifymsg
+@samp{ %l}
+@end table
+
+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
+@sc{cvs}'s format strings.
+
+Fixing @file{loginfo} could be a little tougher. The old style
+@file{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 @samp{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 @samp{1} from
+your @file{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 @samp{%} followed by unrecognized characters and by
+@samp{@{@}} was treated in past versions of CVS is not strictly adhered to as
+there were bugs in the old versions. Specifically, @samp{%@{@}} 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 @samp{%@{sVv@}}, e.g. @samp{%@{sVv@}}, @samp{%@{sV@}}, or
+@samp{%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 @sc{cvs}, so you can just
+put up with the deprecation warnings for awhile if you like.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node commitinfo
+@appendixsubsec Commitinfo
+@cindex @file{commitinfo}
+@cindex Commits, precommit verification of
+@cindex commitinfo (admin file)
+@cindex info files, commitinfo
+@cindex script hooks, commitinfo
+@cindex trigger scripts, commitinfo
+@cindex info files, precommit verification of commits
+@cindex script hooks, precommit verification of commits
+@cindex trigger scripts, precommit verification of commits
+
+The @file{commitinfo} file defines programs to execute
+whenever @samp{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 @file{commitinfo} file has the standard form for script hooks
+(@pxref{Trigger Scripts}), where each line is a regular expression followed by
+a command to execute. It supports only the DEFAULT keywords.
+
+@cindex format strings, commitinfo admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{commitinfo} supports:
+
+@table @t
+@item @{s@}
+a list of the names of files to be committed
+@end table
+
+@cindex commitinfo (admin file), updating legacy repositories
+@cindex compatibility notes, commitinfo admin file
+Currently, if no format strings are specified, a default
+string of @samp{ %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 @sc{cvs} application.
+For information on updating, @pxref{Updating Commit Files}.
+
+@cindex Exit status, of commitinfo
+@cindex commitinfo (admin file), exit status
+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.
+@c FIXME: need example(s) of what "directory within the
+@c repository" means.
+
+@cindex @file{commitinfo}, working directory
+@cindex @file{commitinfo}, command environment
+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), @emph{or in a copy of the workspace on
+the server (@pxref{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 (@pxref{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.
+
+@c FIXME: should discuss using commitinfo to control
+@c who has checkin access to what (e.g. Joe can check into
+@c directories a, b, and c, and Mary can check into
+@c directories b, c, and d--note this case cannot be
+@c conveniently handled with unix groups). Of course,
+@c adding a new set of features to CVS might be a more
+@c natural way to fix this problem than telling people to
+@c use commitinfo.
+@c FIXME: Should make some reference, especially in
+@c the context of controlling who has access, to the fact
+@c that commitinfo can be circumvented. Perhaps
+@c mention SETXID (but has it been carefully examined
+@c for holes?). This fits in with the discussion of
+@c general CVS security in "Password authentication
+@c security" (the bit which is not pserver-specific).
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node verifymsg
+@appendixsubsec Verifying log messages
+@cindex @file{verifymsg} (admin file)
+@cindex Log message, verifying
+@cindex logging, commits
+
+Once you have entered a log message, you can evaluate
+that message to check for specific content, such as
+a bug ID. Use the @file{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 @file{verifymsg} file is often most useful together
+with the @file{rcsinfo} file, which can be used to
+specify a log message template (@pxref{rcsinfo}).
+
+The @file{verifymsg} file has the standard form for script hooks
+(@pxref{Trigger Scripts}), where each line is a regular expression followed by
+a command to execute. It supports only the DEFAULT keywords.
+
+@cindex format strings, verifymsg admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{verifymsg} supports:
+
+@table @t
+@item l
+the full path to the file containing the log message to be verified
+@item @{sV@}
+File attributes, where:
+@table @t
+@item s
+file name
+@item V
+old version number (pre-checkin)
+@end table
+@end table
+
+@cindex verifymsg (admin/commit file), updating legacy repositories
+@cindex compatibility notes, verifymsg admin file
+Currently, if no format strings are specified, a default
+string of @samp{ %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 @sc{cvs} application.
+For information on updating, @pxref{Updating Commit Files}.
+
+One thing that should be noted is that the @samp{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.
+
+@cindex Exit status, of @file{verifymsg}
+If the verification script exits with a non-zero exit status,
+the commit is aborted.
+
+@cindex @file{verifymsg}, changing the log message
+In the default configuration, CVS allows the
+verification script to change the log message. This is
+controlled via the RereadLogAfterVerify CVSROOT/config
+option.
+
+When @samp{RereadLogAfterVerify=always} or
+@samp{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.
+
+@xref{config}, for more on CVSROOT/config options.
+
+It is NOT a good idea for a @file{verifymsg} script to
+interact directly with the user in the various
+client/server methods. For the @code{pserver} method,
+there is no protocol support for communicating between
+@file{verifymsg} and the client on the remote end. For the
+@code{ext} and @code{server} methods, it is possible
+for CVS to become confused by the characters going
+along the same channel as the CVS protocol
+messages. See @ref{Remote repositories}, for more
+information on client/server setups. In addition, at the time
+the @file{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 @file{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.
+
+@menu
+* verifymsg example:: Verifymsg example
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node verifymsg example
+@appendixsubsubsec Verifying log messages
+@cindex verifymsg, example
+The following is a little silly example of a
+@file{verifymsg} file, together with the corresponding
+@file{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
+@file{/usr/cvssupport/tc.template}.
+
+@example
+BugId:
+@end example
+
+The script @file{/usr/cvssupport/bugid.verify} is used to
+evaluate the log message.
+
+@example
+#!/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
+@end example
+
+The @file{verifymsg} file contains this line:
+
+@example
+^tc /usr/cvssupport/bugid.verify %l
+@end example
+
+The @file{rcsinfo} file contains this line:
+
+@example
+^tc /usr/cvssupport/tc.template
+@end example
+
+The @file{config} file contains this line:
+
+@example
+RereadLogAfterVerify=always
+@end example
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node loginfo
+@appendixsubsec Loginfo
+@cindex loginfo (admin file)
+@cindex logging, commits
+@cindex Storing log messages
+@cindex Mailing log messages
+@cindex Distributing log messages
+@cindex Log messages
+
+The @file{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. @ref{posttag} for how to log tagging
+information and @ref{postadmin} for how to log changes due to the @code{admin}
+command.
+
+The @file{loginfo} file has the standard form for script hooks
+(@pxref{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:
+
+@table @code
+@item commit
+Once per directory, immediately after a successfully completing the commit of
+all files within that directory.
+@item import
+Once per import, immediately after completion of all write operations.
+@item add
+Immediately after the successful @code{add} of a directory.
+@end table
+
+Any script called via @file{loginfo} will be fed the log information on its
+standard input. Note that the filter program @strong{must} read @strong{all}
+of the log information from its standard input or @sc{cvs} may fail with a
+broken pipe signal.
+
+@cindex format strings, loginfo admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{loginfo} supports:
+
+@table @t
+@item @{stVv@}
+File attributes, where:
+@table @t
+@item s
+file name
+@item T
+tag name of destination, or the empty string when there is no associated
+tag name (this usually means the trunk)
+@item V
+old version number (pre-checkin)
+@item v
+new version number (post-checkin)
+@end table
+@end table
+
+For example, some valid format strings are @samp{%%},
+@samp{%s}, @samp{%@{s@}}, and @samp{%@{stVv@}}.
+
+@cindex loginfo (admin file), updating legacy repositories
+@cindex compatibility notes, loginfo admin file
+Currently, if @samp{UseNewInfoFmtStrings} is not set in the @file{config}
+administration file (@pxref{config}), the format strings will be substituted
+as they were in past versions of @sc{cvs}, but this feature is deprecated.
+It is simply in place so that legacy repositories will remain compatible with
+the new @sc{cvs} application. For information on updating,
+please see @ref{Updating Commit Files}.
+
+As an example, if @samp{/u/src/master/yoyodyne/tc} is the repository, @samp{%p}
+and @samp{%@{sVv@}} are the format strings, and three files (@t{ChangeLog},
+@t{Makefile}, @t{foo.c}) were modified, the output might be:
+
+@example
+yoyodyne/tc ChangeLog 1.1 1.2 Makefile 1.3 1.4 foo.c 1.12 1.13
+@end example
+
+Note: when @sc{cvs} is accessing a remote repository,
+@file{loginfo} will be run on the @emph{remote}
+(i.e., server) side, not the client side (@pxref{Remote
+repositories}).
+
+@menu
+* loginfo example:: Loginfo example
+* Keeping a checked out copy:: Updating a tree on every checkin
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node loginfo example
+@appendixsubsubsec Loginfo example
+
+The following @file{loginfo} file, together with the
+tiny shell-script below, appends all log messages
+to the file @file{$CVSROOT/CVSROOT/commitlog},
+and any commits to the administrative files (inside
+the @file{CVSROOT} directory) are also logged in
+@file{/usr/adm/cvsroot-log}.
+Commits to the @file{prog1} directory are mailed to @t{ceder}.
+
+@c FIXME: is it a CVS feature or bug that only the
+@c first matching line is used? It is documented
+@c above, but is it useful? For example, if we wanted
+@c to run both "cvs-log" and "Mail" for the CVSROOT
+@c directory, it is kind of awkward if
+@c only the first matching line is used.
+@example
+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
+@end example
+
+The shell-script @file{/usr/local/bin/cvs-log} looks
+like this:
+
+@example
+#!/bin/sh
+(echo "------------------------------------------------------";
+ echo -n "$2 ";
+ date;
+ echo;
+ cat) >> $1
+@end example
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Keeping a checked out copy
+@appendixsubsubsec Keeping a checked out copy
+
+@c What other index entries? It seems like
+@c people might want to use a lot of different
+@c words for this functionality.
+@cindex Keeping a checked out copy
+@cindex Checked out copy, keeping
+@cindex Web pages, maintaining with CVS
+
+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 @sc{cvs} and want every checkin to cause the files
+used by the web server to be updated.
+@c Can we offer more details on the web example? Or
+@c point the user at how to figure it out? This text
+@c strikes me as sufficient for someone who already has
+@c some idea of what we mean but not enough for the naive
+@c user/sysadmin to understand it and set it up.
+
+The way to do this is by having loginfo invoke
+@code{cvs update}. Doing so in the naive way will
+cause a problem with locks, so the @code{cvs update}
+must be run in the background.
+@c Should we try to describe the problem with locks?
+@c It seems like a digression for someone who just
+@c wants to know how to make it work.
+@c Another choice which might work for a single file
+@c is to use "cvs -n update -p" which doesn't take
+@c out locks (I think) but I don't see many advantages
+@c of that and we might as well document something which
+@c works for multiple files.
+Here is an example for unix (this should all be on one line):
+
+@example
+^cyclic-pages\(/\|$\) (date; cat; (sleep 2; cd /u/www/local-docs;
+ cvs -q update -d) &) >> $CVSROOT/CVSROOT/updatelog 2>&1
+@end example
+
+This will cause checkins to repository directory @code{cyclic-pages}
+and its subdirectories to update the checked
+out tree in @file{/u/www/local-docs}.
+@c More info on some of the details? The "sleep 2" is
+@c so if we are lucky the lock will be gone by the time
+@c we start and we can wait 2 seconds instead of 30.
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node postadmin
+@appendixsubsec Logging admin commands
+@cindex postadmin (admin file)
+@cindex script hook, postadmin
+@cindex Admin commands, logging
+
+The @file{postadmin} file defines programs to execute after an @code{admin}
+command modifies files. The @file{postadmin} file has the standard form
+for script hooks (@pxref{Trigger Scripts}), where each line is a regular
+expression followed by a command to execute. It supports the ALL and DEFAULT
+keywords.
+
+@cindex format strings, postadmin admin file
+The @file{postadmin} file supports no format strings other than the common
+ones (@pxref{syntax}),
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node taginfo
+@appendixsubsec Taginfo
+@cindex taginfo (admin file)
+@cindex script hook, taginfo
+@cindex Tags, logging
+@cindex Tags, verifying
+The @file{taginfo} file defines programs to execute
+when someone executes a @code{tag} or @code{rtag}
+command. The @file{taginfo} file has the standard form
+for script hooks (@pxref{Trigger Scripts}), where each line
+is a regular expression followed by a command to execute.
+It supports the ALL and DEFAULT keywords.
+
+@cindex format strings, taginfo admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{taginfo} supports:
+
+@table @t
+@item b
+tag type (@code{T} for branch, @code{N} for not-branch, or @code{?} for
+unknown, as during delete operations)
+@item o
+operation (@code{add} for @code{tag}, @code{mov} for @code{tag -F}, or
+@code{del} for @code{tag -d})
+@item t
+new tag name
+@item @{sTVv@}
+file attributes, where:
+@table @t
+@item s
+file name
+@item T
+tag name of destination, or the empty string when there is no associated
+tag name (this usually means the trunk)
+@item V
+old version number (for a move or delete operation)
+@item v
+new version number (for an add or move operation)
+@end table
+@end table
+
+For example, some valid format strings are @samp{%%}, @samp{%p}, @samp{%t},
+@samp{%s}, @samp{%@{s@}}, and @samp{%@{sVv@}}.
+
+@cindex taginfo (admin file), updating legacy repositories
+@cindex compatibility notes, taginfo admin file
+Currently, if no format strings are specified, a default
+string of @samp{ %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 @sc{cvs} application.
+For information on updating, @pxref{Updating Commit Files}.
+
+@cindex Exit status, of taginfo admin file
+@cindex taginfo (admin file), exit status
+A non-zero exit of the filter program will cause the tag to be
+aborted.
+
+Here is an example of using @file{taginfo} to log @code{tag} and @code{rtag}
+commands. In the @file{taginfo} file put:
+
+@example
+ALL /usr/local/cvsroot/CVSROOT/loggit %t %b %o %p %@{sVv@}
+@end example
+
+@noindent
+Where @file{/usr/local/cvsroot/CVSROOT/loggit} contains the
+following script:
+
+@example
+#!/bin/sh
+echo "$@@" >>/home/kingdon/cvsroot/CVSROOT/taglog
+@end example
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node posttag
+@appendixsubsec Logging tags
+@cindex posttag (admin file)
+@cindex script hook, posttag
+@cindex Tags, logging
+
+The @file{posttag} file defines programs to execute after a @code{tag} or
+@code{rtag} command modifies files. The @file{posttag} file has the standard
+form for script hooks (@pxref{Trigger Scripts}), where each line is a regular
+expression followed by a command to execute. It supports the ALL and DEFAULT
+keywords.
+
+@cindex format strings, posttag admin file
+The @file{posttag} admin file supports the same format strings as the
+@file{taginfo} file (@pxref{taginfo}),
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node postwatch
+@appendixsubsec Logging watch commands
+@cindex postwatch (admin file)
+@cindex script hook, postwatch
+@cindex Watch family of commands, logging
+
+The @file{postwatch} file defines programs to execute after any command (for
+instance, @code{watch}, @code{edit}, @code{unedit}, or @code{commit}) modifies
+any @file{CVS/fileattr} file in the repository (@pxref{Watches}). The
+@file{postwatch} file has the standard form for script hooks
+(@pxref{Trigger Scripts}), where each line is a regular expression followed by
+a command to execute. It supports the ALL and DEFAULT keywords.
+
+@cindex format strings, postwatch admin file
+The @file{postwatch} file supports no format strings other than the common
+ones (@pxref{syntax}), but it is worth noting that the @code{%c} format string
+may not be replaced as you might expect. Client runs of @code{edit} and
+@code{unedit} can sometimes skip contacting the @sc{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,
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node preproxy
+@appendixsubsec Launch a Script before Proxying
+@cindex preproxy (admin file)
+@cindex script hook, preproxy
+@cindex Write proxy, verifying
+@cindex Write proxy, logging
+
+The @file{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.
+
+@file{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 @file{preproxy} file has the standard form
+for script hooks (@pxref{Trigger Scripts}), where each line is a regular
+expression followed by a command to execute. It supports the ALL and DEFAULT
+keywords.
+
+@cindex format strings, preproxy admin file
+In addition to the common format strings, the @file{preproxy} file supports the
+following format string:
+
+@table @t
+@item P
+the CVSROOT string which specifies the primary server
+@end table
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node postproxy
+@appendixsubsec Launch a Script after Proxying
+@cindex postproxy (admin file)
+@cindex script hook, postproxy
+@cindex Write proxy, logging
+@cindex Write proxy, pull updates
+@cindex secondary server, pull updates
+
+The @file{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.
+
+@file{postproxy} scripts are called once per directory.
+
+The @file{postproxy} file has the standard form
+for script hooks (@pxref{Trigger Scripts}), where each line is a regular
+expression followed by a command to execute. It supports the ALL and DEFAULT
+keywords.
+
+@cindex format strings, postproxy admin file
+In addition to the common format strings, the @file{postproxy} file supports
+the following format string:
+
+@table @t
+@item P
+the CVSROOT string which specifies the primary server
+@end table
+
+
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node rcsinfo
+@appendixsec Rcsinfo
+@cindex rcsinfo (admin file)
+@cindex Form for log message
+@cindex Log message template
+@cindex Template for log message
+@cindex logging, commits
+
+The @file{rcsinfo} file can be used to specify a form to
+edit when filling out the commit log. The
+@file{rcsinfo} file has a syntax similar to the
+@file{verifymsg}, @file{commitinfo} and @file{loginfo}
+files. @xref{syntax}. Unlike the other files the second
+part is @emph{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 @samp{DEFAULT}
+line is used, if it is specified.
+
+All occurrences of the name @samp{ALL} appearing as a
+regular expression are used in addition to the first
+matching regular expression or @samp{DEFAULT}.
+
+@c FIXME: should be offering advice, somewhere around
+@c here, about where to put the template file. The
+@c verifymsg example uses /usr/cvssupport but doesn't
+@c say anything about what that directory is for or
+@c whether it is hardwired into CVS or who creates
+@c it or anything. In particular we should say
+@c how to version control the template file. A
+@c probably better answer than the /usr/cvssupport
+@c stuff is to use checkoutlist (with xref to the
+@c checkoutlist doc).
+@c Also I am starting to see a connection between
+@c this and the Keeping a checked out copy node.
+@c Probably want to say something about that.
+The log message template will be used as a default log
+message. If you specify a log message with @samp{cvs
+commit -m @var{message}} or @samp{cvs commit -f
+@var{file}} that log message will override the
+template.
+
+@xref{verifymsg}, for an example @file{rcsinfo}
+file.
+
+When @sc{cvs} is accessing a remote repository,
+the contents of @file{rcsinfo} at the time a directory
+is first checked out will specify a template. This
+template will be updated on all @samp{cvs update}
+commands. It will also be added to new directories
+added with a @samp{cvs add new-directory} command.
+In versions of @sc{cvs} prior to version 1.12, the
+@file{CVS/Template} file was not updated. If the
+@sc{cvs} server is at version 1.12 or higher an older
+client may be used and the @file{CVS/Template} will
+be updated from the server.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node cvsignore
+@appendixsec Ignoring files via cvsignore
+@cindex cvsignore (admin file), global
+@cindex Global cvsignore
+@cindex Ignoring files
+@c -- This chapter should maybe be moved to the
+@c tutorial part of the manual?
+
+There are certain file names that frequently occur
+inside your working copy, but that you don't want to
+put under @sc{cvs} control. Examples are all the object
+files that you get while you compile your sources.
+Normally, when you run @samp{cvs update}, it prints a
+line for each file it encounters that it doesn't know
+about (@pxref{update output}).
+
+@sc{cvs} has a list of files (or sh(1) file name patterns)
+that it should ignore while running @code{update},
+@code{import} and @code{release}.
+@c -- Are those the only three commands affected?
+This list is constructed in the following way.
+
+@itemize @bullet
+@item
+The list is initialized to include certain file name
+patterns: names associated with @sc{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:
+
+@cindex Ignored files
+@cindex Automatically ignored files
+@example
+ 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
+@end example
+
+@item
+The per-repository list in
+@file{$CVSROOT/CVSROOT/cvsignore} is appended to
+the list, if that file exists.
+
+@item
+The per-user list in @file{.cvsignore} in your home
+directory is appended to the list, if it exists.
+
+@item
+Any entries in the environment variable
+@code{$CVSIGNORE} is appended to the list.
+
+@item
+Any @samp{-I} options given to @sc{cvs} is appended.
+
+@item
+As @sc{cvs} traverses through your directories, the contents
+of any @file{.cvsignore} will be appended to the list.
+The patterns found in @file{.cvsignore} are only valid
+for the directory that contains them, not for
+any sub-directories.
+@end itemize
+
+In any of the 5 places listed above, a single
+exclamation mark (@samp{!}) clears the ignore list.
+This can be used if you want to store any file which
+normally is ignored by @sc{cvs}.
+
+Specifying @samp{-I !} to @code{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 @file{.cvsignore} files, then
+the patterns from those files will be processed even if
+@samp{-I !} is specified. The only workaround is to
+remove the @file{.cvsignore} files in order to do the
+import. Because this is awkward, in the future
+@samp{-I !} might be modified to override
+@file{.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 @file{foo?bar} to match a file
+named @file{foo bar} (it also matches @file{fooxbar}
+and the like). Also note that there is currently no
+way to specify comments.
+@c FIXCVS? I don't _like_ this syntax at all, but
+@c changing it raises all the usual compatibility
+@c issues and I'm also not sure what to change it to.
+
+@node checkoutlist
+@appendixsec The checkoutlist file
+@cindex checkoutlist
+
+It may be helpful to use @sc{cvs} to maintain your own
+files in the @file{CVSROOT} directory. For example,
+suppose that you have a script @file{logcommit.pl}
+which you run by including the following line in the
+@file{commitinfo} administrative file:
+
+@example
+ALL $CVSROOT/CVSROOT/logcommit.pl %r/%p %s
+@end example
+
+To maintain @file{logcommit.pl} with @sc{cvs} you would
+add the following line to the @file{checkoutlist}
+administrative file:
+
+@example
+logcommit.pl
+@end example
+
+The format of @file{checkoutlist} is one line for each
+file that you want to maintain using @sc{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:
+
+@example
+logcommit.pl Could not update CVSROOT/logcommit.pl.
+@end example
+
+After setting up @file{checkoutlist} in this fashion,
+the files listed there will function just like
+@sc{cvs}'s built-in administrative files. For example,
+when checking in one of the files you should get a
+message such as:
+
+@example
+cvs commit: Rebuilding administrative file database
+@end example
+
+@noindent
+and the checked out copy in the @file{CVSROOT}
+directory should be updated.
+
+Note that listing @file{passwd} (@pxref{Password
+authentication server}) in @file{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
+@file{checkoutlist}, see @ref{Keeping a checked out
+copy}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node history file
+@appendixsec The history file
+@cindex History file
+@cindex Log information, saving
+
+By default, the file @file{$CVSROOT/CVSROOT/history} is used
+to log information for the @code{history} command (@pxref{history}).
+This file name may be changed with the @samp{HistoryLogPath} and
+@samp{HistorySearchPath} config options (@pxref{config}).
+
+The file format of the @file{history} file is
+documented only in comments in the @sc{cvs} source
+code, but generally programs should use the @code{cvs
+history} command to access it anyway, in case the
+format changes with future releases of @sc{cvs}.
+
+@node Variables
+@appendixsec Expansions in administrative files
+@cindex Internal variables
+@cindex Variables
+
+Sometimes in writing an administrative file, you might
+want the file to be able to know various things based
+on environment @sc{cvs} is running in. There are
+several mechanisms to do that.
+
+To find the home directory of the user running @sc{cvs}
+(from the @code{HOME} environment variable), use
+@samp{~} followed by @samp{/} or the end of the line.
+Likewise for the home directory of @var{user}, use
+@samp{~@var{user}}. These variables are expanded on
+the server machine, and don't get any reasonable
+expansion if pserver (@pxref{Password authenticated})
+is in use; therefore user variables (see below) may be
+a better choice to customize behavior based on the user
+running @sc{cvs}.
+@c Based on these limitations, should we deprecate ~?
+@c What is it good for? Are people using it?
+
+One may want to know about various pieces of
+information internal to @sc{cvs}. A @sc{cvs} internal
+variable has the syntax @code{$@{@var{variable}@}},
+where @var{variable} starts with a letter and consists
+of alphanumeric characters and @samp{_}. If the
+character following @var{variable} is a
+non-alphanumeric character other than @samp{_}, the
+@samp{@{} and @samp{@}} can be omitted. The @sc{cvs}
+internal variables are:
+
+@table @code
+@item CVSROOT
+@cindex CVSROOT, internal variable
+This is the absolute path to the current @sc{cvs} root directory.
+@xref{Repository}, for a description of the various
+ways to specify this, but note that the internal
+variable contains just the directory and not any
+of the access method information.
+
+@item RCSBIN
+@cindex RCSBIN, internal variable
+In @sc{cvs} 1.9.18 and older, this specified the
+directory where @sc{cvs} was looking for @sc{rcs}
+programs. Because @sc{cvs} no longer runs @sc{rcs}
+programs, specifying this internal variable is now an
+error.
+
+@item CVSEDITOR
+@cindex CVSEDITOR, internal variable
+@itemx EDITOR
+@cindex EDITOR, internal variable
+@itemx VISUAL
+@cindex VISUAL, internal variable
+These all expand to the same value, which is the editor
+that @sc{cvs} is using. @xref{Global options}, for how
+to specify this.
+
+@item USER
+@cindex USER, internal variable
+Username of the user running @sc{cvs} (on the @sc{cvs}
+server machine).
+When using pserver, this is the user specified in the repository
+specification which need not be the same as the username the
+server is running as (@pxref{Password authentication server}).
+Do not confuse this with the environment variable of the same name.
+
+@item SESSIONID
+@cindex COMMITID, internal variable
+Unique Session ID of the @sc{cvs} process. This is a
+random string of printable characters of at least 16
+characters length. Users should assume that it may
+someday grow to at most 256 characters in length.
+
+@item COMMITID
+@cindex COMMITID, internal variable
+Unique Session ID of the @sc{cvs} process. This is a
+random string of printable characters of at least 16
+characters length. Users should assume that it may
+someday grow to at most 256 characters in length.
+@end table
+
+If you want to pass a value to the administrative files
+which the user who is running @sc{cvs} can specify,
+use a user variable.
+@cindex User variables
+To expand a user variable, the
+administrative file contains
+@code{$@{=@var{variable}@}}. To set a user variable,
+specify the global option @samp{-s} to @sc{cvs}, with
+argument @code{@var{variable}=@var{value}}. It may be
+particularly useful to specify this option via
+@file{.cvsrc} (@pxref{~/.cvsrc}).
+
+For example, if you want the administrative file to
+refer to a test directory you might create a user
+variable @code{TESTDIR}. Then if @sc{cvs} is invoked
+as
+
+@example
+cvs -s TESTDIR=/work/local/tests
+@end example
+
+@noindent
+and the
+administrative file contains @code{sh
+$@{=TESTDIR@}/runtests}, then that string is expanded
+to @code{sh /work/local/tests/runtests}.
+
+All other strings containing @samp{$} are reserved;
+there is no way to quote a @samp{$} character so that
+@samp{$} represents itself.
+
+Environment variables passed to administrative files are:
+
+@table @code
+@cindex environment variables, passed to administrative files
+
+@item CVS_USER
+@cindex CVS_USER, environment variable
+The @sc{cvs}-specific username provided by the user, if it
+can be provided (currently just for the pserver access
+method), and to the empty string otherwise. (@code{CVS_USER}
+and @code{USER} may differ when @file{$CVSROOT/CVSROOT/passwd}
+is used to map @sc{cvs} usernames to system usernames.)
+
+@item LOGNAME
+@cindex LOGNAME, environment variable
+The username of the system user.
+
+@item USER
+@cindex USER, environment variable
+Same as @code{LOGNAME}.
+Do not confuse this with the internal variable of the same name.
+@end table
+
+@node config
+@appendixsec The CVSROOT/config configuration file
+
+@cindex configuration file
+@cindex config, in CVSROOT
+@cindex CVSROOT/config
+
+Usually, the @file{config} file is found at @file{$CVSROOT/CVSROOT/config},
+but this may be overridden on the @code{pserver} and @code{server} command
+lines (@pxref{server & pserver}).
+
+The administrative file @file{config} contains various
+miscellaneous settings which affect the behavior of
+@sc{cvs}. The syntax is slightly different from the
+other administrative files.
+
+Leading white space on any line is ignored, though the syntax is very strict
+and will reject spaces and tabs almost anywhere else.
+
+Empty lines, lines containing nothing but white space, and lines which start
+with @samp{#} (discounting any leading white space) are ignored.
+
+@c FIXME: where do we define comments for the other
+@c administrative files.
+Other lines consist of the optional leading white space, a keyword, @samp{=},
+and a value. Please note again that this syntax is very strict.
+Extraneous spaces or tabs, other than the leading white space, are not
+permitted on these lines.
+@c See comments in parseinfo.c:parse_config for more
+@c discussion of this strictness.
+
+As of CVS 1.12.13, lines of the form @samp{[@var{CVSROOT}]} mark the subsequent
+section of the config file as applying only to certain repositories. Multiple
+@samp{[@var{CVSROOT}]} lines without intervening
+@samp{@var{KEYWORD}=@var{VALUE}} pairs cause processing to fall through,
+processing subsequent keywords for any root in the list. Finally, keywords
+and values which appear before any @samp{[@var{CVSROOT}]} lines are defaults,
+and may to apply to any repository. For example, consider the following file:
+
+@example
+# Defaults
+LogHistory=TMAR
+
+[/cvsroots/team1]
+ LockDir=/locks/team1
+
+[/cvsroots/team2]
+ LockDir=/locks/team2
+
+[/cvsroots/team3]
+ LockDir=/locks/team3
+
+[/cvsroots/team4]
+ LockDir=/locks/team4
+
+[/cvsroots/team3]
+[/cvsroots/team4]
+ # Override logged commands for teams 3 & 4.
+ LogHistory=all
+@end example
+
+This example file sets up separate lock directories for each project, as well
+as a default set of logged commands overridden for the example's team 3 &
+team 4. This syntax could be useful, for instance, if you wished to share a
+single config file, for instance @file{/etc/cvs.conf}, among several
+repositories.
+
+Currently defined keywords are:
+
+@table @code
+@cindex HistoryLogPath, in CVSROOT/config
+@item HistorySearchPath=@var{pattern}
+Request that @sc{cvs} look for its history information in files matching
+@var{pattern}, which is a standard UNIX file glob. If @var{pattern} matches
+multiple files, all will be searched in lexicographically sorted order.
+@xref{history}, and @ref{history file}, for more.
+
+If no value is supplied for this option, it defaults to
+@file{$CVSROOT/CVSROOT/history}.
+
+@cindex HistorySearchPath, in CVSROOT/config
+@item HistoryLogPath=@var{path}
+Control where @sc{cvs} logs its history. If the file does not exist, @sc{cvs}
+will attempt to create it. Format strings, as available to the GNU C
+@code{strftime} function and often the UNIX date command, and the string
+@var{$CVSROOT} will be substituted in this path. For example, consider the
+line:
+
+@example
+HistoryLogPath=$CVSROOT/CVSROOT/history/%Y-%m-%d
+@end example
+
+This line would cause @sc{cvs} to attempt to create its history file in a
+subdirectory (@file{history}) of the configuration directory (@file{CVSROOT})
+with a name equal to the current date representation in the ISO8601 format (for
+example, on May 11, 2005, @sc{cvs} would attempt to log its history under the
+repository root directory in a file named @file{CVSROOT/history/2005-05-11}).
+@xref{history}, and @ref{history file}, for more.
+
+If no value is supplied for this option, it defaults to
+@file{$CVSROOT/CVSROOT/history}.
+
+@cindex ImportNewFilesToVendorBranchOnly, in CVSROOT/config
+@cindex import, config admin file
+@cindex config (admin file), import
+@item ImportNewFilesToVendorBranchOnly=@var{value}
+Specify whether @code{cvs import} should always behave as if the
+@samp{-X} flag was specified on the command line.
+@var{value} may be either @samp{yes} or @samp{no}. If set to @samp{yes},
+all uses of @code{cvs import} on the repository will behave as if the
+@samp{-X} flag was set. The default value is @samp{no}.
+
+@cindex KeywordExpand, in CVSROOT/config
+@item KeywordExpand=@var{value}
+Specify @samp{i} followed by a list of keywords to be expanded
+(for example, @samp{KeywordExpand=iMYCVS,Name,Date}),
+or @samp{e} followed by a list of keywords not to be expanded
+(for example, @samp{KeywordExpand=eCVSHeader}).
+For more on keyword expansion, see @ref{Configuring keyword expansion}.
+
+@cindex LocalKeyword, in CVSROOT/config
+@item LocalKeyword=@var{value}
+Specify a local alias for a standard keyword.
+For example, @samp{LocalKeyword=MYCVS=CVSHeader}.
+For more on local keywords, see @ref{Keyword substitution}.
+
+@cindex LockDir, in CVSROOT/config
+@item LockDir=@var{directory}
+Put @sc{cvs} lock files in @var{directory} rather than
+directly in the repository. This is useful if you want
+to let users read from the repository while giving them
+write access only to @var{directory}, not to the
+repository.
+It can also be used to put the locks on a very fast
+in-memory file system to speed up locking and unlocking
+the repository.
+You need to create @var{directory}, but
+@sc{cvs} will create subdirectories of @var{directory} as it
+needs them. For information on @sc{cvs} locks, see
+@ref{Concurrency}.
+
+@c Mention this in Compatibility section?
+Before enabling the LockDir option, make sure that you
+have tracked down and removed any copies of @sc{cvs} 1.9 or
+older. Such versions neither support LockDir, nor will
+give an error indicating that they don't support it.
+The result, if this is allowed to happen, is that some
+@sc{cvs} users will put the locks one place, and others will
+put them another place, and therefore the repository
+could become corrupted. @sc{cvs} 1.10 does not support
+LockDir but it will print a warning if run on a
+repository with LockDir enabled.
+
+@cindex LogHistory, in CVSROOT/config
+@item LogHistory=@var{value}
+Control what is logged to the @file{CVSROOT/history} file (@pxref{history}).
+Default of @samp{TOEFWUPCGMAR} (or simply @samp{all}) will log
+all transactions. Any subset of the default is
+legal. (For example, to only log transactions that modify the
+@file{*,v} files, use @samp{LogHistory=TMAR}.) To disable history logging
+completely, use @samp{LogHistory=}.
+
+@cindex MaxCommentLeaderLength, in CVSROOT/config
+@cindex Log keyword, configuring substitution behavior
+@item MaxCommentLeaderLength=@var{length}
+Set to some length, in bytes, where a trailing @samp{k}, @samp{M}, @samp{G},
+or @samp{T} causes the preceding nubmer to be interpreted as kilobytes,
+megabytes, gigabytes, or terrabytes, respectively, will cause
+@code{$@splitrcskeyword{Log}$} keywords (@pxref{Keyword substitution}), with
+more than @var{length} bytes preceding it on a line to be ignored (or to fall
+back on the comment leader set in the RCS archive file - see
+@code{UseArchiveCommentLeader} below). Defaults to 20 bytes to allow checkouts
+to proceed normally when they include binary files containing
+@code{$@splitrcskeyword{Log}$} keywords and which users have neglected to mark
+as binary.
+
+@cindex MinCompressionLevel, in CVSROOT/config
+@cindex MaxCompressionLevel, in CVSROOT/config
+@cindex Compression levels, restricting on server
+@item MinCompressionLevel=@var{value}
+@itemx MaxCompressionLevel=@var{value}
+Restricts the level of compression used by the @sc{cvs} server to a @var{value}
+between 0 and 9. @var{value}s 1 through 9 are the same @sc{zlib} compression
+levels accepted by the @samp{-z} option (@pxref{Global options}), and 0 means
+no compression. When one or both of these keys are set and a client requests a
+level outside the specified range, the server will simply use the closest
+permissable level. Clients will continue compressing at the level requested by
+the user.
+
+The exception is when level 0 (no compression) is not available and the client
+fails to request any compression. The @sc{cvs} server will then exit with an
+error message when it becomes apparent that the client is not going to request
+compression. This will not happen with clients version 1.12.13 and later since
+these client versions allow the server to notify them that they must request
+some level of compression.
+
+@ignore
+@cindex PreservePermissions, in CVSROOT/config
+@item PreservePermissions=@var{value}
+Enable support for saving special device files,
+symbolic links, file permissions and ownerships in the
+repository. The default value is @samp{no}.
+@xref{Special Files}, for the full implications of using
+this keyword.
+@end ignore
+
+@cindex PrimaryServer, in CVSROOT/config
+@cindex Primary server
+@cindex Secondary server
+@cindex proxy, write
+@cindex write proxy
+@item PrimaryServer=@var{CVSROOT}
+When specified, and the repository specified by @var{CVSROOT} is not the one
+currently being accessed, then the server will turn itself into a transparent
+proxy to @var{CVSROOT} for write requests. The @var{hostname} configured as
+part of @var{CVSROOT} must resolve to the same string returned by the
+@command{uname} command on the primary server for this to work. Host name
+resolution is performed via some combination of @command{named}, a broken out
+line from @file{/etc/hosts}, and the Network Information Service (NIS or YP),
+depending on the configuration of the particular system.
+
+Only the @samp{:ext:} method is
+currently supported for primaries (actually, @samp{:fork:} is supported as
+well, but only for testing - if you find another use for accessing a primary
+via the @samp{:fork:} method, please send a note to @email{bug-cvs@@nongnu.org}
+about it). See @ref{Write proxies} for more on configuring and using write
+proxies.
+
+@cindex RCSBIN, in CVSROOT/config
+@item RCSBIN=@var{bindir}
+For @sc{cvs} 1.9.12 through 1.9.18, this setting told
+@sc{cvs} to look for @sc{rcs} programs in the
+@var{bindir} directory. Current versions of @sc{cvs}
+do not run @sc{rcs} programs; for compatibility this
+setting is accepted, but it does nothing.
+
+@cindex RereadLogAfterVerify, in CVSROOT/config
+@cindex @file{verifymsg}, changing the log message
+@item RereadLogAfterVerify=@var{value}
+Modify the @samp{commit} command such that CVS will reread the
+log message after running the program specified by @file{verifymsg}.
+@var{value} may be one of @samp{yes} or @samp{always}, indicating that
+the log message should always be reread; @samp{no}
+or @samp{never}, indicating that it should never be
+reread; or @var{value} may be @samp{stat}, indicating
+that the file should be checked with the file system
+@samp{stat()} function to see if it has changed (see warning below)
+before rereading. The default value is @samp{always}.
+
+@strong{Note: the `stat' mode can cause CVS to pause for up to
+one extra second per directory committed. This can be less IO and
+CPU intensive but is not recommended for use with large repositories}
+
+@xref{verifymsg}, for more information on how verifymsg
+may be used.
+
+@cindex SystemAuth, in CVSROOT/config
+@item SystemAuth=@var{value}
+If @var{value} is @samp{yes}, then pserver should check
+for users in the system's user database if not found in
+@file{CVSROOT/passwd}. If it is @samp{no}, then all
+pserver users must exist in @file{CVSROOT/passwd}.
+The default is @samp{yes}. For more on pserver, see
+@ref{Password authenticated}.
+
+@cindex TmpDir, in config
+@cindex temporary files, location of
+@cindex temporary directory, set in config
+@item TmpDir=@var{path}
+Specify @var{path} as the directory to create temporary files in.
+@xref{Global options}, for more on setting the path to the temporary
+directory. This option first appeared with @sc{cvs} release 1.12.13.
+
+@cindex TopLevelAdmin, in CVSROOT/config
+@item TopLevelAdmin=@var{value}
+Modify the @samp{checkout} command to create a
+@samp{CVS} directory at the top level of the new
+working directory, in addition to @samp{CVS}
+directories created within checked-out directories.
+The default value is @samp{no}.
+
+This option is useful if you find yourself performing
+many commands at the top level of your working
+directory, rather than in one of the checked out
+subdirectories. The @file{CVS} directory created there
+will mean you don't have to specify @code{CVSROOT} for
+each command. It also provides a place for the
+@file{CVS/Template} file (@pxref{Working directory
+storage}).
+
+@cindex UseArchiveCommentLeader, in CVSROOT/config
+@cindex Log keyword, configuring substitution behavior
+@item UseArchiveCommentLeader=@var{value}
+Set to @code{true}, if the text preceding a @code{$@splitrcskeyword{Log}$}
+keyword is found to exceed @code{MaxCommentLeaderLength} (above) bytes, then
+the comment leader set in the RCS archive file (@pxref{admin}), if any, will
+be used instead. If there is no comment leader set in the archive file or
+@var{value} is set to @samp{false}, then the keyword will not be expanded
+(@pxref{Keyword list}). To force the comment leader in the RCS archive file to
+be used exclusively (and @code{$@splitrcskeyword{Log}$} expansion skipped in
+files where the comment leader has not been set in the archive file), set
+@var{value} and set @code{MaxCommentLeaderLength} to @code{0}.
+
+@cindex UseNewInfoFmtStrings, in CVSROOT/config
+@cindex format strings, config admin file
+@cindex config (admin file), updating legacy repositories
+@cindex compatibility notes, config admin file
+@item UseNewInfoFmtStrings=@var{value}
+Specify whether @sc{cvs} should support the new or old command line
+template model for the commit support files (@pxref{commit files}).
+This configuration variable began life in deprecation and is only here
+in order to give people time to update legacy repositories to use the new
+format string syntax before support for the old syntax is removed. For
+information on updating your repository to support the new model,
+please see @ref{Updating Commit Files}.
+
+@emph{Note that new repositories (created with the @code{cvs init} command)
+will have this value set to @samp{yes}, but the default value is @samp{no}.}
+
+@cindex UserAdminOptions, in CVSROOT/config
+@item UserAdminOptions=@var{value}
+Control what options will be allowed with the @code{cvs admin}
+command (@pxref{admin}) for users not in the @code{cvsadmin} group.
+The @var{value} string is a list of single character options
+which should be allowed. If a user who is not a member of the
+@code{cvsadmin} group tries to execute any @code{cvs admin}
+option which is not listed they will will receive an error message
+reporting that the option is restricted.
+
+If no @code{cvsadmin} group exists on the server, @sc{cvs} will
+ignore the @code{UserAdminOptions} keyword (@pxref{admin}).
+
+When not specified, @code{UserAdminOptions} defaults to
+@samp{k}. In other words, it defaults to allowing
+users outside of the @code{cvsadmin} group to use the
+@code{cvs admin} command only to change the default keyword
+expansion mode for files.
+
+As an example, to restrict users not in the @code{cvsadmin}
+group to using @code{cvs admin} to change the default keyword
+substitution mode, lock revisions, unlock revisions, and
+replace the log message, use @samp{UserAdminOptions=klum}.
+@end table
+
+
+
+@c ---------------------------------------------------------------------
+@node Environment variables
+@appendix All environment variables which affect CVS
+@cindex Environment variables
+@cindex Reference manual for variables
+
+This is a complete list of all environment variables
+that affect @sc{cvs} (Windows users, please bear with this list;
+$VAR is equivalent to %VAR% at the Windows command prompt).
+
+@table @code
+@cindex CVSIGNORE, environment variable
+@item $CVSIGNORE
+A whitespace-separated list of file name patterns that
+@sc{cvs} should ignore. @xref{cvsignore}.
+
+@cindex CVSWRAPPERS, environment variable
+@item $CVSWRAPPERS
+A whitespace-separated list of file name patterns that
+@sc{cvs} should treat as wrappers. @xref{Wrappers}.
+
+@cindex CVSREAD, environment variable
+@cindex Read-only files, and CVSREAD
+@item $CVSREAD
+If this is set, @code{checkout} and @code{update} will
+try hard to make the files in your working directory
+read-only. When this is not set, the default behavior
+is to permit modification of your working files.
+
+@cindex CVSREADONLYFS, environment variable
+@item $CVSREADONLYFS
+Turns on read-only repository mode. This allows one to
+check out from a read-only repository, such as within
+an anoncvs server, or from a @sc{cd-rom} repository.
+
+It has the same effect as if the @samp{-R} command-line
+option is used. This can also allow the use of
+read-only NFS repositories.
+
+@item $CVSUMASK
+Controls permissions of files in the repository. See
+@ref{File permissions}.
+
+@item $CVSROOT
+Should contain the full pathname to the root of the @sc{cvs}
+source repository (where the @sc{rcs} files are
+kept). This information must be available to @sc{cvs} for
+most commands to execute; if @code{$CVSROOT} is not set,
+or if you wish to override it for one invocation, you
+can supply it on the command line: @samp{cvs -d cvsroot
+cvs_command@dots{}} Once you have checked out a working
+directory, @sc{cvs} stores the appropriate root (in
+the file @file{CVS/Root}), so normally you only need to
+worry about this when initially checking out a working
+directory.
+
+@item $CVSEDITOR
+@cindex CVSEDITOR, environment variable
+@itemx $EDITOR
+@cindex EDITOR, environment variable
+@itemx $VISUAL
+@cindex VISUAL, environment variable
+Specifies the program to use for recording log messages
+during commit. @code{$CVSEDITOR} overrides
+@code{$EDITOR}, which overrides @code{$VISUAL}.
+See @ref{Committing your changes} for more or
+@ref{Global options} for alternative ways of specifying a
+log editor.
+
+@cindex PATH, environment variable
+@item $PATH
+If @code{$RCSBIN} is not set, and no path is compiled
+into @sc{cvs}, it will use @code{$PATH} to try to find all
+programs it uses.
+
+@cindex HOME, environment variable
+@item $HOME
+@cindex HOMEPATH, environment variable
+@item $HOMEPATH
+@cindex HOMEDRIVE, environment variable
+@item $HOMEDRIVE
+Used to locate the directory where the @file{.cvsrc}
+file, and other such files, are searched. On Unix, @sc{cvs}
+just checks for @code{HOME}. On Windows NT, the system will
+set @code{HOMEDRIVE}, for example to @samp{d:} and @code{HOMEPATH},
+for example to @file{\joe}. On Windows 95, you'll
+probably need to set @code{HOMEDRIVE} and @code{HOMEPATH} yourself.
+@c We are being vague about whether HOME works on
+@c Windows; see long comment in windows-NT/filesubr.c.
+
+@cindex CVS_RSH, environment variable
+@item $CVS_RSH
+Specifies the external program which @sc{cvs} connects with,
+when @code{:ext:} access method is specified.
+@pxref{Connecting via rsh}.
+
+@item $CVS_SERVER
+Used in client-server mode when accessing a remote
+repository using @sc{rsh}. It specifies the name of
+the program to start on the server side (and any
+necessary arguments) when accessing a remote repository
+using the @code{:ext:}, @code{:fork:}, or @code{:server:} access methods.
+The default value for @code{:ext:} and @code{:server:} is @code{cvs};
+the default value for @code{:fork:} is the name used to run the client.
+@pxref{Connecting via rsh}
+
+@item $CVS_PASSFILE
+Used in client-server mode when accessing the @code{cvs
+login server}. Default value is @file{$HOME/.cvspass}.
+@pxref{Password authentication client}
+
+@cindex CVS_CLIENT_PORT
+@item $CVS_CLIENT_PORT
+Used in client-server mode to set the port to use when accessing the server
+via Kerberos, GSSAPI, or @sc{cvs}'s password authentication protocol
+if the port is not specified in the CVSROOT.
+@pxref{Remote repositories}
+
+@cindex CVS_PROXY_PORT
+@item $CVS_PROXY_PORT
+Used in client-server mode to set the port to use when accessing a server
+via a web proxy, if the port is not specified in the CVSROOT. Works with
+GSSAPI, and the password authentication protocol.
+@pxref{Remote repositories}
+
+@cindex CVS_RCMD_PORT, environment variable
+@item $CVS_RCMD_PORT
+Used in client-server mode. If set, specifies the port
+number to be used when accessing the @sc{rcmd} demon on
+the server side. (Currently not used for Unix clients).
+
+@cindex CVS_CLIENT_LOG, environment variable
+@item $CVS_CLIENT_LOG
+Used for debugging only in client-server
+mode. If set, everything sent to the server is logged
+into @file{@code{$CVS_CLIENT_LOG}.in} and everything
+sent from the server is logged into
+@file{@code{$CVS_CLIENT_LOG}.out}.
+
+@cindex CVS_SERVER_SLEEP, environment variable
+@item $CVS_SERVER_SLEEP
+Used only for debugging the server side in
+client-server mode. If set, delays the start of the
+server child process the specified amount of
+seconds so that you can attach to it with a debugger.
+
+@cindex CVS_IGNORE_REMOTE_ROOT, environment variable
+@item $CVS_IGNORE_REMOTE_ROOT
+For @sc{cvs} 1.10 and older, setting this variable
+prevents @sc{cvs} from overwriting the @file{CVS/Root}
+file when the @samp{-d} global option is specified.
+Later versions of @sc{cvs} do not rewrite
+@file{CVS/Root}, so @code{CVS_IGNORE_REMOTE_ROOT} has no
+effect.
+
+@cindex CVS_LOCAL_BRANCH_NUM, environment variable
+@item $CVS_LOCAL_BRANCH_NUM
+Setting this variable allows some control over the
+branch number that is assigned. This is specifically to
+support the local commit feature of CVSup. If one sets
+@code{CVS_LOCAL_BRANCH_NUM} to (say) 1000 then branches
+the local repository, the revision numbers will look
+like 1.66.1000.xx. There is almost a dead-set certainty
+that there will be no conflicts with version numbers.
+
+@cindex COMSPEC, environment variable
+@item $COMSPEC
+Used under OS/2 only. It specifies the name of the
+command interpreter and defaults to @sc{cmd.exe}.
+
+@cindex TMPDIR, environment variable
+@cindex temporary file directory, set via environment variable
+@cindex temporary files, location of
+@item $TMPDIR
+Directory in which temporary files are located.
+@xref{Global options}, for more on setting the temporary directory.
+
+@cindex CVS_PID, environment variable
+@item $CVS_PID
+This is the process identification (aka pid) number of
+the @sc{cvs} process. It is often useful in the
+programs and/or scripts specified by the
+@file{commitinfo}, @file{verifymsg}, @file{loginfo}
+files.
+@end table
+
+@node Compatibility
+@appendix Compatibility between CVS Versions
+
+@cindex CVS, versions of
+@cindex Versions, of CVS
+@cindex Compatibility, between CVS versions
+@c We don't mention versions older than CVS 1.3
+@c on the theory that it would clutter it up for the vast
+@c majority of people, who don't have anything that old.
+@c
+The repository format is compatible going back to
+@sc{cvs} 1.3. But see @ref{Watches Compatibility}, if
+you have copies of @sc{cvs} 1.6 or older and you want
+to use the optional developer communication features.
+@c If you "cvs rm" and commit using 1.3, then you'll
+@c want to run "rcs -sdead <file,v>" on each of the
+@c files in the Attic if you then want 1.5 and
+@c later to recognize those files as dead (I think the
+@c symptom if this is not done is that files reappear
+@c in joins). (Wait: the above will work but really to
+@c be strictly correct we should suggest checking
+@c in a new revision rather than just changing the
+@c state of the head revision, shouldn't we?).
+@c The old convert.sh script was for this, but it never
+@c did get updated to reflect use of the RCS "dead"
+@c state.
+@c Note: this is tricky to document without confusing
+@c people--need to carefully say what CVS version we
+@c are talking about and keep in mind the distinction
+@c between a
+@c repository created with 1.3 and on which one now
+@c uses 1.5+, and a repository on which one wants to
+@c use both versions side by side (e.g. during a
+@c transition period).
+@c Wait, can't CVS just detect the case in which a file
+@c is in the Attic but the head revision is not dead?
+@c Not sure whether this should produce a warning or
+@c something, and probably needs further thought, but
+@c it would appear that the situation can be detected.
+@c
+@c We might want to separate out the 1.3 compatibility
+@c section (for repository & working directory) from the
+@c rest--that might help avoid confusing people who
+@c are upgrading (for example) from 1.6 to 1.8.
+@c
+@c A minor incompatibility is if a current version of CVS
+@c puts "Nfoo" into CVS/Tag, then CVS 1.9 or older will
+@c see this as if there is no tag. Seems to me this is
+@c too obscure to mention.
+
+The working directory format is compatible going back
+to @sc{cvs} 1.5. It did change between @sc{cvs} 1.3
+and @sc{cvs} 1.5. If you run @sc{cvs} 1.5 or newer on
+a working directory checked out with @sc{cvs} 1.3,
+@sc{cvs} will convert it, but to go back to @sc{cvs}
+1.3 you need to check out a new working directory with
+@sc{cvs} 1.3.
+
+The remote protocol is interoperable going back to @sc{cvs} 1.5, but no
+further (1.5 was the first official release with the remote protocol,
+but some older versions might still be floating around). In many
+cases you need to upgrade both the client and the server to take
+advantage of new features and bug fixes, however.
+
+@c Perhaps should be saying something here about the
+@c "D" lines in Entries (written by CVS 1.9; 1.8 and
+@c older don't use them). These are supposed to be
+@c compatible in both directions, but I'm not sure
+@c they quite are 100%. One common gripe is if you
+@c "rm -r" a directory and 1.9 gets confused, as it
+@c still sees it in Entries. That one is fixed in
+@c (say) 1.9.6. Someone else reported problems with
+@c starting with a directory which was checked out with
+@c an old version, and then using a new version, and
+@c some "D" lines appeared, but not for every
+@c directory, causing some directories to be skipped.
+@c They weren't sure how to reproduce this, though.
+
+@c ---------------------------------------------------------------------
+@node Troubleshooting
+@appendix Troubleshooting
+
+If you are having trouble with @sc{cvs}, this appendix
+may help. If there is a particular error message which
+you are seeing, then you can look up the message
+alphabetically. If not, you can look through the
+section on other problems to see if your problem is
+mentioned there.
+
+@menu
+* Error messages:: Partial list of CVS errors
+* Connection:: Trouble making a connection to a CVS server
+* Other problems:: Problems not readily listed by error message
+@end menu
+
+@ignore
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@c @node Bad administrative files
+@appendixsec Bad administrative files
+
+@c -- Give hints on how to fix them
+@end ignore
+
+@node Error messages
+@appendixsec Partial list of error messages
+
+Here is a partial list of error messages that you may
+see from @sc{cvs}. It is not a complete list---@sc{cvs}
+is capable of printing many, many error messages, often
+with parts of them supplied by the operating system,
+but the intention is to list the common and/or
+potentially confusing error messages.
+
+The messages are alphabetical, but introductory text
+such as @samp{cvs update: } is not considered in
+ordering them.
+
+In some cases the list includes messages printed by old
+versions of @sc{cvs} (partly because users may not be
+sure which version of @sc{cvs} they are using at any
+particular moment).
+@c If we want to start retiring messages, perhaps we
+@c should pick a cutoff version (for example, no more
+@c messages which are specific to versions before 1.9)
+@c and then move the old messages to an "old messages"
+@c node rather than deleting them completely.
+
+@table @code
+@c FIXME: What is the correct way to format a multiline
+@c error message here? Maybe @table is the wrong
+@c choice? Texinfo gurus?
+@item @var{file}:@var{line}: Assertion '@var{text}' failed
+The exact format of this message may vary depending on
+your system. It indicates a bug in @sc{cvs}, which can
+be handled as described in @ref{BUGS}.
+
+@item cvs @var{command}: authorization failed: server @var{host} rejected access
+This is a generic response when trying to connect to a
+pserver server which chooses not to provide a
+specific reason for denying authorization. Check that
+the username and password specified are correct and
+that the @code{CVSROOT} specified is allowed by @samp{--allow-root}
+in @file{inetd.conf}. See @ref{Password authenticated}.
+
+@item cvs @var{command}: conflict: removed @var{file} was modified by second party
+This message indicates that you removed a file, and
+someone else modified it. To resolve the conflict,
+first run @samp{cvs add @var{file}}. If desired, look
+at the other party's modification to decide whether you
+still want to remove it. If you don't want to remove
+it, stop here. If you do want to remove it, proceed
+with @samp{cvs remove @var{file}} and commit your
+removal.
+@c Tests conflicts2-142b* in sanity.sh test for this.
+
+@item cannot change permissions on temporary directory
+@example
+Operation not permitted
+@end example
+This message has been happening in a non-reproducible,
+occasional way when we run the client/server testsuite,
+both on Red Hat Linux 3.0.3 and 4.1. We haven't been
+able to figure out what causes it, nor is it known
+whether it is specific to Linux (or even to this
+particular machine!). If the problem does occur on
+other unices, @samp{Operation not permitted} would be
+likely to read @samp{Not owner} or whatever the system
+in question uses for the unix @code{EPERM} error. If
+you have any information to add, please let us know as
+described in @ref{BUGS}. If you experience this error
+while using @sc{cvs}, retrying the operation which
+produced it should work fine.
+@c This has been seen in a variety of tests, including
+@c multibranch-2, multibranch-5, and basic1-24-rm-rm,
+@c so it doesn't seem particularly specific to any one
+@c test.
+
+@item cvs [server aborted]: Cannot check out files into the repository itself
+The obvious cause for this message (especially for
+non-client/server @sc{cvs}) is that the @sc{cvs} root
+is, for example, @file{/usr/local/cvsroot} and you try
+to check out files when you are in a subdirectory, such
+as @file{/usr/local/cvsroot/test}. However, there is a
+more subtle cause, which is that the temporary
+directory on the server is set to a subdirectory of the
+root (which is also not allowed). If this is the
+problem, set the temporary directory to somewhere else,
+for example @file{/var/tmp}; see @code{TMPDIR} in
+@ref{Environment variables}, for how to set the
+temporary directory.
+
+@item cannot commit files as 'root'
+See @samp{'root' is not allowed to commit files}.
+
+@c For one example see basica-1a10 in the testsuite
+@c For another example, "cvs co ." on NT; see comment
+@c at windows-NT/filesubr.c (expand_wild).
+@c For another example, "cvs co foo/bar" where foo exists.
+@item cannot open CVS/Entries for reading: No such file or directory
+This generally indicates a @sc{cvs} internal error, and
+can be handled as with other @sc{cvs} bugs
+(@pxref{BUGS}). Usually there is a workaround---the
+exact nature of which would depend on the situation but
+which hopefully could be figured out.
+
+@c This is more obscure than it might sound; it only
+@c happens if you run "cvs init" from a directory which
+@c contains a CVS/Root file at the start.
+@item cvs [init aborted]: cannot open CVS/Root: No such file or directory
+This message is harmless. Provided it is not
+accompanied by other errors, the operation has
+completed successfully. This message should not occur
+with current versions of @sc{cvs}, but it is documented
+here for the benefit of @sc{cvs} 1.9 and older.
+
+@item cvs server: cannot open /root/.cvsignore: Permission denied
+@itemx cvs [server aborted]: can't chdir(/root): Permission denied
+See @ref{Connection}.
+
+@item cvs [checkout aborted]: cannot rename file @var{file} to CVS/,,@var{file}: Invalid argument
+This message has been reported as intermittently
+happening with @sc{cvs} 1.9 on Solaris 2.5. The cause is
+unknown; if you know more about what causes it, let us
+know as described in @ref{BUGS}.
+
+@item cvs [@var{command} aborted]: cannot start server via rcmd
+This, unfortunately, is a rather nonspecific error
+message which @sc{cvs} 1.9 will print if you are
+running the @sc{cvs} client and it is having trouble
+connecting to the server. Current versions of @sc{cvs}
+should print a much more specific error message. If
+you get this message when you didn't mean to run the
+client at all, you probably forgot to specify
+@code{:local:}, as described in @ref{Repository}.
+
+@item ci: @var{file},v: bad diff output line: Binary files - and /tmp/T2a22651 differ
+@sc{cvs} 1.9 and older will print this message
+when trying to check in a binary file if
+@sc{rcs} is not correctly installed. Re-read the
+instructions that came with your @sc{rcs} distribution
+and the @sc{install} file in the @sc{cvs}
+distribution. Alternately, upgrade to a current
+version of @sc{cvs}, which checks in files itself
+rather than via @sc{rcs}.
+
+@item cvs checkout: could not check out @var{file}
+With @sc{cvs} 1.9, this can mean that the @code{co} program
+(part of @sc{rcs}) returned a failure. It should be
+preceded by another error message, however it has been
+observed without another error message and the cause is
+not well-understood. With the current version of @sc{cvs},
+which does not run @code{co}, if this message occurs
+without another error message, it is definitely a @sc{cvs}
+bug (@pxref{BUGS}).
+@c My current suspicion is that the RCS in the rcs (not
+@c cvs/winnt/rcs57nt.zip) directory on the _Practical_
+@c CD is bad (remains to be confirmed).
+@c There is also a report of something which looks
+@c very similar on SGI, Irix 5.2, so I dunno.
+
+@item cvs [login aborted]: could not find out home directory
+This means that you need to set the environment
+variables that @sc{cvs} uses to locate your home directory.
+See the discussion of @code{HOME}, @code{HOMEDRIVE}, and @code{HOMEPATH} in
+@ref{Environment variables}.
+
+@item cvs update: could not merge revision @var{rev} of @var{file}: No such file or directory
+@sc{cvs} 1.9 and older will print this message if there was
+a problem finding the @code{rcsmerge} program. Make
+sure that it is in your @code{PATH}, or upgrade to a
+current version of @sc{cvs}, which does not require
+an external @code{rcsmerge} program.
+
+@item cvs [update aborted]: could not patch @var{file}: No such file or directory
+This means that there was a problem finding the
+@code{patch} program. Make sure that it is in your
+@code{PATH}. Note that despite appearances the message
+is @emph{not} referring to whether it can find @var{file}.
+If both the client and the server are running a current
+version of @sc{cvs}, then there is no need for an
+external patch program and you should not see this
+message. But if either client or server is running
+@sc{cvs} 1.9, then you need @code{patch}.
+
+@item cvs update: could not patch @var{file}; will refetch
+This means that for whatever reason the client was
+unable to apply a patch that the server sent. The
+message is nothing to be concerned about, because
+inability to apply the patch only slows things down and
+has no effect on what @sc{cvs} does.
+@c xref to update output. Or File status?
+@c Or some place else that
+@c explains this whole "patch"/P/Needs Patch thing?
+
+@item dying gasps from @var{server} unexpected
+There is a known bug in the server for @sc{cvs} 1.9.18
+and older which can cause this. For me, this was
+reproducible if I used the @samp{-t} global option. It
+was fixed by Andy Piper's 14 Nov 1997 change to
+src/filesubr.c, if anyone is curious.
+If you see the message,
+you probably can just retry the operation which failed,
+or if you have discovered information concerning its
+cause, please let us know as described in @ref{BUGS}.
+
+@item end of file from server (consult above messages if any)
+The most common cause for this message is if you are
+using an external @code{rsh} program and it exited with
+an error. In this case the @code{rsh} program should
+have printed a message, which will appear before the
+above message. For more information on setting up a
+@sc{cvs} client and server, see @ref{Remote repositories}.
+
+@item cvs [update aborted]: EOF in key in RCS file @var{file},v
+@itemx cvs [checkout aborted]: EOF while looking for end of string in RCS file @var{file},v
+This means that there is a syntax error in the given
+@sc{rcs} file. Note that this might be true even if @sc{rcs} can
+read the file OK; @sc{cvs} does more error checking of
+errors in the RCS file. That is why you may see this
+message when upgrading from @sc{cvs} 1.9 to @sc{cvs}
+1.10. The likely cause for the original corruption is
+hardware, the operating system, or the like. Of
+course, if you find a case in which @sc{cvs} seems to
+corrupting the file, by all means report it,
+(@pxref{BUGS}).
+There are quite a few variations of this error message,
+depending on exactly where in the @sc{rcs} file @sc{cvs}
+finds the syntax error.
+
+@cindex mkmodules
+@item cvs commit: Executing 'mkmodules'
+This means that your repository is set up for a version
+of @sc{cvs} prior to @sc{cvs} 1.8. When using @sc{cvs}
+1.8 or later, the above message will be preceded by
+
+@example
+cvs commit: Rebuilding administrative file database
+@end example
+
+If you see both messages, the database is being rebuilt
+twice, which is unnecessary but harmless. If you wish
+to avoid the duplication, and you have no versions of
+@sc{cvs} 1.7 or earlier in use, remove @code{-i mkmodules}
+every place it appears in your @code{modules}
+file. For more information on the @code{modules} file,
+see @ref{modules}.
+
+@c This message comes from "co", and I believe is
+@c possible only with older versions of CVS which call
+@c co. The problem with being able to create the bogus
+@c RCS file still exists, though (and I think maybe
+@c there is a different symptom(s) now).
+@c FIXME: Would be nice to have a more exact wording
+@c for this message.
+@item missing author
+Typically this can happen if you created an RCS file
+with your username set to empty. @sc{cvs} will, bogusly,
+create an illegal RCS file with no value for the author
+field. The solution is to make sure your username is
+set to a non-empty value and re-create the RCS file.
+@c "make sure your username is set" is complicated in
+@c and of itself, as there are the environment
+@c variables the system login name, &c, and it depends
+@c on the version of CVS.
+
+@item cvs [checkout aborted]: no such tag @var{tag}
+This message means that @sc{cvs} isn't familiar with
+the tag @var{tag}. Usually the root cause is that you have
+mistyped a tag name. Ocassionally this can also occur because the
+users creating tags do not have permissions to write to the
+@file{CVSROOT/val-tags} file (@pxref{File permissions}, for more).
+
+Prior to @sc{cvs} version 1.12.10, there were a few relatively
+obscure cases where a given tag could be created in an archive
+file in the repository but @sc{cvs} would require the user to
+@c Search sanity.sh for "no such tag" to see some of
+@c the relatively obscure cases.
+try a few other @sc{cvs} commands involving that tag
+until one was found whch caused @sc{cvs} to update
+@cindex CVSROOT/val-tags file, forcing tags into
+@cindex val-tags file, forcing tags into
+the @file{val-tags} file, at which point the originally failing command
+would begin to work. This same method can be used to repair a @file{val-tags}
+file that becomes out of date due to the permissions problem mentioned above.
+This updating is only required once per tag - once a tag is listed in
+@file{val-tags}, it stays there.
+
+Note that using @samp{tag -f} to not require tag matches did not and
+does not override this check (@pxref{Common options}).
+
+@item *PANIC* administration files missing
+This typically means that there is a directory named
+@sc{cvs} but it does not contain the administrative files
+which @sc{cvs} puts in a CVS directory. If the problem is
+that you created a CVS directory via some mechanism
+other than @sc{cvs}, then the answer is simple, use a name
+other than @sc{cvs}. If not, it indicates a @sc{cvs} bug
+(@pxref{BUGS}).
+
+@item rcs error: Unknown option: -x,v/
+This message will be followed by a usage message for
+@sc{rcs}. It means that you have an old version of
+@sc{rcs} (probably supplied with your operating
+system), as well as an old version of @sc{cvs}.
+@sc{cvs} 1.9.18 and earlier only work with @sc{rcs} version 5 and
+later; current versions of @sc{cvs} do not run @sc{rcs} programs.
+@c For more information on installing @sc{cvs}, see
+@c (FIXME: where? it depends on whether you are
+@c getting binaries or sources or what).
+@c The message can also say "ci error" or something
+@c instead of "rcs error", I suspect.
+
+@item cvs [server aborted]: received broken pipe signal
+This message can be caused by a loginfo program that fails to
+read all of the log information from its standard input.
+If you find it happening in any other circumstances,
+please let us know as described in @ref{BUGS}.
+
+@item 'root' is not allowed to commit files
+When committing a permanent change, @sc{cvs} makes a log entry of
+who committed the change. If you are committing the change logged
+in as "root" (not under "su" or other root-priv giving program),
+@sc{cvs} cannot determine who is actually making the change.
+As such, by default, @sc{cvs} disallows changes to be committed by users
+logged in as "root". (You can disable this option by passing the
+@code{--enable-rootcommit} option to @file{configure} and recompiling @sc{cvs}.
+On some systems this means editing the appropriate @file{config.h} file
+before building @sc{cvs}.)
+
+@item cvs [server aborted]: Secondary out of sync with primary!
+
+This usually means that the version of @sc{cvs} running on a secondary
+server is incompatible with the version running on the primary server
+(@pxref{Write proxies}).
+This will not occur if the client supports redirection.
+
+It is not the version number that is significant here, but the list of
+supported requests that the servers provide to the client.
+For example, even if both servers were the same version,
+if the secondary was compiled with GSSAPI support and the primary was not,
+the list of supported requests provided by the two servers
+would be different and the secondary would not work as a transparent
+proxy to the primary.
+Conversely, even if the two servers were radically different versions
+but both provided the same list of valid requests to the client,
+the transparent proxy would succeed.
+
+@item Terminated with fatal signal 11
+This message usually indicates that @sc{cvs} (the server, if you're
+using client/server mode) has run out of (virtual) memory.
+Although @sc{cvs} tries to catch the error and issue a more meaningful
+message, there are many circumstances where that is not possible.
+If you appear to have lots of memory available to the system,
+the problem is most likely that you're running into a system-wide
+limit on the amount of memory a single process can use or a
+similar process-specific limit.
+The mechanisms for displaying and setting such limits vary from
+system to system, so you'll have to consult an expert for your
+particular system if you don't know how to do that.
+
+@item Too many arguments!
+This message is typically printed by the @file{log.pl}
+script which is in the @file{contrib} directory in the
+@sc{cvs} source distribution. In some versions of
+@sc{cvs}, @file{log.pl} has been part of the default
+@sc{cvs} installation. The @file{log.pl} script gets
+called from the @file{loginfo} administrative file.
+Check that the arguments passed in @file{loginfo} match
+what your version of @file{log.pl} expects. In
+particular, the @file{log.pl} from @sc{cvs} 1.3 and
+older expects the log file as an argument whereas the
+@file{log.pl} from @sc{cvs} 1.5 and newer expects the
+log file to be specified with a @samp{-f} option. Of
+course, if you don't need @file{log.pl} you can just
+comment it out of @file{loginfo}.
+
+@item cvs [update aborted]: unexpected EOF reading @var{file},v
+See @samp{EOF in key in RCS file}.
+
+@item cvs [login aborted]: unrecognized auth response from @var{server}
+This message typically means that the server is not set
+up properly. For example, if @file{inetd.conf} points
+to a nonexistent cvs executable. To debug it further,
+find the log file which inetd writes
+(@file{/var/log/messages} or whatever inetd uses on
+your system). For details, see @ref{Connection}, and
+@ref{Password authentication server}.
+
+@item cvs commit: Up-to-date check failed for `@var{file}'
+This means that someone else has committed a change to
+that file since the last time that you did a @code{cvs
+update}. So before proceeding with your @code{cvs
+commit} you need to @code{cvs update}. @sc{cvs} will merge
+the changes that you made and the changes that the
+other person made. If it does not detect any conflicts
+it will report @samp{M @var{file}} and you are ready
+to @code{cvs commit}. If it detects conflicts it will
+print a message saying so, will report @samp{C @var{file}},
+and you need to manually resolve the
+conflict. For more details on this process see
+@ref{Conflicts example}.
+
+@item Usage: diff3 [-exEX3 [-i | -m] [-L label1 -L label3]] file1 file2 file3
+@example
+Only one of [exEX3] allowed
+@end example
+This indicates a problem with the installation of
+@code{diff3} and @code{rcsmerge}. Specifically
+@code{rcsmerge} was compiled to look for GNU diff3, but
+it is finding unix diff3 instead. The exact text of
+the message will vary depending on the system. The
+simplest solution is to upgrade to a current version of
+@sc{cvs}, which does not rely on external
+@code{rcsmerge} or @code{diff3} programs.
+
+@item warning: unrecognized response `@var{text}' from cvs server
+If @var{text} contains a valid response (such as
+@samp{ok}) followed by an extra carriage return
+character (on many systems this will cause the second
+part of the message to overwrite the first part), then
+it probably means that you are using the @samp{:ext:}
+access method with a version of rsh, such as most
+non-unix rsh versions, which does not by default
+provide a transparent data stream. In such cases you
+probably want to try @samp{:server:} instead of
+@samp{:ext:}. If @var{text} is something else, this
+may signify a problem with your @sc{cvs} server.
+Double-check your installation against the instructions
+for setting up the @sc{cvs} server.
+@c FIXCVS: should be printing CR as \r or \015 or some
+@c such, probably.
+
+@item cvs commit: [@var{time}] waiting for @var{user}'s lock in @var{directory}
+This is a normal message, not an error. See
+@ref{Concurrency}, for more details.
+
+@item cvs commit: warning: editor session failed
+@cindex Exit status, of editor
+This means that the editor which @sc{cvs} is using exits with a nonzero
+exit status. Some versions of vi will do this even when there was not
+a problem editing the file. If so, point the
+@code{CVSEDITOR} environment variable to a small script
+such as:
+
+@example
+#!/bin/sh
+vi $*
+exit 0
+@end example
+
+@item cvs update: warning: @var{file} was lost
+This means that the working copy of @var{file} has been deleted
+but it has not been removed from @sc{cvs}.
+This is nothing to be concerned about,
+the update will just recreate the local file from the repository.
+(This is a convenient way to discard local changes to a file:
+just delete it and then run @code{cvs update}.)
+
+@item cvs update: warning: @var{file} is not (any longer) pertinent
+This means that the working copy of @var{file} has been deleted,
+it has not been removed from @sc{cvs} in the current working directory,
+but it has been removed from @sc{cvs} in some other working directory.
+This is nothing to be concerned about,
+the update would have removed the local file anyway.
+
+@end table
+
+@node Connection
+@appendixsec Trouble making a connection to a CVS server
+
+This section concerns what to do if you are having
+trouble making a connection to a @sc{cvs} server. If
+you are running the @sc{cvs} command line client
+running on Windows, first upgrade the client to
+@sc{cvs} 1.9.12 or later. The error reporting in
+earlier versions provided much less information about
+what the problem was. If the client is non-Windows,
+@sc{cvs} 1.9 should be fine.
+
+If the error messages are not sufficient to track down
+the problem, the next steps depend largely on which
+access method you are using.
+
+@table @code
+@cindex :ext:, troubleshooting
+@item :ext:
+Try running the rsh program from the command line. For
+example: "rsh servername cvs -v" should print @sc{cvs}
+version information. If this doesn't work, you need to
+fix it before you can worry about @sc{cvs} problems.
+
+@cindex :server:, troubleshooting
+@item :server:
+You don't need a command line rsh program to use this
+access method, but if you have an rsh program around,
+it may be useful as a debugging tool. Follow the
+directions given for :ext:.
+
+@cindex :pserver:, troubleshooting
+@item :pserver:
+Errors along the lines of "connection refused" typically indicate
+that inetd isn't even listening for connections on port 2401
+whereas errors like "connection reset by peer",
+"received broken pipe signal", "recv() from server: EOF",
+or "end of file from server"
+typically indicate that inetd is listening for
+connections but is unable to start @sc{cvs} (this is frequently
+caused by having an incorrect path in @file{inetd.conf}
+or by firewall software rejecting the connection).
+"unrecognized auth response" errors are caused by a bad command
+line in @file{inetd.conf}, typically an invalid option or forgetting
+to put the @samp{pserver} command at the end of the line.
+Another less common problem is invisible control characters that
+your editor "helpfully" added without you noticing.
+
+One good debugging tool is to "telnet servername
+2401". After connecting, send any text (for example
+"foo" followed by return). If @sc{cvs} is working
+correctly, it will respond with
+
+@example
+cvs [pserver aborted]: bad auth protocol start: foo
+@end example
+
+If instead you get:
+
+@example
+Usage: cvs [cvs-options] command [command-options-and-arguments]
+...
+@end example
+
+@noindent
+then you're missing the @samp{pserver} command at the end of the
+line in @file{inetd.conf}; check to make sure that the entire command
+is on one line and that it's complete.
+
+Likewise, if you get something like:
+
+@example
+Unknown command: `pserved'
+
+CVS commands are:
+ add Add a new file/directory to the repository
+...
+@end example
+
+@noindent
+then you've misspelled @samp{pserver} in some way. If it isn't
+obvious, check for invisible control characters (particularly
+carriage returns) in @file{inetd.conf}.
+
+If it fails to work at all, then make sure inetd is working
+right. Change the invocation in @file{inetd.conf} to run the
+echo program instead of cvs. For example:
+
+@example
+2401 stream tcp nowait root /bin/echo echo hello
+@end example
+
+After making that change and instructing inetd to
+re-read its configuration file, "telnet servername
+2401" should show you the text hello and then the
+server should close the connection. If this doesn't
+work, you need to fix it before you can worry about
+@sc{cvs} problems.
+
+On AIX systems, the system will often have its own
+program trying to use port 2401. This is AIX's problem
+in the sense that port 2401 is registered for use with
+@sc{cvs}. I hear that there is an AIX patch available
+to address this problem.
+
+Another good debugging tool is the @samp{-d}
+(debugging) option to inetd. Consult your system
+documentation for more information.
+
+If you seem to be connecting but get errors like:
+
+@example
+cvs server: cannot open /root/.cvsignore: Permission denied
+cvs [server aborted]: can't chdir(/root): Permission denied
+@end example
+
+@noindent
+then you probably haven't specified @samp{-f} in @file{inetd.conf}.
+(In releases prior to @sc{cvs} 1.11.1, this problem can be caused by
+your system setting the @code{$HOME} environment variable
+for programs being run by inetd. In this case, you can either
+have inetd run a shell script that unsets @code{$HOME} and then runs
+@sc{cvs}, or you can use @code{env} to run @sc{cvs} with a pristine
+environment.)
+
+If you can connect successfully for a while but then can't,
+you've probably hit inetd's rate limit.
+(If inetd receives too many requests for the same service
+in a short period of time, it assumes that something is wrong
+and temporarily disables the service.)
+Check your inetd documentation to find out how to adjust the
+rate limit (some versions of inetd have a single rate limit,
+others allow you to set the limit for each service separately.)
+@end table
+
+@node Other problems
+@appendixsec Other common problems
+
+Here is a list of problems which do not fit into the
+above categories. They are in no particular order.
+
+@itemize @bullet
+@item
+On Windows, if there is a 30 second or so delay when
+you run a @sc{cvs} command, it may mean that you have
+your home directory set to @file{C:/}, for example (see
+@code{HOMEDRIVE} and @code{HOMEPATH} in
+@ref{Environment variables}). @sc{cvs} expects the home
+directory to not end in a slash, for example @file{C:}
+or @file{C:\cvs}.
+@c FIXCVS: CVS should at least detect this and print an
+@c error, presumably.
+
+@item
+If you are running @sc{cvs} 1.9.18 or older, and
+@code{cvs update} finds a conflict and tries to
+merge, as described in @ref{Conflicts example}, but
+doesn't tell you there were conflicts, then you may
+have an old version of @sc{rcs}. The easiest solution
+probably is to upgrade to a current version of
+@sc{cvs}, which does not rely on external @sc{rcs}
+programs.
+@end itemize
+
+@c ---------------------------------------------------------------------
+@node Credits
+@appendix Credits
+
+@cindex Contributors (manual)
+@cindex Credits (manual)
+Roland Pesch, then of Cygnus Support <@t{roland@@wrs.com}>
+wrote the manual pages which were distributed with
+@sc{cvs} 1.3. Much of their text was copied into this
+manual. He also read an early draft
+of this manual and contributed many ideas and
+corrections.
+
+The mailing-list @code{info-cvs} is sometimes
+informative. I have included information from postings
+made by the following persons:
+David G. Grubbs <@t{dgg@@think.com}>.
+
+Some text has been extracted from the man pages for
+@sc{rcs}.
+
+The @sc{cvs} @sc{faq} by David G. Grubbs has provided
+useful material. The @sc{faq} is no longer maintained,
+however, and this manual is about the closest thing there
+is to a successor (with respect to documenting how to
+use @sc{cvs}, at least).
+
+In addition, the following persons have helped by
+telling me about mistakes I've made:
+
+@display
+Roxanne Brunskill <@t{rbrunski@@datap.ca}>,
+Kathy Dyer <@t{dyer@@phoenix.ocf.llnl.gov}>,
+Karl Pingle <@t{pingle@@acuson.com}>,
+Thomas A Peterson <@t{tap@@src.honeywell.com}>,
+Inge Wallin <@t{ingwa@@signum.se}>,
+Dirk Koschuetzki <@t{koschuet@@fmi.uni-passau.de}>
+and Michael Brown <@t{brown@@wi.extrel.com}>.
+@end display
+
+The list of contributors here is not comprehensive; for a more
+complete list of who has contributed to this manual see
+the file @file{doc/ChangeLog} in the @sc{cvs} source
+distribution.
+
+@c ---------------------------------------------------------------------
+@node BUGS
+@appendix Dealing with bugs in CVS or this manual
+
+@cindex Bugs in this manual or CVS
+Neither @sc{cvs} nor this manual is perfect, and they
+probably never will be. If you are having trouble
+using @sc{cvs}, or think you have found a bug, there
+are a number of things you can do about it. Note that
+if the manual is unclear, that can be considered a bug
+in the manual, so these problems are often worth doing
+something about as well as problems with @sc{cvs} itself.
+
+@cindex Reporting bugs
+@cindex Bugs, reporting
+@cindex Errors, reporting
+@itemize @bullet
+@item
+If you want someone to help you and fix bugs that you
+report, there are companies which will do that for a
+fee. One such company is:
+
+@cindex Ximbiot
+@cindex Support, getting CVS support
+@example
+Ximbiot
+319 S. River St.
+Harrisburg, PA 17104-1657
+USA
+Email: info@@ximbiot.com
+Phone: (717) 579-6168
+Fax: (717) 234-3125
+@url{http://ximbiot.com/}
+
+@end example
+
+@item
+If you got @sc{cvs} through a distributor, such as an
+operating system vendor or a vendor of freeware
+@sc{cd-rom}s, you may wish to see whether the
+distributor provides support. Often, they will provide
+no support or minimal support, but this may vary from
+distributor to distributor.
+
+@item
+If you have the skills and time to do so, you may wish
+to fix the bug yourself. If you wish to submit your
+fix for inclusion in future releases of @sc{cvs}, see
+the file @sc{hacking} in the @sc{cvs} source
+distribution. It contains much more information on the
+process of submitting fixes.
+
+@item
+There may be resources on the net which can help. A
+good place to start is:
+
+@example
+@url{http://cvs.nongnu.org/}
+@end example
+
+If you are so inspired, increasing the information
+available on the net is likely to be appreciated. For
+example, before the standard @sc{cvs} distribution
+worked on Windows 95, there was a web page with some
+explanation and patches for running @sc{cvs} on Windows
+95, and various people helped out by mentioning this
+page on mailing lists or newsgroups when the subject
+came up.
+
+@item
+It is also possible to report bugs to @email{bug-cvs@@nongnu.org}.
+Note that someone may or may not want to do anything
+with your bug report---if you need a solution consider
+one of the options mentioned above. People probably do
+want to hear about bugs which are particularly severe
+in consequences and/or easy to fix, however. You can
+also increase your odds by being as clear as possible
+about the exact nature of the bug and any other
+relevant information. The way to report bugs is to
+send email to @email{bug-cvs@@nongnu.org}. Note
+that submissions to @email{bug-cvs@@nongnu.org} may be distributed
+under the terms of the @sc{gnu} Public License, so if
+you don't like this, don't submit them. There is
+usually no justification for sending mail directly to
+one of the @sc{cvs} maintainers rather than to
+@email{bug-cvs@@nongnu.org}; those maintainers who want to hear
+about such bug reports read @email{bug-cvs@@nongnu.org}. Also note
+that sending a bug report to other mailing lists or
+newsgroups is @emph{not} a substitute for sending it to
+@email{bug-cvs@@nongnu.org}. It is fine to discuss @sc{cvs} bugs on
+whatever forum you prefer, but there are not
+necessarily any maintainers reading bug reports sent
+anywhere except @email{bug-cvs@@nongnu.org}.
+@end itemize
+
+@cindex Known bugs in this manual or CVS
+People often ask if there is a list of known bugs or
+whether a particular bug is a known one. The file
+@sc{bugs} in the @sc{cvs} source distribution is one
+list of known bugs, but it doesn't necessarily try to
+be comprehensive. Perhaps there will never be a
+comprehensive, detailed list of known bugs.
+
+@c ---------------------------------------------------------------------
+@node Index
+@unnumbered Index
+@cindex Index
+
+@printindex cp
+
+@bye
+
+Local Variables:
+fill-column: 55
+End: