diff options
Diffstat (limited to 'doc/cvs.texinfo')
-rw-r--r-- | doc/cvs.texinfo | 15923 |
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: |