summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornate <nate@FreeBSD.org>1995-03-31 07:45:34 +0000
committernate <nate@FreeBSD.org>1995-03-31 07:45:34 +0000
commit97dcd3ee2c52c29f7f4f4ad1a792395166114f77 (patch)
tree839b28261115079f11388074d28948dfe43a9c4d
parent02981a52b9b7d28ced57a7a8115421fdd16789eb (diff)
downloadFreeBSD-src-97dcd3ee2c52c29f7f4f4ad1a792395166114f77.zip
FreeBSD-src-97dcd3ee2c52c29f7f4f4ad1a792395166114f77.tar.gz
Original sources from CVS-1.4A2 munged to fit our directory structure.
-rw-r--r--gnu/usr.bin/cvs/FAQ7826
-rw-r--r--gnu/usr.bin/cvs/README207
-rw-r--r--gnu/usr.bin/cvs/TODO610
-rw-r--r--gnu/usr.bin/cvs/contrib/clmerge156
-rw-r--r--gnu/usr.bin/cvs/contrib/cvs-format.el75
-rw-r--r--gnu/usr.bin/cvs/contrib/intro.doc112
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/NEWS113
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-lucid.el133
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs2log326
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs2sccs143
-rw-r--r--gnu/usr.bin/cvs/cvs/NOTES60
-rw-r--r--gnu/usr.bin/cvs/cvs/convert.sh28
-rw-r--r--gnu/usr.bin/cvs/cvs/cvsbug.sh533
-rw-r--r--gnu/usr.bin/cvs/cvs/cvsrc.c140
-rw-r--r--gnu/usr.bin/cvs/cvs/options.h202
-rw-r--r--gnu/usr.bin/cvs/cvs/root.c171
-rw-r--r--gnu/usr.bin/cvs/cvs/sanity.el18
-rw-r--r--gnu/usr.bin/cvs/cvs/sanity.sh1069
-rw-r--r--gnu/usr.bin/cvs/doc/cvs-paper.ms1073
-rw-r--r--gnu/usr.bin/cvs/doc/cvs.texinfo6644
-rw-r--r--gnu/usr.bin/cvs/lib/config.h133
-rw-r--r--gnu/usr.bin/cvs/lib/hostname.c49
-rw-r--r--gnu/usr.bin/cvs/lib/memmove.c57
-rw-r--r--gnu/usr.bin/cvs/lib/strerror.c813
-rw-r--r--gnu/usr.bin/cvs/lib/version.c20
25 files changed, 20711 insertions, 0 deletions
diff --git a/gnu/usr.bin/cvs/FAQ b/gnu/usr.bin/cvs/FAQ
new file mode 100644
index 0000000..38f8e15
--- /dev/null
+++ b/gnu/usr.bin/cvs/FAQ
@@ -0,0 +1,7826 @@
+
+Archive-name: cvs-faq
+$Revision: 1.1 $ <<== Include this in your comments
+$Date: 1994/10/07 06:17:45 $
+
+===========================================================================
+== Frequently Asked Questions about CVS (The Concurrent Versions System) ==
+===========================================================================
+
+ This document attempts to answer questions posed by users of CVS.
+
+ CVS installers, administrators and maintainers looking for info on
+ system setup should read the section entitled "Installing CVS".
+
+
+ Disclaimer:
+
+ Though every attempt has been made to ensure the veracity of the
+ following material, no responsibility is assumed for any use, or
+ for any consequences resulting from any use, of the information
+ contained herein. No guarantee of suitability for any purpose
+ is offered or implied. Nothing in this document may be assumed
+ to represent the employers of its contributors.
+
+ I also might have slipped in a whopper or two to see if you are
+ paying attention. ;-) In other words, don't bet the house on
+ anything you read here unless you have checked it out yourself.
+
+
+
+ Send questions and answers (along with additions to, subtractions
+ from, and divisions of existing questions -- no multiplications,
+ square roots, or transcendental functions, my cabinet is full of them)
+ to the author, who wrote all unattributed text: (Does it always
+ feel strange to refer to oneself in the third person?)
+
+ David G. Grubbs <dgg@think.com>
+
+
+ To help readers of previous versions of this document, I will annotate
+ each question with a change marker
+
+ Change markers: Column 1 will contain a:
+
+ '-' for a Question that has changed.
+ '=' for an Answer that has changed.
+ '#' for an entry with changes to both Question and Answer.
+ '+' for a newly added Question and Answer.
+
+
+ The markers indicate significant changes in content between major
+ revision numbers. Trivial changes, such as question reordering or
+ spelling and grammar corrections are not marked. If I need to delete
+ a question, I'll move it to a "Deleted" section for a few revisions.
+ Deletions will arise when new versions of CVS are released. In the
+ long run, any question that can be answered by "get the latest
+ release" will be deleted.
+
+ The minor revision number will change frequently. If a minor revision
+ change is large enough, I'll add a change marker. At major revision
+ changes the markers will be cleared and set again, based on the latest
+ minor revision of the previous major revision.
+
+
+
+ Editorial comments are delimited by pairs of "[[" & "]]". They
+ contain either references to the (usually unfinished) nature of the
+ FAQ entry itself or version-specific comments to be removed (or
+ altered) when new revisions of CVS are released.
+
+ You may redistribute this as long as you don't take statements out
+ of context. Keep it together along with the revision number.
+
+
+============================================
+== Section 0 ==== Introduction ====
+============================================
+
+The questions in this document come from many sources in many forms. Some
+are simple, some verbose. A few are difficult, but all of them have been
+asked of the author at one time or another. Some questions are really
+three or more different problems rolled into one plaintive cry for help.
+Others reveal one of the bugs or weaknesses of CVS.
+
+CVS addresses some difficult problems to which there are no perfect
+solutions. CVS also changes over time as new features are required.
+
+Therefore, the questions are about a complicated moving target.
+
+Though in most cases I've tried to provide the simplest answer I can
+think of, some of the *questions* are difficult to follow. If you
+aren't using CVS regularly, don't expect to understand everything.
+
+A Frequently Asked Questions document is not a substitute for the man page
+or any other documentation. It is an attempt to answer questions.
+
+You should also keep in mind that FAQs are not really intended to be
+read in their entirety like a text book. You should use "grep" or
+your editor's search capability to hunt for keywords and read the
+sections you need.
+
+
+Questions are divided into five numbered Sections. Sections are divided
+into lettered sub-sections. The questions are numbered sequentially
+within each sub-section, though they are in no particular order.
+
+
+ 1. What is CVS?
+ A. What is CVS? What's it for? Why CVS?
+ B. Where do I find it? Where can I find Help?
+ C. How does CVS differ from other similar software?
+ D. What do you mean by . . .? (Definitions)
+
+ 2. User Tasks
+ A. Getting Started
+ B. Common User Tasks
+ C. Less Common User Tasks
+ D. General Questions
+
+ 3. Commands
+ A. through P. One section for each CVS command.
+
+ 4. Advanced Topics
+ A. Installing CVS
+ B. Setting up and Managing the Repository
+ C. Branching
+ D. Tricks of the Trade
+ E. Weirdness
+ F. Related Software
+ G. Other Systems
+
+ 5. Past & Future
+ A. Contributors.
+ B. Bugs and Patches
+ C. Development
+
+ 6. Table of Contents
+
+
+Final note:
+
+ Except for the "Past & Future" section, all answers in this
+ document refer to the latest released version of CVS: 1.3.
+
+
+============================================
+== Section 1 ==== What is CVS? ====
+============================================
+
+----------------
+-- Section 1A -- What is CVS? What's it for? Why CVS?
+----------------
+
+ **** Questions:
+
+ 1A.1 What does CVS stand for? Can you describe it in one sentence?
+ 1A.2 What is CVS for? What does it do for me?
+ 1A.3 How does CVS work?
+=1A.4 What is CVS useful for?
+=1A.5 What is CVS *not* useful for?
+=1A.6 Why isn't it called OSCO (Online Source COntrol)?
+
+
+ **** Answers:
+
+ 1A.1 What does CVS stand for? Can you describe it in one sentence?
+
+ "CVS" is an acronym for the "Concurrent Versions System".
+
+ CVS is a "Source Control" or "Revision Control" tool
+ designed to keep track of changes to files made by groups of
+ developers working on the same files, allowing them to
+ stay in sync with each other as each individual chooses.
+
+
+ 1A.2 What is CVS for? What does it do for me?
+
+ CVS is used to keep track of collections of files in a shared
+ directory, called "The Repository". Each collection of files
+ can be given a "module" name, which is used to "checkout"
+ that collection.
+
+ After checkout, files can be modified (using your favorite
+ editor), "committed" back into the Repository and compared
+ against earlier revisions. Collections of files can be
+ "tagged" with a symbolic name for later retrieval.
+
+ You can add new files, remove files you no longer want, ask for
+ information about sets of files in three different ways,
+ produce patch "diffs" from a base revision and merge the
+ committed changes of other developers into your working files.
+
+
+ 1A.3 How does CVS work?
+
+ CVS stores its files in a directory hierarchy, called the
+ Repository, which is separate from the user's working directory.
+
+ Files in the Repository are stored in a format dictated by the
+ RCS commands CVS uses to do much of its real work. RCS files
+ are standard byte-stream files with an internal format described
+ by keywords stored in the files themselves.
+
+ To begin work, you execute the "checkout" command, handing it
+ a module or directory you want to work on. CVS copies each file
+ in the specified module or directory out of the Repository and
+ into a sub-directory created in your current directory.
+
+ You may then modify files in the new sub-directory, building them
+ into output files and testing the results. When you want to make
+ your changes available to other developers, you "commit" them back
+ into the Repository.
+
+ Other developers can check out the same files at the same time.
+ To merge the committed work of others into your working files
+ you use the "update" command. When your merged files build
+ and test correctly, you may commit the merged result. This
+ method is referred to as "copy-modify-merge", which does not
+ require locks on the source files.
+
+ At any time, usually at some milestone, you can "tag" the
+ committed files, producing a symbolic name that can be handed
+ to a future "checkout" command. A special form of "tag"
+ can produce a branch in development, as usually happens at
+ "release" time.
+
+ When you no longer plan to modify or refer to your local copy
+ of the files, they can be removed.
+
+
+=1A.4 What is CVS useful for?
+
+ CVS is intended to be useful for three major activities:
+
+ 1. Multiple developers
+
+ The major advantage of using CVS over the older and simpler
+ tools like RCS or SCCS is that it allows multiple developers
+ to work on the same sources at the same time.
+
+ The shared Repository provides a rendezvous point for
+ committed sources that allows developers a fair amount of
+ flexibility in how often to publish (via the "commit"
+ command) changes or include work committed by others (via the
+ "update" command).
+
+
+ 2. Vendor releases
+
+ If you are making changes to a product distributed by someone
+ else, the CVS feature, called the Vendor Branch, allows you
+ to combine local modifications with vendor releases.
+
+ I have found this most useful when dealing with sources from
+ three major classes of source vendor:
+
+ a. Large companies who send you tapes full of the latest
+ release (e.g. Unix OS vendors, database companies).
+
+ b. Public Domain software which *always* requires work.
+
+ c. Pseudo-Public sources which require medium amounts of
+ work. (e.g. GNU programs, X, etc.)
+
+
+ 3. Branches
+
+ Aside from the "Vendor Branch", there are three kinds of
+ "branches in development" that CVS can support:
+
+ a. Your working directory can be treated as a private branch.
+
+ b. A Development branch can be shared by one or more developers.
+
+ c. At release time, a branch is usually created for bug fixes.
+
+ (See 1D.9 and Section 4C for more info on branches.)
+
+ Although, at this writing, CVS's branch support is a bit
+ primitive, CVS was designed to allow you to create branches,
+ work on them for while and merge them back into the main
+ line of development. Arbitrary sharing and merging between
+ branches is not currently supported.
+
+
+=1A.5 What is CVS *not* useful for?
+
+ CVS is not a build system.
+
+ Though the structure of your Repository and modules file
+ interact with your build system (e.g. Makefiles), they are
+ essentially independent.
+
+ CVS does not dictate how you build anything. It merely stores
+ files for retrieval in a tree structure you devise.
+
+ CVS does not dictate how to use disk space in the checked
+ out working directories. If you write your Makefiles 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. That's simply bad planning.
+
+ If you modularize your work, and construct a build system
+ that will share files (via links, mounts, VPATH in Makefiles,
+ etc.), you can arrange your disk usage however you like.
+
+ But you have to remember that *any* such system is a lot of
+ work to construct and maintain. CVS does not address the
+ issues involved. You must use your brain and a collection
+ of other tools to provide a build scheme to match your plans.
+
+ Of course, you should place the tools created to support such
+ a build system (scripts, Makefiles, etc) under CVS.
+
+
+ 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, CVS can't help.
+
+ 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.
+
+
+ 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.
+
+ 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 "conflict" is
+ purely textual, arising when two changes to the same base file
+ are near enough to spook the merge (i.e. "diff3") command.
+
+ 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 X
+ defined in file A. At the same time, someone edits file B,
+ adding new calls to function X using the old arguments. You
+ are outside the realm of CVS's competence.
+
+ Acquire the habit of reading specs and talking to your peers.
+
+
+ CVS is not a configuration management system.
+
+ CVS is a source control system. The phrase "configuration
+ management" is a marketing term, not an industry-recognized
+ set of functions.
+
+ A true "configuration management system" would contain
+ elements of the following:
+
+ * Source control.
+ * Dependency tracking.
+ * Build systems (i.e. What to build and how to find
+ things during a build. What is shared? What is local?)
+ * Bug tracking.
+ * Automated Testing procedures.
+ * Release Engineering documentation and procedures.
+ * Tape Construction.
+ * Customer Installation.
+ * A way for users to run different versions of the same
+ software on the same host at the same time.
+
+ CVS provides only the first.
+
+
+=1A.6 Why isn't it called OSCO (Online Source COntrol)?
+
+ Better discount? CVS is shorter? (The international audience
+ requires an explanation: Both CVS and OSCO are the names of large
+ chains of Pharmacies (drug stores) in the U.S.)
+
+
+
+----------------
+-- Section 1B -- Where do I find CVS? Where can I find Help?
+----------------
+
+ **** Questions:
+
+ 1B.1 How do I get more information about CVS?
+ 1B.2 Is there an archive of CVS material?
+ 1B.3 How do I get a copy of the latest version of CVS?
+ 1B.4 Is there any other documentation? How about tutorials?
+ 1B.5 Is there a mailing list devoted to CVS? How do I get on it?
+ 1B.6 What prayers are appropriate for each of the major denominations
+ (e.g. 20's, 50's, 100's) when issuing complex CVS commands?
++1B.7 How do I get files out of the archive if I don't have FTP?
+
+
+ **** Answers:
+
+=1B.1 How do I get more information about CVS?
+
+ 1. The first thing you should do is read the man page.
+
+ 2. Type "cvs -H" for general help or "cvs -H command" for
+ command-specific help.
+
+ 3. Read the original CVS paper (in the source tree, under "doc").
+ It describes the purpose of CVS and some of its workings. Note
+ that some of the emphasis (especially on multiple vendors
+ providing the same sources) is out of date.
+
+ 4. Read the man pages for RCS.
+
+ 5. Read the source code.
+
+ 6. Look in the "doc" directory in the FTP archive described
+ below.
+
+ 7. Read the gnu.cvs.info newsgroup.
+
+ 8. If you don't get the newsgroup, you can join the info-cvs
+ mailing list, described below.
+
+
+ 1B.2 Is there an archive of CVS material?
+
+ An anonymous FTP area has been set up. It contains many of the
+ CVS files you might want, including documentation, patches and
+ the latest release.
+
+ ftp think.com
+ >>> User: anonymous
+ >>> Passwd: <Your Internet address>
+ cd /pub/cvs
+ get README
+ get Index
+
+ The README has more (and more up-to-date) information. The Index
+ contains a terse list of what is in the archive.
+
+
++1B.3 How do I get files out of the archive if I don't have FTP?
+
+ Use one of the FTP<->Email servers. These are the ones
+ I've been told about:
+
+
+ 1. To use DEC's ftpmail service, type
+
+ echo 'send help' | mail ftpmail@decwrl.dec.com
+
+ which will send you a message telling you how to use Email to
+ retrieve files from FTP archives.
+
+
+ 2. If you are on BITNET, use Princeton's BITFTP server. Type
+
+ echo 'send help' | mail bitftp@pucc.princeton.edu
+
+ (It is likely that only BITNET addresses can use this one.)
+
+
+ 3. Other possibilities I've heard of from the net:
+ (Try the one closest to you.)
+
+ ftpmail@sunsite.unc.edu
+ ftpmail@cs.arizona.edu
+ ftpmail@cs.uow.edu.au
+ ftpmail@doc.ic.ac.uk
+
+
+ 1B.4 How do I get a copy of the latest version of CVS?
+
+ The latest released version of CVS and all the programs it
+ depends on should be available through anonymous FTP on any FSF
+ archive. The main FSF archive is at "prep.ai.mit.edu". There is
+ another archive at UUNET and other large Internet sites.
+
+ Program(s) Latest revision
+ ----------- -----------------------
+ CVS 1.3
+ RCS 5.6.0.1
+ GNU diff 2.3
+
+ The GNU version of diff is suggested by both the RCS and CVS
+ configuration instructions because it works better than the
+ standard version. If you plan to use dbm in the modules file, you
+ might also want to pick up the GNU dbm library.
+
+ It is a good idea not to accept the versions of CVS, RCS or diff
+ you find lying on your system unless you have checked out their
+ provenance. Using inconsistent collections of tools can cause you
+ more trouble than you probably want.
+
+ The FTP archive mentioned above should contain the latest official
+ release of CVS, some official and unofficial patches and possibly
+ complete patched versions of CVS in use somewhere.
+
+
+ 1B.5 Is there any other documentation? How about tutorials?
+
+ Take a look at the "doc" sub-directory in the FTP archive.
+ You should find a growing collection of additional CVS
+ documentation there.
+
+ Other sources:
+
+ 1. Per Cederqvist's Texinfo manual.
+
+ The latest version of the Texinfo manual written by Per
+ Cederqvist is included in the "doc" area mentioned
+ above.
+
+
+ 2. Gray Watson's cvs_tutorial.
+
+ There is a version of this document in the "doc" area.
+
+ 3. Apparently there is at least one project at O'Reilly (on
+ RCS/SCCS) that will include some info about CVS.
+
+
+ [[Anything else?]]
+
+
+#1B.6 Is there a mailing list or Usenet newsgroup devoted to CVS?
+ How do I find them?
+
+ An Internet mailing list named "info-cvs" grew out of the private
+ mailing list used by the CVS 1.3 alpha testers in early 1992. An
+ associated Usenet newsgroup named "gnu.cvs.info" was created in
+ August, 1993.
+
+ The newsgroup and the mailing list are bidirectionally gatewayed,
+ meaning that you only need access to one of them. Anything sent
+ to the mailing list will be automatically posted to "gnu.cvs.info"
+ and anything posted to the newsgroup will be automatically mailed
+ to "info-cvs".
+
+ First try the newsgroup, since it is generally easier to read (and
+ manage) than a mailing list. Ask your system administrator
+ whether you get the "gnu" hierarchy. If so, select a newsreader
+ and dive in.
+
+ If you don't get any form of Usenet News (or don't get the "gnu"
+ hierarchy), you can add yourself to the mailing list by sending an
+ Email message to:
+
+ info-cvs-request@prep.ai.mit.edu
+
+ (Don't forget the "-request" or you'll send a message to the
+ whole list, some of whom are capable of remote execution.)
+
+ Mail to the whole list should be sent to:
+
+ info-cvs@prep.ai.mit.edu
+
+ An archive of the mailing list and the newsgroup might appear
+ someday in the CVS FTP archive.
+
+
+ 1B.7 What prayers are appropriate for each of the major denominations
+ (e.g. 20's, 50's, 100's) when issuing complex CVS commands?
+
+ Only what the traffic will allow, in small, unmarked bills
+ delivered to me, Ralph Icebag, in a plain brown wrapper, by a
+ brown-shoed square, in the dead of night. (Apologies to
+ Firesign Theater.)
+
+
+
+----------------
+-- Section 1C -- How does CVS differ from other similar software?
+----------------
+
+This section attempts to list programs purporting to cover some of the
+same territory as CVS. [[These are very sparsely documented here. If you
+know something about one of these tools, how about trying to flesh out an
+entry or two?]]
+
+
+ **** Questions:
+
+=1C.1 How does CVS differ from RCS?
+ 1C.2 How does CVS differ from SCCS?
+=1C.3 How does CVS differ from ClearCase?
+=1C.4 How does CVS differ from TeamWare?
+ 1C.5 How does CVS differ from SunPro?
+ 1C.6 How does CVS differ from Aegis?
+ 1C.7 How does CVS differ from Shapetools?
++1C.8 How does CVS differ from TeamNet?
++1C.9 How does CVS differ from ProFrame?
++1C.10 How does CVS differ from CaseWare/CM?
++1C.11 How does CVS differ from Sublime?
+
+
+ **** Answers:
+
+
+=1C.1 How does CVS differ from RCS?
+
+ CVS uses RCS to do much of its work and absolutely all the work
+ of changing the underlying RCS files in the Repository.
+
+ RCS comprises a set of programs designed to keep track of changes
+ to individual files. Of course, it also allows you to refer to
+ whole sets of files on the command line, but groups are
+ manipulated by iterating over those files. There is no pretense
+ of combined interaction between the files.
+
+ CVS's main intent is to provide a set of grouping functions that
+ allow you to treat a collection of RCS files as a single object.
+ Of course, CVS also has to do a lot of iteration, but it tries
+ its best to hide that it is doing so. In addition, CVS has some
+ truly group-oriented facets, such as the modules file and the CVS
+ administrative files that refer to a whole directory or module.
+
+ One group aspect that can be a bit confusing is that a CVS branch
+ is not the same as an RCS branch. To support a CVS branch, CVS
+ uses "tags" (what RCS calls "symbols") and some local state,
+ in addition to RCS branches.
+
+ Other features offered by CVS that are not supported directly by
+ RCS are
+
+ 1. Automatic determination of the state of a file, (e.g.
+ modified, up-to-date with the Repository, already tagged
+ with the same string, etc.) which helps in limiting the
+ amount of displayed text you have to wade through to
+ figure out what changed and what to do next.
+
+ 2. A copy-modify-merge scheme that avoids locking the files
+ and allows simultaneous development on a single file.
+
+ 3. Serialization of commits. CVS requires you to merge all
+ changes committed (via "update") since you checked out
+ your working copy of the file. Although it is still
+ possible to commit a file filled with old data, it is less
+ likely than when using raw RCS.
+
+ 4. Relatively easy merging of releases from external Vendors.
+
+
+
+ 1C.2 How does CVS differ from SCCS?
+
+ SCCS is much closer to RCS than to CVS, so some of the previous
+ entry applies.
+
+ You might want to take a look at Walter Tichy's papers on RCS,
+ which are referred to in the RCS man pages.
+
+ [[More info here?]]
+
+
+=1C.3 How does CVS differ from ClearCase?
+
+ ClearCase is a client-server CASE tool for version management,
+ configuration management, and process management. ClearCase
+ is an evolution of the popular DSEE tools, formerly available
+ on HP/Apollo platforms. ClearCase includes an X/Motif GUI,
+ command-line interface, and C programmer API, and is currently
+ available on Sun, HP, and SGI platforms.
+
+ ClearCase uses a special Unix filesystem type, called "mfs"
+ for "multi-version file system". Conceptually, mfs adds
+ another dimension to the regular Unix filesystem. The new
+ axis is used to store the different versions of files. Each
+ user makes a "view" into the file database by creating a
+ special mfs mountpoint on their machine. Each view has a set
+ of flexible selection rules that specify the particular
+ version of each file to make visible in that view. You can
+ think of a "view" as a workarea in CVS, except that the files
+ don't really exist on your local disk until you modify them.
+ This type of filesystem is sometimes called "copy-on-write"
+ and conserves disk space for files that are read-only.
+ Another advantage is that a view is "tranparent" in the sense
+ that all of the files in a "view" appear to be regular Unix
+ files to other tools and Unix system calls. An extended
+ naming convention allows access to particular versions of a
+ file directly: "test.cc@@/main/bugfix/3" identifies the third
+ version of test.c on the bugfix branch.
+
+ ClearCase supports both the copy-modify-merge model of CVS and
+ the checkin/checkout development model with file locking.
+ Directories are versionable objects as well as files. A
+ graphical n-way merge tool is provided. Like CVS, ClearCase
+ supports branches, symbolic tags, and delta compression.
+ ASCII as well as binary files are supported, and converters
+ from RCS, SCCS, DSEE formats are also included.
+
+ A make-compatible build facility is provided that can identify
+ common object code and share it among developers. A build
+ auditing feature automatically records file dependencies by
+ tracking every file that is opened when producing a derived
+ object, thus making explicit Makefiles unnecessary. Pre- and
+ post-event triggers are available for most ClearCase
+ operations to invoke user programs or shell scripts.
+ User-defined attributes can be assigned to any version or
+ object. Hyperlinks between versioned objects can record their
+ relationship.
+
+ For more information, contact:
+
+ Atria Software, Inc.
+ 24 Prime Park Way
+ Natick, MA 01760
+ info@atria.com
+
+ (508) 650-1193 (phone)
+ (508) 650-1196 (fax)
+
+ Contributed by Steve Turner
+ [extracted from the ClearCase 1.1.1 documentation]
+
+
+=1C.4 How does CVS differ from TeamWare?
+
+ TeamWare is a configuration management tool from Sun
+ Microsystems.
+
+ For more information, contact:
+
+ SunExpress, Inc.
+ P.O. Box 4426
+ Bridgeton, MO 63044-9863
+ (800)873-7869
+
+
+ 1C.5 How does CVS differ from SunPro?
+
+ SunPro is advertised as the successor to "SCCS".
+
+ [[Need more info here.]]
+
+
+ 1C.6 How does CVS differ from Aegis?
+
+ Aegis appears to be a policy-setting tool that allows you to use
+ other sub-programs (make, RCS, etc.) to implement pieces of the
+ imposed policy.
+
+ The initial document seems to say that most Unix tools are
+ inadequate for use under Aegis.
+
+ It is not really similar to CVS and requires a different mindset.
+
+ [[Need more info here.]]
+
+
+ 1C.7 How does CVS differ from Shapetools?
+
+ Shapetools includes a build mechanism (called Shape, not
+ surprisingly) that is aware of the version mechanism, and some
+ dependency tracking. It is based on a file system extension
+ called Attributed File System, which allows arbitrary-sized
+ "attributes" to be associated with a file. Files are versioned in
+ a manner similar to RCS. Configurations are managed through the
+ Shapefile, an extension of the Makefile syntax and functionality.
+ Shape includes version selection rules to allow sophisticated
+ selection of component versions in a build.
+
+ Shapetools' concurrency control is pessimistic, in contrast to
+ that of CVS. Also, there's very limited support for branching and
+ merging. It has a built-in policy for transitioning a system from
+ initial development to production.
+
+ Contributed by Don Dwiggins
+
+
++1C.8 How does CVS differ from TeamNet?
+
+ TeamNet is a configuration management tool from TeamOne.
+
+ For more information, contact:
+
+ TeamOne
+ 710 Lakeway Drive, Ste 100
+ Sunnyvale, CA 94086
+ (800) 442-6650
+
+ Contributed by Steve Turner
+
+
++1C.9 How does CVS differ from ProFrame?
+
+ ProFrame is a new system integration framework from IBM.
+ ProFrame is compliant with the CFI (CAD Framework Initiative)
+ industry standards, including the Scheme extension language.
+
+ ProFrame consists of three major components: (1) the Process
+ Manager that automates your local design methodology (2) the
+ Design Data Manager handles configuration management, and (3)
+ Inter-tool Communication to provide a communication path among
+ tools running on heterogeneous servers.
+
+ The Design Data Manager(2) is probably the appropriate
+ component to compare to CVS. The Design Data Manager provides
+ version control with checkin/checkout capability,
+ configuration management, and data dependency tracking. A
+ graphical data selection interface is provided. Using this
+ interface, you may create and manipulate objects and hierarchy
+ structures, view the revision history for an object, and view
+ and assign attributes to a design object.
+
+ The ProFrame server currently runs only on RS600, but clients
+ may be a wide variety of Unix platforms. Contact IBM for the
+ latest platform information.
+
+ For more information, contact:
+
+ IBM
+ EDA Marketing and Sales
+ P.O. Box 950, M/S P121
+ Poughkeepsie, NY 12602
+ (800) 332-0066
+
+
+ Contributed by Steve Turner
+ [extracted from the ProFrame 1.1.0 datasheet]
+
+
++1C.10 How does CVS differ from CaseWare/CM?
+
+ CaseWare/CM is a software configuration management product
+ from CaseWare, Inc. CaseWare/CM may be customized to support
+ a wide variety of methodologies, including various phases of
+ the software lifecycle, and different access rights for users.
+
+ A GUI is provided to view version histories and
+ configurations. A merge tools is also included. CaseWare
+ supports type-specific lifecycles, which allows different types
+ of files to move through different lifecycles. Also provided
+ is a build facility to support automatic dependency analysis,
+ parallel, distributed, and remote builds, and variant
+ releases.
+
+ CaseWare/CM has been integrated with other CASE tools,
+ including FrameMaker, ALSYS Ada, CodeCenter/Object Center, HP
+ SoftBench, and Software Through Pictures. CaseWare also
+ offers CaseWare/PT, a problem tracking system to integrate
+ change requests with configuration management.
+
+ Multiple vendors and operating systems are supported.
+
+ For more information, contact:
+
+ CaseWare, Inc.
+ 108 Pacifica, 2nd Floor
+ Irvine, CA 92718-3332
+ (714) 453-2200 (phone)
+ (714) 453-2276 (fax)
+
+ Contributed by Steve Turner
+ [extracted from the CaseWare/CM data sheet]
+
+
++1C.11 How does CVS differ from Sublime?
+
+ Produced by AT&T.
+
+ [[Need more info here.]]
+
+
+----------------
+-- Section 1D -- What do you mean by . . .? (Definitions)
+----------------
+
+ **** Questions:
+
+#1D.1 What are "The Repository", "$CVSROOT" and "CVSROOT"?
+ 1D.2 What is an RCS file?
+ 1D.3 What is a working file?
+ 1D.4 What is a working directory (or working area)?
+ 1D.5 What is "checking out"?
+=1D.6 What is a revision?
+ 1D.7 What is a "Tag"?
+=1D.8 What are "HEAD" and "BASE"?
+=1D.9 What is a Branch?
+=1D.10 What is "the trunk"?
+=1D.11 What is a module?
++1D.12 What does "merge" mean?
+
+
+ **** Answers:
+
+
+#1D.1 What are "The Repository", "$CVSROOT" and "CVSROOT"?
+
+ The Repository is a directory tree containing the CVS
+ administrative files and all the RCS files that constitute
+ "imported" or "committed" work. The Repository is kept in a
+ shared area, separate from the working areas of all developers.
+
+ Users of CVS must set their "CVSROOT" environment variable to the
+ absolute pathname of the head of the Repository. Most command
+ line interpreters replace an instance of "$CVSROOT" with the value
+ of the "CVSROOT" environment variable. By analogy, in this
+ document "$CVSROOT" is used as shorthand for "the absolute
+ pathname of the directory at the head of the Repository".
+
+ One of the things found in $CVSROOT is a directory named CVSROOT.
+ It contains all the "state", the administrative files, that CVS
+ needs during execution. The "modules", "history", "commitinfo",
+ "loginfo" and other files can be found there.
+
+
+ 1D.2 What is an RCS file?
+
+ A file, usually ending in ",v", containing the source text and
+ the revision history for all committed revisions of a source
+ file. It is stored separately from the working files, in a
+ directory hierarchy, called the Repository.
+
+ RCS is the "Revision Control System" that CVS uses to manage
+ individual files.
+
+
+ 1D.3 What is a working file?
+
+ A disk file containing a checked-out copy of a source file that
+ earlier had been placed under CVS. If the working file has been
+ edited, the changes since the last committed revision are
+ invisible to other users of CVS.
+
+
+ 1D.4 What is a working directory (or working area)?
+
+ The "checkout" command creates a tree of working directories,
+ filling them with working files. A working directory always
+ contains a sub-directory named ./CVS containing information
+ about working files and the location of the directory within the
+ Repository that was used to create the working directory.
+
+ A working directory is the place where you work and the place
+ from which you "commit" files.
+
+
+ 1D.5 What is "checking out"?
+
+ "Checking out" is the act of using the "checkout" command to
+ copy a particular revision from a set of RCS files into your
+ working area. See the "checkout" command in Section 3C.
+
+
+=1D.6 What is a revision?
+
+ A "revision" is a version of a file that was "committed" (or
+ "checked in", in RCS terms) some time in the past. CVS (and
+ RCS) can retrieve any file that was committed by specifying its
+ revision number or its "tag" (or symbolic name, in RCS terms).
+
+ In CVS, a "tag" is more useful than a revision number. It usually
+ marks a milestone in development represented by different revision
+ numbers in different files, all available as one "tagged"
+ collection.
+
+ Sometimes the word "revision" is used as shorthand for "the file
+ you get if you retrieve (via "checkout" or "update") the given
+ revision from the Repository."
+
+
+ 1D.7 What is a "Tag"?
+
+ A "Tag" is a symbolic name, a synonym or alias for a
+ particular revision number in a file. The CVS "tag" command
+ places the same "Tag" on all files in a working directory,
+ allowing you to retrieve those files by name in the future.
+
+
+=1D.8 What are "HEAD" and "BASE"?
+
+ BASE and HEAD are built-in tags that don't show up in the "log"
+ or "status" listings. They are interpreted directly by CVS.
+
+ "HEAD" refers to the latest revision on the current branch in the
+ Repository. The current branch is either the main line of
+ development, or a branch in development created by placing a
+ branch tag on a set of files and checking out that branch.
+
+ "BASE" refers to the revision on the current branch you last
+ checked out, updated, or committed. If you have not modified
+ your working file, "BASE" is the committed revision matching it.
+
+ Most of the time BASE and HEAD refer to the same revision. They
+ become different for two reasons:
+
+ 1. Someone else changed HEAD by committing a new revision of your
+ file to the Repository. You can pull BASE up to equal HEAD by
+ executing "update".
+
+ 2. You moved BASE backward by executing "checkout" or "update"
+ with the option "-r <rev/tag>" or "-D <date>". CVS records a
+ sticky tag and moves your files to the specified earlier
+ revision. You can clear the sticky tag and pull BASE up to
+ equal HEAD by executing "update -A".
+
+
+=1D.9 What is a Branch?
+
+ Any mechanism that allows one or more developers to modify a
+ physically separate copy of a file without affecting anyone other
+ than those working on the branch.
+
+ There are four kinds of branches CVS deals with:
+
+ 1. The Vendor Branch.
+
+ A single vendor branch is supported. The "import" command
+ takes a sequence of releases from a source code vendor (called
+ a "vendor" even if no money is involved), placing them on a
+ special "Vendor" branch. The Vendor branch is considered part
+ of the "Main line" of development, though it must be merged
+ into locally modified files on the RCS Main branch before the
+ "import" is complete.
+
+ See Section 3H ("import").
+
+ 2. Your Working directory.
+
+ A checked-out working directory, can be treated like a private
+ branch. No one but you can touch your files. You have
+ complete control over when you include work committed by
+ others. However, you can't commit or tag intermediate versions
+ of your work.
+
+ 3. A Development branch.
+
+ A group of developers can share changes among the group,
+ without affecting the Main line of development, by creating a
+ branch. Only those who have checked-out the branch see the
+ changes committed to that branch. This kind of branch is
+ usually temporary, collapsing (i.e. merge and forget) into the
+ Main line when the project requiring the branch is completed.
+
+ You can also create a private branch of this type, allowing an
+ individual to commit (and tag) intermediate revisions without
+ changing the Main line. It should be managed exactly like a
+ Development Branch -- collapsed into the Main line and
+ forgotten when the work is done.
+
+ 4. A Release branch.
+
+ At release time, a branch should be created marking what was
+ released. Later, small changes (sometimes called "patches")
+ can be made to the release without including everything else on
+ the Main line of development. You avoid forcing the customer
+ to accept new, possibly untested, features added since the
+ release. This is also the way to correct bugs found during
+ testing in an environment where other developers have continued
+ to commit to the Main line while you are testing and packaging
+ the release.
+
+ Although the internal format of this type of branch (branch tag
+ and RCS branches) is the same as in a development branch, the
+ purpose and the way it is managed are different. The major
+ difference is that the branch is Permanent. Once you let a
+ release out the door to customers, or to the next stage of
+ whatever process you are using, you should retain forever the
+ branch marking the release.
+
+ Since the branch is permanent, you cannot incorporate the
+ branch fixes into the Main line by "collapsing" (merging and
+ forgetting) the release branch. For large changes to many
+ files on the release branch, you will have to perform a branch
+ merge using "update -j <rev> -j <rev>". (See 4C.7)
+
+ The most common way to merge small changes back into Main line
+ development is to make the change in both places
+ simultaneously. This is faster than trying to perform a
+ selective merge.
+
+ See 1D.12 (merges) and Section 4C, on Branching for more info.
+
+
+=1D.10 What is "the trunk"?
+
+ Another name for the RCS Main Branch. The RCS Main Branch is
+ related, but not equivalent, to both the CVS Main branch and what
+ developers consider to be the Main line of development.
+ See 3H.3 and Section 4C on Branching.
+
+
+=1D.11 What is a module?
+
+ In essence, a module is a name you hand to the "checkout" command
+ to retrieve one or more files to work on. It was originally
+ intended to be a simple, unique name in the "modules" file
+ attached to a directory or a subset of files within a directory.
+
+ The module idea is now a somewhat slippery concept that can be
+ defined in two different ways:
+
+ A. A module is an argument to "checkout". There are three types:
+
+ 1. An entry in the modules file. A "module" name as described
+ in 'B.' below.
+
+ 2. A relative path to a directory or file in the Repository.
+
+ 3. A mixed-mode string of "modulename/relative-path".
+ Everything up to the first slash ('/') is looked up as a
+ module. The relative path is appended to the directory
+ associated with the module name and the resulting path is
+ checked out as in #2 above.
+
+
+ B. A module is a unique (within the file) character string in the
+ first column of the modules file. There are five types:
+
+ 1. A name for a directory within the Repository that
+ allows you to ignore the parent directories above it.
+
+ Example:
+
+ emacs gnu/emacs
+
+
+ 2. A name for a subset of the files within such a directory.
+
+ Example:
+
+ ls unix/bin Makefile ls.c
+
+
+ The 2nd through Nth strings in the above must be *files*.
+ No directories, no relative pathnames. To checkout more
+ than one directory by a single name, use an alias as
+ described in #5 below.
+
+
+ 3. A relative pathname to a directory within the Repository
+ which, when checked out, creates an image of part of the
+ Repository structure in your current directory.
+
+ Example:
+
+ gnu/emacs -o /emacs.helper gnu/emacs
+
+ The files checked out are exactly the same as the files you
+ would get if the path weren't even in the modules file. The
+ only reason to put this kind of relative pathname into the
+ modules file is to hook one of the helper functions onto it.
+
+
+ 4. A relative pathname to a single file within the Repository
+ which, when checked out, creates something you probably
+ don't want: It creates a directory by the name of the file
+ and puts the file in it.
+
+ Example:
+
+ gnu/emacs/Makefile -o /emacs.helper gnu/emacs Makefile
+
+ The file checked out is the same as what you would get if
+ you handed the relative pathname to the "checkout" command.
+ But it puts it in a strange place. The only reason to do
+ this is to hook a helper function onto a specific file name.
+
+
+ 5. An alias consisting of a list of any of the above, including
+ other aliases.
+
+ Example:
+
+ my_work -a emacs gnu/bison unix/bin/ls.c
+
+
+ Another way to look at it is that the modules file is simply
+ another way to "name" files. The hierarchical directory
+ structure provides another. You should use whatever turns out to
+ be simplest for your development group.
+
+
+ As an example, say you want to keep track of three programs, and
+ want to be allowed to check out any combination of one, two or all
+ three at a time. Here are most of the combinations I can think
+ of. Experiment and choose what you want -- you won't need every
+ possibility.
+
+
+ # All directories in "world", even ones added later.
+ world world
+
+ # All three programs by name. They checkout into local dir.
+ prog123 -a prog1 prog2 prog3
+
+ # All three programs by name. They checkout into "world" subdir.
+ wprog123 -a wprog1 wprog2 wprog3
+
+ # Individual progs checkout into dirs named "prog1", etc.
+ prog1 world/prog1
+ prog2 world/prog2
+ prog3 world/prog3
+
+ # Individual progs checkout into dirs named "world/prog1", etc.
+ wprog1 -a world/prog1
+ wprog2 -a world/prog2
+ wprog3 -a world/prog3
+
+ # Pairs that checkout into local dir.
+ prog12 -a prog1 prog2
+ prog13 -a prog1 prog3
+ prog23 -a prog2 prog3
+
+ # Pairs that checkout into world subdir.
+ # Instead of using the wprog aliases, we could use "world/prog9"
+ wprog12 -a wprog1 wprog2
+ wprog13 -a wprog1 wprog3
+ wprog23 -a wprog2 wprog3
+
+
++1D.12 What does "merge" mean?
+
+ A merge is a way of combining changes made in two independent
+ copies of the same "base" file. There are always three files
+ involved in a merge: the original, or "base", file and two
+ copies of that base file modified in different ways.
+
+ Humans aren't very good at handling three things at once, so the
+ terminology dealing with merges can become strained. One way to
+ think about it is that all merges are performed by inserting the
+ difference between a base revision and a later revision (committed
+ by someone else) into your working file. Both the "later"
+ revision and your working file are presumed to have started life
+ as a copy of the "base" revision.
+
+ In CVS, there are three main types of "merge":
+
+ 1. The "update" command automatically merges revisions committed
+ by others into your working file. In this case, the three
+ files involved in the merge are:
+
+ Base: The revision you originally checked out.
+ Later: A revision committed onto the current branch
+ after you checked out the Base revision.
+ Working: Your working file. The one lying in the working
+ directory containing changes you have made.
+
+ 2. The "update -j <branch_tag>" command merges a whole branch into
+ your working file, which is presumed to be on the Main line of
+ development.
+
+ See 4C.6
+
+ 3. The "update -j <rev> -j <rev>" merges the difference between
+ two specific revisions on some other branch (though the two
+ revisions are usually on the same branch) into your working
+ directory.
+
+ See 4C.7
+
+
+
+
+==========================================
+== Section 2 ==== User Tasks ====
+==========================================
+
+----------------
+-- Section 2A -- Getting Started
+----------------
+
+ **** Questions:
+
+ 2A.1 What is the first thing I have to know?
+ 2A.2 Where do I work?
+=2A.3 What does CVS use from my environment?
+ 2A.4 OK, I've been told that CVS is set up, my module is named
+ "ralph" and I have to start editing. What do I type?
+ 2A.5 I have been using RCS for a while. Can I convert to CVS without
+ losing my revision history? How about converting from SCCS?
+
+
+ **** Answers:
+
+ 2A.1 What is the first thing I have to know?
+
+ Your organization has assigned one or more persons to understand,
+ baby-sit and administer both the CVS programs and the data
+ Repository. I call these persons Repository Administrators.
+ They will have set up a Repository and "imported" files into it.
+
+ If you don't believe anyone has this responsibility, or you are
+ just testing CVS, then *you* are the Repository Administrator.
+
+ If you are a normal user of CVS ask your Repository Administrator
+ what module you should check out.
+
+ Then you can work.
+
+ If you *are* the Repository Administrator, you will want to read
+ everything you can get your hands on, including this FAQ. Source
+ control issues can be difficult, especially when you get to
+ branches and release planning. Expect to feel stupid for a few
+ days/weeks.
+
+ No tool in the universe avoids the need for intelligent
+ organization. In other words, there are all sorts of related
+ issues you will probably have to learn. Don't expect to dive in
+ without any preparation, stuff your 300 Megabytes of sources into
+ CVS and expect to start working. If you don't prepare first, you
+ will probably spend a few sleepless nights.
+
+
+ 2A.2 Where do I work?
+
+ Wherever you have disk space. That's one of the advantages of
+ CVS: you use the "checkout" command to copy files from the
+ Repository to your working directory, which can be anywhere you
+ have the space.
+
+ Your local group might have conventions for where to work.
+ Ask your peers.
+
+
+=2A.3 What does CVS use from my environment?
+
+ You must set two environment variables. Some shells share these
+ variables with local shell variables using a different syntax.
+ You'll have to learn how your shell handles them.
+
+ Variable Value (or action)
+ --------- ---------------------
+ CVSROOT Absolute pathname of the head of your Repository.
+
+ PATH Normally set to a list of ':'-separated directory
+ pathnames searched to find executables. You must
+ make sure "cvs" is in one of the directories.
+ If your CVS installation set the RCSBIN directory
+ to null (""), then the RCS commands also must be
+ somewhere in your PATH.
+
+
+ Optional variables: (Used if set, but ignored otherwise.)
+
+ Variable Value (or action)
+ --------- ---------------------
+ CVSEDITOR The name of your favorite fast-start editor
+ program. You'll be kicked into your editor to
+ supply revision comments if you don't specify them
+ via -m "Log message" on the command line.
+ [Note: This is not in 1.3 -- It should appear in
+ the next release.]
+
+ EDITOR Used if CVSEDITOR doesn't exist. If EDITOR
+ doesn't exist, CVS uses a configured constant,
+ usually, "vi".
+
+ CVSREAD Sets files to read-only on "checkout".
+
+ RCSBIN Changes where CVS finds the RCS commands.
+
+ CVSIGNORE Adds to the ignore list. See Section 2D.
+
+
+ Other variables used by CVS that are normally set upon login:
+
+ Variable Value (or action)
+ --------- ---------------------
+ LOGNAME Used to find the real user name.
+
+ USER Used to find the real user name if no LOGNAME.
+
+ HOME Used to determine your home directory, if set.
+ Otherwise LOGNAME/USER/getuid() are used to find
+ your home directory from the passwd file.
+
+
+ 2A.4 OK, I've been told that CVS is set up, my module is named
+ "ralph" and I have to start editing. What do I type?
+
+ cvs checkout ralph
+ cd ralph
+
+ And hack away.
+
+
+ 2A.5 I have been using RCS for a while. Can I convert to CVS without
+ losing my revision history? How about converting from SCCS?
+
+ If you are asking such questions, you are not a mere user of CVS,
+ but one of its Administrators! You should take a look at Section
+ 4A, "Installing CVS" and Section 4B, "Setting up and Managing
+ the Repository".
+
+
+----------------
+-- Section 2B -- Common User Tasks
+----------------
+
+What I consider a "common user task" generally involves combinations
+of the following commands:
+
+ add, checkout, commit, diff, log, status, tag, update
+
+
+Conventions in this section:
+
+ 1. Before each CVS command, you are assumed to have typed a "cd"
+ command to move into a writable working directory.
+
+ 2. All further "cd" commands specified in the examples are assumed
+ to start in the above working directory.
+
+ 3. Unless a point is being made about multiple instances, all modules
+ are named <module>, all tags are named <tag> (branch tags are
+ named <branch_tag>) and all files are named <file>.
+
+ The checkout command will take a relative path name in place
+ of a module name. If you use a relative pathname in place of
+ <module>, you should use the same relative path every place
+ you see <module> in that example.
+
+
+ **** Questions:
+
+#2B.1 What is the absolute minimum I have to do to edit a file?
+=2B.2 If I edit multiple files, must I type "commit" for each one?
+ 2B.3 How do I get rid of the directory that "checkout" created?
+=2B.4 How do I find out what has changed?
+=2B.5 I just created a new file. How do I add it to the Repository?
+=2B.6 How do I merge changes made by others into my working directory?
+ 2B.7 How do I label a set of revisions so I can retrieve them later?
+ 2B.8 How do I checkout an old release of a module, directory or file?
+ 2B.9 What do I have to remember to do periodically?
+
+
+ **** Answers:
+
+
+#2B.1 What is the absolute minimum I have to do to edit a file?
+
+ Tell your Repository Administrator to create a module covering the
+ directory or files you care about. You'll find out that the
+ module name is named <module>. Then type:
+
+ cvs checkout <module>
+ cd <module>
+ emacs <file> # Isn't Emacs a synonym for editor?
+ cvs commit <file>
+
+ If you don't use modules (in my opinion, a mistake), you can check
+ out a directory by substituting its relative path within the
+ Repository for <module> in the example above.
+
+ To check out a single file, you'll have to change the "cd
+ <module>" to "cd to the parent of the file named in <module>".
+
+
+=2B.2 If I edit multiple files, must I type "commit" for each one?
+
+ No. You can do them all at once by name or by directory.
+ See 3D.2.
+
+
+ 2B.3 How do I get rid of the directory that "checkout" created?
+
+ Change your directory to be the same as when you executed the
+ "checkout" command and type:
+
+ cvs release -d <module>
+
+
+ The current version of CVS does not detect foreign directories
+ (i.e. ones that weren't created by CVS) in your working
+ directory and will destroy them.
+
+ If you don't care about keeping "history", and you don't care to
+ plan ahead to a more completely implemented "release" command, you
+ can just remove it. That's "rm -rf <module>" under Unix.
+
+
+=2B.4 How do I find out what has changed?
+
+ There are many ways to answer this.
+
+ To find out what you've changed in your current working directory
+ since your last commit, type:
+
+ cvs diff
+
+ To find out what other people have added (to your branch) since
+ you last checked out or updated, type:
+
+ cvs diff -r BASE -r HEAD
+
+ To look at a revision history containing the comments for all
+ changes, you can use the "log" command.
+
+ You can also use "history" to trace a wide variety of events.
+
+
+=2B.5 I just created a new file. How do I add it to the Repository?
+
+ The "update" command will display files CVS doesn't know about in
+ your working directory marked with a '?' indicator.
+
+ ? <file>
+
+ To add <file> to the Repository, type:
+
+ cvs add <file>
+ cvs commit <file>
+
+
+=2B.6 How do I merge changes made by others into my working directory?
+
+ If you are asking about other branches, see Section 4C on
+ "Branching". You will have to use the "update -j" command.
+
+ Retrieving changes made to the Repository on the *same* branch you
+ are working on is the main purpose of the "update" command. The
+ "update" command tries to merge work committed to the Repository
+ by others since you last executed "checkout", "update" or "commit"
+ into your working files.
+
+ For a single file, there are five possible results when you type
+ the "update" command:
+
+ 1. If neither you nor others have made changes to <file>, "update"
+ will print nothing.
+
+ 2. If you have made no changes to a file, but others have, CVS
+ will replace your working file with a copy of the latest
+ revision of that file in the Repository. You will see:
+
+ U <file>
+
+ You might want to examine the changes (using the CVS "diff"
+ command) to see if they mesh with your own in related files.
+
+ 3. If you have made changes, but others have not, you will see:
+
+ M <file>
+
+ Nothing happened except you were told that you have a modified
+ file in your directory.
+
+ 4. If both you and others have made changes to a file, but in
+ different sections of the file, CVS will merge the changes
+ stored in the Repository since your last "checkout", "update"
+ or "commit" into your working file. You will see:
+
+ RCS file: /Repository/module/<file>
+ retrieving revision 1.X
+ retrieving revision 1.Y
+ Merging differences between 1.X and 1.Y into <file>
+ M <file>
+
+ If you execute "diff" before and after this step, you should
+ see the same output. This is one of the few times the
+ otherwise nonsensical phrase "same difference" means something.
+
+
+ 5. If both you and others have made changes to the same section of
+ a file, CVS will merge the changes into your file as in #4
+ above, but it will leave conflict indicators in the file.
+ You will see:
+
+ RCS file: /Repository/module/<file>
+ retrieving revision 1.X
+ retrieving revision 1.Y
+ Merging differences between 1.X and 1.Y into <file>
+ rcsmerge warning: overlaps during merge
+ cvs update: conflicts found in <file>
+ C <file>
+
+ This is a "conflict". The file will contain strange-looking
+ text marking the overlapping text.
+
+ You must examine the overlaps with care and resolve the
+ problem without removing all previous work.
+
+
+
+ 2B.7 How do I label a set of revisions so I can retrieve them later?
+
+ To "tag" the BASE revisions (the ones you last checked out,
+ updated, or committed) you should "cd" to the head of the working
+ directory you want to tag and type:
+
+ cvs tag <tag>
+
+ It recursively walks through your working directory tagging the
+ BASE revisions of all files.
+
+ To "tag" the latest revision on the Main branch in the
+ Repository, you can use the following from anywhere:
+ (No "cd" is required -- it works directly on the Repository.)
+
+ cvs rtag <tag> <module>
+
+
+ 2B.8 How do I checkout an old release of a module, directory or file?
+
+ Module names and directories are simply ways to name sets of
+ files. Once the names are determined, there are 6 ways to specify
+ which revision of a particular file to check out:
+
+ 1. By tag or symbolic name, via the "-r <tag>" option.
+
+ 2. By date, via the "-D <date>" option.
+
+ 3. By branch tag (a type of tag with a magic format), via the
+ "-r <branch_tag>" option.
+
+ 4. By date within a branch, via the "-r <branch_tag>:<date>"
+ option.
+
+ 5. By an explicit branch revision number, which refers to the
+ latest revision on the branch. This isn't really an "old"
+ revision, from the branch's perspective, but from the user's
+ perspective the branch might have been abandoned in the past.
+
+ 6. An explicit revision number. Though this works, it is almost
+ useless for more than one file.
+
+
+ You type:
+
+ cvs checkout <option-specified-above> <module>
+ cd <module>
+
+
+ 2B.9 What do I have to remember to do periodically?
+
+ You should execute "cvs -n update" fairly often to keep track of
+ what you and others have changed. It won't change anything -- it
+ will just give you a report.
+
+ Unless you are purposely delaying the inclusion of others' work,
+ you should execute "update" once in a while and resolve the
+ conflicts. It is not good to get too far out of sync.
+
+ It is assumed that your system administrators have arranged for
+ editor backup and Unix temp files (#* and .#*) to be deleted after
+ a few weeks. But you might want to look around for anything else
+ that is ignored or hidden. Try "cvs -n update -I !" to see all
+ the ignored files.
+
+ If you are the Repository Administrator, see 4B.17.
+
+
+----------------
+-- Section 2C -- Less Common User Tasks
+----------------
+
+What I consider a "less common user task" generally involves one or
+more of the following commands:
+
+ history, import, export, rdiff, release, remove, rtag
+
+
+ **** Questions:
+
+ 2C.1 Can I create sub-directories in my working directory?
+ 2C.2 How do I add new sub-directories to the Repository?
+ 2C.3 How do I remove a file I don't need?
+=2C.4 How do I rename a file?
+ 2C.5 How do I make sure that all the files and directories in my
+ working directory are really in the Repository?
+=2C.6 How do I create a branch?
+=2C.7 How do I modify the modules file? How about the other files in
+ the CVSROOT administrative area?
++2C.8 How do I split a file into pieces, retaining revision histories?
+
+
+ **** Answers:
+
+
+ 2C.1 Can I create sub-directories in my working directory?
+
+ Yes, but the "update" command will traverse them, wasting a lot
+ of time. You can't currently ignore directories but if a
+ directory has no ./CVS administrative directory, nothing will
+ happen to it during an "update".
+
+ On the other hand "release -d" will delete it without warning.
+
+
+ 2C.2 How do I add new sub-directories to the Repository?
+
+ The "add" command will work on directories. You type:
+
+ mkdir <dir>
+ cvs add <dir>
+
+ It will respond:
+
+ Add directory /Repos/<dir> to the Repository (y/n) [n] ?
+
+ If you type a 'y', you will create both a directory in the
+ Repository and a ./CVS administrative directory within the local
+ <dir> directory.
+
+
+ 2C.3 How do I remove a file I don't need?
+
+ (See the questions in Section 4B on removing files from the
+ Repository.)
+
+ You type:
+
+ rm <file>
+ cvs remove <file>
+
+ CVS registers the file for removal. To complete the removal, you
+ must type:
+
+ cvs commit <file>
+
+ CVS moves the file to the Attic associated with your working
+ directory. Each directory in the Repository stores its deleted
+ files in an Attic sub-directory. A normal "checkout" doesn't
+ look in the Attic, but if you specify a tag, a date or a
+ revision, the "checkout" (or "update") command will retrieve
+ files from the Attic with that tag, date or revision.
+
+
+=2C.4 How do I rename a file?
+
+ CVS does not offer a way to rename a file in a way that CVS can
+ track later. See Section 4B for more information.
+
+ Here is the best way to get the effect of renaming, while
+ preserving the change log:
+
+ 1. Copy the RCS (",v") file directly in the Repository.
+
+ cp $CVSROOT/<odir>/<ofile>,v $CVSROOT/<ndir>/<nfile>,v
+
+ 2. Remove the old file using CVS.
+
+ By duplicating the file, you will preserve the change
+ history and the ability to retrieve earlier revisions of the
+ old file via the "-r <tag/rev>" or "-D <date>" options to
+ "checkout" and "update".
+
+ cd <working-dir>/<odir>
+ rm <ofile>
+ cvs remove <ofile>
+ cvs commit <ofile>
+
+ 3. Retrieve <newfile> and remove all the Tags from it.
+
+ By stripping off all the old Tags, the "checkout -r" and
+ "update -r" commands won't retrieve revisions Tagged before
+ the renaming.
+
+ cd <working-dir>/<ndir>
+ cvs update <nfile>
+ cvs log <nfile> # Save the list of Tags
+ cvs tag -d <tag1> <nfile>
+ cvs tag -d <tag2> <nfile>
+ . . .
+
+
+ This technique can be used to rename files within one directory or
+ across different directories. You can apply this idea to
+ directories too, as long as you apply the above to each file and
+ don't delete the old directory.
+
+ Of course, you have to change the build system (e.g. Makefile) in
+ your <working-dir> to know about the name change.
+
+
+ 2C.5 How do I make sure that all the files and directories in my
+ working directory are really in the Repository?
+
+ Normally, you only need to be notified of files you forgot to
+ "add". A simple "update", or "cvs -n update" (which won't modify
+ your working directory) will display non-added files preceded by a
+ '?' indicator. To recover, "add" and "commit" them.
+
+ To verify that all your directories are in the Repository, you
+ have to go look. Though CVS traverses all directories, it
+ produces no output for directories not backed up by a Repository
+ directory.
+
+ By default many patterns of files are ignored. If you create a
+ file named "core" or a file ending in ".o", it is usually
+ ignored. If you really want to see all the files that aren't in
+ the Repository, you can use a special "ignore" pattern to say
+ "ignore no files". Try executing: (You may have to quote or
+ backwhack (i.e. precede by '\') the '!' in your shell.)
+
+ cvs -n update -I !
+
+ The above command will display not only the normal 'M'odified,
+ 'U'pdate and 'C'onflict indicators on files within the
+ Repository, but it will also display each file not in the
+ Repository preceded by a '?' character.
+
+ The '-n' option will not allow "update" to alter your working
+ directory.
+
+
+=2C.6 How do I create a branch?
+
+ Type this in your working directory:
+
+ cvs tag -b <branch_tag>
+
+ and you will create a branch. No files have real branches in them
+ yet, but if you move onto the branch by typing:
+
+ cvs update -r <branch_tag>
+
+ and commit a file in the normal way:
+
+ cvs commit <file>
+
+ then a branch will be created in the underlying <file>,v file and
+ the new revision of <file> will appear only on that branch.
+
+ See Section 4C, on Branching.
+
+
+=2C.7 How do I modify the modules file? How about the other files in
+ the CVSROOT administrative area?
+
+ A module named "modules" has been provided in the default modules
+ file, so you can type:
+
+ cvs checkout modules
+ cd modules
+
+ Another module named CVSROOT has been provided in the default
+ modules file, covering all the administrative files. Type:
+
+ cvs checkout CVSROOT
+ cd CVSROOT
+
+ Then you can edit your files, followed by:
+
+ cvs commit
+
+ If you use the provided template for the "modules" file, both the
+ CVSROOT and the "modules" module will have the "mkmodules" program
+ as a "commit helper".
+
+ After a file is committed in these modules the "mkmodules"
+ command will convert all the files CVSROOT directory within the
+ Repository into a form that is usable by CVS.
+
+
++2C.8 How do I split a file into pieces, retaining revision histories?
+
+ If you and a coworker find yourselves repeatedly committing the
+ same file, but never for changes in the same area of the file, you
+ might want to split the file into two or more pieces. If you are
+ both changing the same section of code, splitting the file is of
+ no use. You should talk to each other instead.
+
+ If you decide to split the file, here's a suggestion. In many
+ ways, it is similar to multiple "renamings" as described in
+ 2C.4 above.
+
+ Say you want to split <fileA>, which already in the Repository,
+ into three pieces, <fileA>, <fileB> and <fileC>.
+
+ 1. Copy the RCS (",v") files directly in the Repository,
+ creating all the new files.
+
+ cp $CVSROOT/<path>/<fileA>,v $CVSROOT/<path>/<fileB>,v
+ cp $CVSROOT/<path>/<fileA>,v $CVSROOT/<path>/<fileC>,v
+ cvs update <fileB> <fileC>
+
+ 2. Then remove all the <tags> from the new files by using:
+
+ cvs log <fileB> <fileC> # Save the list of <tag?>
+ cvs tag -d <tag1> <fileB> <fileC>
+ cvs tag -d <tag2> <fileB> <fileC>
+ . . .
+
+ 3. Edit and commit all three copies of the same file into three
+ distinct files. This is a hand-editing job, not something
+ CVS can handle. [From experience, I'd suggest making sure
+ that only one copy of each line of code exists among the
+ three files, except for "include" statements, which must be
+ duplicated. And make sure the code compiles.]
+
+ emacs <fileA> <fileB> <fileC>
+ cvs commit <fileA> <fileB> <fileC>
+
+
+ As in the "rename" case, by duplicating the files, you'll preserve
+ the change history and the ability to retrieve earlier revisions.
+
+ Also, as in the "rename" case, you can apply this idea to
+ directories too, by changing <path> to <pathA>, <pathB> and
+ <pathC> in the example.
+
+ Of course, you have to change your build system (e.g. Makefile).
+
+
+
+----------------
+-- Section 2D -- General Questions
+----------------
+
+ **** Questions:
+
+=2D.1 How do I see what CVS is trying to do?
+ 2D.2 If I work with multiple modules, should I check them all out and
+ commit them occasionally? Is it OK to leave modules checked out?
+ 2D.3 What is a "sticky" tag? What makes it sticky? How do I loosen it?
+ 2D.4 How do I get an old revision without updating the "sticky tag"?
+=2D.5 What operations disregard sticky tags?
+=2D.6 Is there a way to avoid reverting my Emacs buffer after
+ committing a file? Is there a "cvs-mode" for Emacs?
+ 2D.7 How does conflict resolution work? What *really* happens if two
+ of us change the same file?
+ 2D.8 How can I tell who has a module checked out?
+#2D.9 Where did the .#<file>.1.3 file in my working directory come from?
+ 2D.10 What is this "ignore" stuff?
+ 2D.11 Why does .cvsignore not ignore directories?
+ 2D.12 Is it safe to interrupt CVS using Control-C?
+ 2D.13 How do I turn off the "admin" command?
+ 2D.14 How do I turn off the ability to disable history via "cvs -l"?
+ 2D.15 How do I keep certain people from accessing certain directories?
+
+
+ **** Answers:
+
+
+=2D.1 How do I see what CVS is trying to do?
+
+ The '-t' option on the main "cvs" command will display every
+ external command (mostly RCS commands and file deletions) it
+ executes. When combined with the '-n' option, which prevents the
+ execution of any command that might modify a file, you can see
+ what it will do before you let it fly. The '-t' option will *not*
+ display every internal action, only calls to external programs.
+
+ To see a harmless example, try typing:
+
+ cvs -nt update
+
+ Some systems offer a "trace" command that will display all system
+ calls as they happen. This is a *very* low-level interface, but
+ it can be useful.
+
+ The most complete answer is to read the source, compile it
+ with the '-g' option and execute it under a debugger.
+
+
+ 2D.2 If I work with multiple modules, should I check them all out and
+ commit them occasionally? Is it OK to leave modules checked out?
+
+ The simple answers are "Yes."
+
+ There is no reason to remove working directories, other than to
+ save disk space. As long as you have committed the files you
+ choose to make public, your working directory is just like any
+ other directory.
+
+ CVS doesn't care whether you leave modules checked out or not.
+ The advantage of leaving them checked out is that you can quickly
+ visit them to make and commit changes.
+
+
+ 2D.3 What is a "sticky" tag? What makes it sticky? How do I loosen it?
+
+ When you execute "update -r <tag>", CVS remembers the <tag>. It
+ has become "sticky" in the sense that until you change it or
+ remove it, the tag is remembered and used in references to the
+ file as if you had typed "-r <tag>" on the command line.
+
+ It is most useful for a <branch_tag>, which is a sticky tag
+ indicating what branch you are working on.
+
+ A revision number ("-r <rev-number>") or date ("-D <date>") can
+ also become sticky when they are specified on the command line.
+
+ A sticky tag, revision or date remains until you specify another
+ tag, revision or date the same way. The "update -A" command
+ moves back to the Main branch, which has the side-effect of
+ clearing all sticky items on the updated files.
+
+ The "checkout" command creates sticky tags, revisions and dates
+ the same way "update" does.
+
+ Also, the '-k' option records a "sticky" keyword option that
+ is used in further "updates until "update -A" is specified.
+
+
+ 2D.4 How do I get an old revision without updating the "sticky tag"?
+
+ Use the '-p' option to "pipe" data to standard output. The
+ command "update -p -r <tag/rev>" sends the selected revision to
+ your standard output (usually the terminal, unless redirected).
+ The '-p' affects no disk files, leaving a "sticky tag" unaltered
+ and avoiding all other side-effects of a normal "update".
+
+ If you want to save the result, you can redirect "stdout" to a
+ file using your shell's redirection capability. In most shells
+ the following command works:
+
+ cvs update -p -r <tag/rev> filename > diskfile
+
+
+=2D.5 What operations disregard sticky tags?
+
+ The functions that routinely disregard sticky tags are:
+
+ 1. Those that work directly on the Repository or its
+ administrative files:
+
+ admin rtag log status remove history
+
+ 2. Those that take Tags or revisions as arguments and ignore
+ everything else: (They also never *set* a sticky tag.)
+
+ rdiff import export
+
+ 3. The "release" command itself ignores sticky tags, but it
+ calls "cvs -n update" (which *does* pay attention to a
+ sticky tag) to figure out what inconsistencies exist in
+ the working directory. If no discrepancies exist between
+ the files you originally checked out (possibly marked by a
+ sticky tag) and what is there now, "release -d" will
+ delete them all.
+
+ 4. The "tag" command, which works on the revision lying in
+ the working directory however it got there. That the
+ revision lying there might happen to have a sticky tag
+ attached to it is not the "tag" command's concern.
+
+
+ The main function that *does* read and write sticky tags is the
+ "update" command. You can avoid referring to or changing the
+ sticky tag by using the '-p' option, which sends files to your
+ terminal, touching nothing else.
+
+ The "checkout" command sets sticky tags when checking out a new
+ module and it acts like "update" when checking out a module into
+ an existing directory.
+
+ The "diff" and "commit" commands use the sticky tags, unless
+ overridden on the command line. They do not set sticky tags. (In
+ the future, "commit" might set a sticky branch tag on a newly
+ added file.) Note that you can only "commit" to a file checked
+ out with a sticky tag, if the tag identifies a branch.
+
+ There are really two types of sticky tags, one attached to
+ individual files (in the ./CVS/Entries file) and one attached to
+ each directory (in the ./CVS/Tag file). They can differ.
+
+ The "add" command doesn't pay attention to anything -- it just
+ registers the desire to add a new file. When a newly added file
+ is `committed", CVS *should* use the "directory tag" to determine
+ what branch to commit it to and set the corresponding sticky tag.
+ Unfortunately, it doesn't work correctly in CVS 1.3. See 4C.8.
+
+
+=2D.6 Is there a way to avoid reverting my Emacs buffer after
+ committing a file? Is there a "cvs-mode" for Emacs?
+
+ See Section 4F.1
+
+
+ 2D.7 How does conflict resolution work? What *really* happens if two
+ of us change the same file?
+
+ While editing files, there is no conflict. You are working on
+ separate virtual branches of development contained in your working
+ directories. When one of you decides to commit the file, the
+ other may not commit the same file until "update" has merged the
+ two together.
+
+ Say you both check out rev 1.2 of <file>. Your coworker commits
+ revision 1.3. When you try to commit your file, CVS says:
+
+ cvs commit: Up-to-date check failed for `<file>'
+
+ You must merge your coworker's changes into your working file by
+ typing:
+
+ cvs update <file>
+
+ which will produce the output described in 2B.6.
+
+ After you resolve any overlaps caused by the merging process, you
+ may then commit the file.
+
+ Yes, the first one who commits can cause the other some work.
+
+ Yes, between the time you execute "update" and "commit", someone
+ else may have committed a later revision of <file>. You will have
+ to execute "update" again to merge the new work before
+ committing. Most organizations don't have this problem. If you
+ do, you might consider splitting the file.
+
+
+ 2D.8 How can I tell who has a module checked out?
+
+ If you "checkout" module names (not relative pathnames) and you
+ use the release command, the "history" command will display who
+ has what checked out. It is advisory only; it can be circumvented
+ by using the '-l' option on the main "cvs" command.
+
+
+#2D.9 Where did the .#<file>.1.3 file in my working directory come from?
+
+ It was created during an "update" when CVS merged changes from the
+ Repository into your modified working file.
+
+ It serves the same purpose as any "backup" file: saving your bacon
+ often enough to be worth retaining. It is invaluable in
+ recovering when things go wrong.
+
+ Say Developers A (you) and B check out rev 1.3 of file <file>.
+ You both make changes -- different changes. B commits first, so
+ <file>,v in the Repository contains revisions up through 1.4.
+
+ At this point, there are 5 (yes, five) versions of the file of
+ interest to you:
+
+ 1. Revision 1.3 (What you originally checked out.)
+ 2. Revision 1.4 (What you need from developer B.)
+ 3. Your old working file. (Before the update.)
+ 4. Your new working file. (After the merge caused by "update".)
+ 5. Revision 1.5 (Which you will commit shortly.)
+
+ In the case where your working file was not modified, #1 and #3
+ will be the same, as will #2 and #4. In this degenerate case,
+ there is no need to create #5. The following assumes that your
+ working file was modified.
+
+ If the merge executed by the "update" caused no overlaps, #4
+ and #5 will be the same. But you might then make changes before
+ committing, so the difference between #4 and #5 might be more
+ than just the correction of overlaps. In general, though, you
+ don't need #4 after a commit.
+
+ But #3 (which is the one saved as ".#<file>.1.3") holds all of
+ your work, independent of B's work. It could represent a major
+ effort that you couldn't afford to lose. If you don't save it
+ somewhere, the merge makes #3 *disappear* under a potential
+ rat's nest of conflicts caused by overlapping changes.
+
+ I have been saved a few times, and others I support have been
+ saved hundreds of times, by the ability to "diff <original file>
+ <original file with only my work added>", which can be done in the
+ example above by the Unix shell command:
+
+ cvs update -p -r 1.3 <file> | diff - .#<file>.1.3
+
+ The assumption is that the ".#" files will be useful far beyond
+ the "commit" point, but not forever. You are expected to run
+ the "normal" Unix cleanup script from "cron", which removes "#*"
+ and ".#*" files older than a some period chosen by your
+ sysadmin, usually ranging from 7 to 30 days.
+
+ A question was raised about the need for #3 after #5 has been
+ committed, under the assumption that you won't commit files until
+ everything is exactly as you like them.
+
+ This assumes perfect humans, which violates one of the Cardinal
+ rules of Software Engineering: Never assume any form of discipline
+ on the part of the users of software. If restrictions are not
+ bound into the software, then you, the toolsmith, have to arrange
+ a recovery path.
+
+ In other words, I've seen every possible variety of screwup you
+ can imagine in #5. There is no way to make assumptions about
+ what "should" happen. I've seen #5 filled with zeros because of
+ NFS failures, I've seen emacs core dumps that leave #5 in an
+ unreasonable state, I've seen a foolish developer uppercase the
+ whole file (with his "undo" size set low so he couldn't undo it)
+ and decide that it would be less work to play with the
+ uppercased file than to blow it away and start over. I've even
+ seen committed files with conflict markers still in them.
+
+ There are all sorts of scenarios where having #3 is incredibly
+ useful. You can move it back into place and try again.
+
+
+ 2D.10 What is this "ignore" stuff?
+
+ The "update" and "import" commands use collections of Unix
+ wildcards to skip over files matching any of those patterns.
+
+ You may add to the built-in ignore list by adding wildcards to
+ the following places: (They are read in this order.)
+
+ 1. In a file named "cvsignore" in $CVSROOT/CVSROOT.
+
+ A Repository Administrator uses this to add site-specific
+ files and patterns to the built-in ignore list.
+
+ 2. In a file named ".cvsignore" in your home directory.
+
+ For user-specific files. For example, if you use "__" as
+ your default junk file prefix, you can put "__*" in your
+ .cvsignore file.
+
+ People who play around in the X tree might want to put
+ "Makefile" in their ignore list, since they are all
+ generated and usually don't end up in the Repository.
+
+ 3. In the CVSIGNORE environment variable.
+
+ For session-specific files.
+
+ 4. Via the '-I' option on "import" or "update" commands.
+
+ For this-command-only files.
+
+ 5. In a file named ".cvsignore" within each directory.
+
+ The contents of a ".cvsignore" file in each directory is
+ temporarily added to the ignore list. This way you can ignore
+ files that are peculiar to that directory, such as executables
+ and other files without known suffix patterns.
+
+ In any of the 5 places listed above, a single '!' character nulls
+ out the ignore list. A Repository administrator can use this to
+ override, rather than enhance, the built-in ignore list. A user
+ can choose to override the system-wide ignore list. For example,
+ if you place "! *.o *.a" in your .cvsignore file, only *.o *.a
+ files, plus any files a local-directory .cvsignore file, are
+ ignored.
+
+
+ 2D.11 Why does .cvsignore not ignore directories?
+
+ Ignore lists are intended to be per-directory wildcards matching
+ various patterns. They are matched against file names, not
+ directory names or relative paths ('/' is an invalid character in
+ an ignore list). I suppose it could be extended, but as it
+ stands, it only works on files.
+
+ This might change in the future.
+
+
+ 2D.12 Is it safe to interrupt CVS using Control-C?
+
+ It depends on what you mean by "safe". ("Ah," said Arthur,
+ "this is obviously some strange usage of the word *safe* that I
+ wasn't previously aware of." -- Hitchhiker's Guide to the Galaxy)
+
+ You won't hurt the underlying RCS files and if you are executing a
+ command that only *reads* data, you will have no cleanup to do.
+
+ But you may have to hit Control-C repeatedly to stop it. CVS uses
+ the Unix "system" routine which blocks signals in the CVS parent
+ process. A single Control-C during "system" will only halt the
+ child process, usually some form of RCS command.
+
+ If you don't hit another Control-C while the CVS process has
+ control, it is likely to continue onto the next task assuming that
+ the earlier one did its job. It is not enough to hit two
+ Control-C's. You might simply kill two child processes and not
+ interrupt CVS at all. Depending on the speed of your processor,
+ your terminal and your fingers, you might have to hit dozens of
+ Control-C's to stop the damn thing.
+
+
+ Executing a CVS command, such as "commit" or "tag" that writes
+ to the files is a different matter.
+
+ Since CVS is not a full-fledged database, with what database
+ people call "commit points", merely stopping the process will
+ not place you back in the starting blocks. CVS has no concept of
+ an "atomic" transaction or of "backtracking", which means that
+ a command can be half-executed.
+
+ First, you will usually leave lock files that you have to go clean
+ up in the Repository.
+
+ Example1:
+
+ If you interrupt a multi-file "commit" in the middle of
+ an RCS checkin, RCS will leave the file either fully
+ checked-in or in its original state. But CVS might have
+ been half-way through the list of files to commit. The
+ directory or module will be inconsistent.
+
+ To recover, you must remove the lock files, then decide
+ whether you want to back out or finish the job.
+
+ To back out, you'll have to apply the "admin -o"
+ command, very carefully, to remove the newly committed
+ revisions. This is usually a bad idea, but is
+ occasionally necessary.
+
+ To finish, you can simply retype the same commit command.
+ CVS will figure out what files are still modified and
+ commit them. It helps that RCS doesn't leave a file in an
+ intermediate state.
+
+
+ Example2:
+
+ If you interrupt a multi-file "tag" command, you have a
+ problem similar, but not equivalent, to interrupting a
+ "commit". The RCS file will still be consistent, but
+ unlike "commit", which only *adds* to the RCS file, "tag"
+ can *move* a tag and it doesn't keep a history of what
+ revision a tag used to be attached to.
+
+ Normally, you have little choice but to re-execute the
+ command and allow it to tag everything consistently.
+
+ You might be able to recover by applying a raw "rcs -n" to
+ the Repository, or by using the equivalent: "cvs admin".
+
+
+ Halting a new "checkout" should cause no harm. If you don't want
+ it, "release" (or rm -rf) it. If you do want it, re-execute the
+ command.
+
+ Halting "update" half-way will give you some strange collection
+ of files and revisions. You'll have to examine the output from
+ the command and take a look at each file that was modified. Good
+ Luck.
+
+
+
+ 2D.13 How do I turn off the "admin" command?
+
+ In the current revision, you'd have to edit the source code.
+
+
+ 2D.14 How do I turn off the ability to disable history via "cvs -l"?
+
+ In the current revision, you'd have to edit the source code.
+
+
+ 2D.15 How do I keep certain people from accessing certain directories?
+
+ If you don't try to run CVS set[ug]id, you can use Unix groups and
+ permissions to limit access to the Repository.
+
+ If you only want to limit "commit" commands, you can write a
+ program to put in the "commitinfo" file. In the "contrib"
+ directory, there is a script called "cvs_acls.pl" that implements
+ a form of access control.
+
+
+========================================
+== Section 3 ==== Commands ====
+========================================
+
+This section contains questions that are easily recognized to be about a
+single command, usually of the form: "Why does the 'xyz' command do this?"
+
+Questions about "missing" features and side-effects not attributable to a
+particular command are in Section 2D, "General Questions".
+
+I won't provide patches here that are longer than a few lines. Patches
+referred to in this section are available in the FTP archive described
+toward the beginning of this document.
+
+
+----------------
+-- Section 3A -- "add", "ad", "new"
+----------------
+
+ **** Questions:
+
+ 3A.1 What is "add" for?
+ 3A.2 How do I add a new file to the branch I'm working on?
+ 3A.3 Why did my newly added file end up in the Attic?
+ 3A.4 How do I put a new file on the Main Branch and branch off from
+ there onto my default branch?
+
+
+ **** Answers:
+
+ 3A.1 What is "add" for?
+
+ To add a new directory to the Repository or to register the
+ desire to add a new file to the Repository.
+
+ The directory is created immediately, after verification, while
+ the desire to add the file is recorded in the local ./CVS
+ administrative directory. To really add the file to the
+ Repository, you must then "commit" it.
+
+
+ 3A.2 How do I add a new file to the branch I'm working on?
+
+ See 4C.8
+
+
+ 3A.3 Why did my newly added file end up in the Attic?
+
+ Your new file is placed in the Attic if it is added onto a side
+ branch without ever showing up on the trunk.
+
+ If the file were in the main Repository area, it would show up
+ when the Main branch is checked out. You didn't commit it onto
+ the Main branch -- only onto the side branch.
+
+
+ 3A.4 How do I put a new file on the Main Branch and branch off from
+ there onto my default branch?
+
+ See 4C.8
+
+
+
+----------------
+-- Section 3B -- "admin", "adm", "rcs"
+----------------
+
+ **** Questions:
+
+ 3B.1 What is "admin" for?
+ 3B.2 Wow! Isn't that dangerous?
+=3B.3 What would I normally use "admin" for?
+=3B.4 What should I avoid when using "admin"?
+-3B.5 How do I restrict the "admin" command? The -i flag in the modules
+ file can restrict commits. What's the equivalent for "admin"?
++3B.6 I backed out a revision with "admin -o" and committed a
+ replacement. Why doesn't "update" retrieve the new revision?
+
+
+ **** Answers:
+
+
+ 3B.1 What is "admin" for?
+
+ To provide direct access to the underlying "rcs" command, which
+ is not documented in this FAQ
+
+
+ 3B.2 Wow! Isn't that dangerous?
+
+ Yes.
+
+ Though you can't hurt the internal structure of an RCS file using
+ its own "rcs" command, you *can* change the underlying RCS
+ files using "admin" in ways that CVS can't handle.
+
+ If you feel the need to use "admin", create some test files
+ with the RCS "ci" command and experiment on them with "rcs"
+ before blasting any CVS files.
+
+
+=3B.3 What would I normally use "admin" for?
+
+ Normally, you wouldn't use admin at all. In unusual
+ circumstances, experts can use it to set up or restore the
+ internal RCS state that CVS requires.
+
+ You can also use the '-o' (for "outdate") option to remove
+ revisions you don't care about. This has its own problems, such
+ as leaving dangling Tags and confusing the "update" command.
+
+
+=3B.4 What should I avoid when using "admin"?
+
+ Never use "admin" to alter branches (using the '-b' option), which
+ CVS takes very seriously. If you change the default branch, CVS
+ will not work as expected. If you create new branches without
+ using the "tag -b" command, you may not be able to treat them as
+ CVS branches.
+
+ Don't try to use the '-l' option, which will lock RCS files.
+ See 4D.7 for a cautionary scenario.
+
+ The "admin -o <file>" allows you to delete revisions, usually a
+ bad idea. You should commit a correction rather than back out a
+ revision. Outdating a revision is prone to all sorts of problems:
+
+ 1. Discarding data is always a bad idea. Unless something in the
+ revision you just committed is a threat to your job or your
+ life, (like naming a function "<boss's name>_is_a_dweeb", or
+ including the combination to the local Mafioso's safe in a C
+ comment), just leave it there. No one cares about simple
+ mistakes -- just commit a corrected revision.
+
+ 2. The time travel paradoxes you can cause by changing history
+ are not worth the trouble. Even if CVS can't interfere with
+ your parents' introduction, it *can* log commits in at least
+ two ways (history and loginfo). The reports now lie -- the
+ revision referred to in the logs no longer exists.
+
+ 3. If you used "import" to place <file> into CVS, outdating all
+ the revisions on the Main branch back to and including revision
+ 1.2 (or worse, 1.1), will produce an invalid CVS file.
+
+ If the <file>,v file only contains revision 1.1 (and the
+ connected branch revision 1.1.1.1), then the default branch
+ must be set to the Vendor branch as it was when you first
+ imported the file. Outdating back through 1.2 doesn't restore
+ the branch setting. Despite the above admonition against it,
+ "admin -b" is the only way to recover:
+
+ cvs admin -b1.1.1 <file>
+
+ 4. Although you can't outdate a physical (RCS) branch point
+ without removing the whole branch, you *can* outdate a revision
+ referred to by a magic branch tag. If you do so, you will
+ invalidate the branch.
+
+ 5. If you "outdate" a tagged revision, you will invalidate all
+ uses of the <tag>, not just the one on <file>. A tag is
+ supposed to be attached to a consistent set of files, usually a
+ set built as a unit. By discarding one of the files in the
+ set, you have destroyed the utility of the <tag>. And it
+ leaves a dangling tag, which points to nothing.
+
+ 6. And even worse, if you commit a revision already tagged, you
+ will alter what the <tag> pointed to without using the "tag"
+ command. For example, if revision 1.3 has <tag> attached to it
+ and you "outdate" the 1.3 revision, <tag> will point to a
+ nonexistent revision. Although this is annoying, it is nowhere
+ near as much trouble as the problem that will occur when you
+ commit to this file again, recreating revision 1.3. The old
+ tag will point to the new revision, a file that was not in
+ existence when the <tag> was applied. And the discrepancy is
+ nearly undetectable.
+
+
+ If you don't understand the above, you should not use the admin
+ command at all.
+
+
+-3B.5 How do I restrict the "admin" command? The -i flag in the modules
+ file can restrict commits. What's the equivalent for "admin"?
+
+ At this writing, to disable the "admin" command, you will have
+ to change the program source code, recompile and reinstall.
+
+
++3B.6 I backed out a revision with "admin -o" and committed a
+ replacement. Why doesn't "update" retrieve the new revision?
+
+ CVS is confused because the revision in the ./CVS/Entries file
+ matches the latest revision in the Repository *and* the timestamp
+ in the ./CVS/Entries file matches your working file. CVS believes
+ that your file is "up-to-date" and doesn't need to be updated.
+
+ You can cause CVS to notice the change by "touch"ing the file.
+ Unfortunately what CVS will tell you is that you have a "Modified"
+ file. If you then "commit" the file, you will bypass the
+ normal CVS check for "up-to-date" and will probably commit the
+ revision that was originally removed by "admin -o".
+
+ Changing a file without changing the revision number confuses CVS
+ no matter whether you did it by replacing the revision (using
+ "admin -o" and "commit" or raw RCS commands) or by applying an
+ editor directly to a Repository (",v") file. Don't do it unless
+ you are absolutely certain no one has the latest revision of the
+ file checked out.
+
+ The best solution to this is to institute a program of deterrent
+ flogging of abusers of "admin -o".
+
+ The "admin" command has other problems." See 3B.4 above.
+
+
+----------------
+-- Section 3C -- "checkout", "co", "get"
+----------------
+
+ **** Questions:
+
+ 3C.1 What is "checkout" for?
+ 3C.2 What is the "module" that "checkout" takes on the command line?
+ 3C.3 Isn't a CVS "checkout" just a bunch of RCS checkouts?
+ 3C.4 What's the difference between "update" and "checkout"?
+ 3C.5 Why can't I check out a file from within my working directory?
+ 3C.6 How do I avoid dealing with those long relative pathnames?
+ 3C.7 Can I move a checked-out directory? Does CVS remember where it
+ was checked out?
+#3C.8 How can I lock files on checkout the way RCS does?
++3C.9 What is "checkout -s"? How is it different from "checkout -c"?
+
+
+ **** Answers:
+
+ 3C.1 What is "checkout" for?
+
+ To acquire a copy of a module (or set of files) to work on.
+
+ All work on files controlled by CVS starts with a "checkout".
+
+
+ 3C.2 What is the "module" that "checkout" takes on the command line?
+
+ It is a name for a directory or a collection of files in the
+ Repository. It provides a compact name space and the ability to
+ execute before and after helper functions based on definitions in
+ the modules file.
+
+ See 1D.11.
+
+
+ 3C.3 Isn't a CVS "checkout" just a bunch of RCS checkouts?
+
+ Like much of CVS, a similar RCS concept is used to support a CVS
+ function. But a CVS checkout is *not* the same as an RCS
+ checkout.
+
+ Differences include:
+
+ 1. CVS does not lock the files. Others may access them at the
+ same time.
+
+ 2. CVS works best when you provide a name for a collection of
+ files (a module or a directory) rather than an explicit list of
+ files to work on.
+
+ 3. CVS remembers what revisions you checked out and what branch
+ you are on, simplifying later commands.
+
+
+
+ 3C.4 What's the difference between "update" and "checkout"?
+
+ The "checkout" and "update" differ in the following ways:
+
+ 1. The "checkout" command always creates a directory, moves into
+ it, then becomes equivalent to "update -d".
+
+ 2. The "update" does not create directories unless you add the
+ '-d' option.
+
+ 3. "Update" is intended to be executed within a working directory
+ created by "checkout". It doesn't take a "module" or
+ "directory" argument, but figures out what Repository files to
+ look at by reading the ./CVS administrative directory.
+
+ 4. The two commands generate completely different types of records
+ in the "history" file.
+
+ The two commands are equivalent in nearly all other respects.
+
+
+ 3C.5 Why can't I check out a file from within my working directory?
+
+ You normally check out a module or directory, not a file. And you
+ normally do it only once at the beginning of a project.
+
+ After the initial "checkout", you can use the "update" command
+ to retrieve any file you want within the checked-out directory.
+ There is no need for further "checkout" commands.
+
+ If you want to retrieve another module or directory to work on,
+ you must provide names for both where to find it in the Repository
+ and where to put it on disk. The "modules" file and your
+ current directory supply two pieces of naming information. While
+ inside a checked-out working directory, the CVS administrative
+ information provides most of the rest.
+
+ You should be careful not to confuse CVS with RCS and use
+ "checkout" in the RCS sense. An RCS "checkout" (which is
+ performed by the RCS "co" command) is closer to a "cvs update"
+ than to a "cvs checkout".
+
+
+ 3C.6 How do I avoid dealing with those long relative pathnames?
+
+ This question has also been phrased:
+
+ How do I avoid all those layers of directories on checkout?
+ or
+ Why do I have to go to the top of my working directory and
+ checkout some long pathname to get a file or two?
+
+
+ This type of question occurs only among groups of people who
+ decide not to use "modules". The answer is to use "module".
+
+ When you hand the "checkout" command a relative pathname, rather
+ than a module name, all directories in the path are created,
+ maintaining the same directory hierarchy as in the Repository.
+ The same kind of environment results if you specify a "module"
+ that is really an alias expanding into a list of relative
+ pathnames rather than a list of module names.
+
+ If you use "module" names, "checkout" creates a single
+ directory by the name of the module in your current directory.
+ This "module" directory becomes your working directory.
+
+ The "module" concept combines the ability to "name" a collection
+ of files with the ability to structure the Repository so that
+ consistent sets of files are checked out together. It is the
+ responsibility of the Repository Administrators to set up a
+ modules file that describes the software within the Repository.
+
+ I consider it unfortunate that CVS sprouted the ability to check
+ out relative pathnames without more extensive and flexible
+ support for "modules."
+
+
+ 3C.7 Can I move a checked-out directory? Does CVS remember where it
+ was checked out?
+
+ Yes and Yes.
+
+ The ./CVS/Repository file in each working directory contains a
+ pathname pointing to the matching directory within the
+ Repository. The pathname is either absolute or relative to
+ $CVSROOT, depending on how you configured CVS.
+
+ When you move a checked-out directory, the CVS administrative
+ files will move along with it. As long as you don't move the
+ Repository itself, or alter your $CVSROOT variable, the moved
+ directory will continue to be usable.
+
+ CVS remembers where you checked out the directory in the
+ "history" file, which can be edited, or even ignored if you
+ don't use the "working directory" information displayed by the
+ "history" command.
+
+
+#3C.8 How can I lock files on checkout the way RCS does?
+
+ Think about why you want that ability. RCS locking is there to
+ keep people from breaking individual files. CVS does the same
+ task a different way. If you are only looking for the consistency
+ aspect, then you should just forget about locking. For normal
+ development, there is no need for CVS to lock anything.
+
+ If you want to restrict access to parts of the Repository, see
+ the question in Section 4B on "Limiting Access".
+
+
++3C.9 What is "checkout -s"? How is it different from "checkout -c"?
+
+ The '-c' and '-s' options to "checkout" both cause the modules
+ file to appear on standard output, but formatted differently.
+
+ "checkout -c" lists the modules file alphabetized by the module
+ name. It also prints all data (including options like '-a' and
+ "-o <prog>") specified in the modules file.
+
+ "checkout -s" lists the modules file sorted by "status" field,
+ then by module name. The status field was intended to allow you
+ to mark modules with strings of your choice to get a quick sorted
+ report based on the data you chose to put in the status fields. I
+ have used it for priority ("Showstopper", etc as tied into a bug
+ database), for porting status ("Ported", "Compiled", etc. when
+ porting a large collection of modules), for "assignee" (the person
+ responsible for maintenance), and for "test suite" (which
+ automatic test procedure to run for a particular module).
+
+ [[CVS 1.3 fails to handle all the flags you can put into the
+ modules file. The '-l' switch in particular causes "checkout -c"
+ to dump core on some systems.]]
+
+
+----------------
+-- Section 3D -- "commit", "ci", "com"
+----------------
+
+ **** Questions:
+
+ 3D.1 What is "commit" for?
+=3D.2 If I edit ten files, do I have to type "commit" ten times?
+ 3D.3 Explain: cvs commit: Up-to-date check failed for `<file>'
+ 3D.4 What happens if two people try to "commit" conflicting changes?
+ 3D.5 I committed something and I don't like it. How do I remove it?
+=3D.6 Explain: cvs commit: sticky tag `V3' for file `X' is not a branch
+=3D.7 Why does "commit -r <branch_tag>" put new files in the attic?
++3D.8 Why does "commit -r <rev>" ignore <rev> on an added file?
+
+
+ **** Answers:
+
+ 3D.1 What is "commit" for?
+
+ To store new revisions in the Repository, making them visible
+ to other users.
+
+
+=3D.2 If I edit ten files, do I have to type "commit" ten times?
+
+ No. The "commit" command will take multiple filenames on the
+ command line and commit them all with the same log message.
+ If the file is unchanged, CVS will skip it.
+
+ Like all CVS commands, "commit" will work on the whole directory
+ by default. Just type "cvs commit" to tell CVS to commit all
+ modified files (i.e. the files that "update" would display
+ preceded by 'M') in the current directory and in all
+ sub-directories.
+
+
+ 3D.3 Explain: cvs commit: Up-to-date check failed for `<file>'
+
+ You may not "commit" a file if your BASE revision (i.e. the
+ revision you last checked out, committed or retrieved via
+ "update") doesn't match the HEAD revision (i.e the latest revision
+ on your branch, usually the Main Branch).
+
+ In other words, someone committed a revision since you last
+ executed "checkout", "update" or "commit". You must now execute
+ "update" to merge the other person's changes into your working
+ file before "commit" will work. You are thus protected (somewhat)
+ from a common form of race condition in source control systems,
+ where a second checkin of minor changes from the same base file
+ obliterates the changes made in the first.
+
+ Normally, the "update" command's auto-merge should be followed
+ by another round of building and testing before the "commit".
+
+
+ 3D.4 What happens if two people try to "commit" conflicting changes?
+
+ Conflicts can occur only when two developers check out the same
+ revision of the same file and make changes. The first developer
+ to commit the file has no chance of seeing the conflict. Only the
+ second developer runs into it, usually when faced with the
+ "Up-to-date" error explained in the previous question.
+
+ There are two types of conflicts:
+
+ 1. When two developers make changes to the same section of code,
+ the auto-merge caused by "update" will print a 'C' on your
+ terminal and leave "overlap" markers in the file.
+
+ You are expected to examine and clean them up before committing
+ the file. (That may be obvious to *some* of you, but . . .)
+
+ 2. A more difficult problem arises when two developers change
+ different sections of code, but make calls to, or somehow
+ depend on, the old version of each other's code.
+
+ The auto-merge does the "right" thing, if you view the file
+ as a series of text lines. But as a program, the two
+ developers have created a problem for themselves.
+
+ This is no different from making cross-referential changes in
+ *separate* files. CVS can't help you. In a perfect world, you
+ would each refer to the specification and resolve it
+ independently. In the real world you have to talk/argue, read
+ code, test and debug until the combined changes work again.
+
+ Welcome to simultaneous development.
+
+
+ 3D.5 I committed something and I don't like it. How do I remove it?
+
+ Though you *can* use the "admin -o" (synonym: "rcs -o") command to
+ delete revisions, unless the file you committed is so embarrassing
+ that the need to eradicate it overrides the need for being
+ careful, you should just grab an old version of the file ("update
+ -p -r <previous-rev>" might help here) and commit it on top of the
+ offending revision.
+
+ See Section 3B on "admin".
+
+
+=3D.6 Explain: cvs commit: sticky tag `V3' for file `X' is not a branch
+
+ The message implies two things:
+
+ 1. You created your working directory by using "checkout -r
+ V3", or you recently executed "update -r V3".
+
+ 2. The tag named V3 is not a branch tag.
+
+
+ CVS remembers any "-r <tag/rev>" arguments handed to the
+ "checkout" or "update" commands. This is the "sticky" part. The
+ <tag/rev> is recorded as the CVS working branch, which is the
+ branch to which "commit" will add a new revision.
+
+ Branch tags are created when you use the -b switch on the "tag" or
+ "rtag" commands. Branch tags are magic tags that don't create a
+ physical branch, but merely mark the revision to branch from when
+ the branch is needed. The first commit to a magic branch creates
+ a physical branch in the RCS files.
+
+ You can commit onto the end of the Main Trunk, if you have no
+ sticky tag at all, or onto the end of a branch, if you have a
+ sticky branch tag. But you can't commit a file that has a sticky
+ tag not pointing to a branch. CVS assumes a sticky Tag or
+ Revision that does not refer to a branch is attached to the middle
+ of a series of revisions. You can't squeeze a new revision
+ between two others. Sticky dates also block commits since they
+ never refer to a branch.
+
+
+ Scenario1:
+
+ If you don't want a branch and were just looking at an old
+ revision, then you can move back to the Main Branch by typing:
+
+ cvs update -A {optional files, default is whole directory}
+
+
+ Scenario2:
+
+ If you really wanted to be on a branch and made an earlier
+ mistake by tagging your branch point with a non-branch tag,
+ you can recover by adding a new branch tag to the old
+ non-branch tag:
+
+ cvs rtag -b -r <oldtag> <newtag> <module>
+
+ (It was not a big mistake. Branch-point tags can be useful.
+ But the <newtag> must have a different name.)
+
+ If you don't know the <module> name or don't use "modules",
+ you can also use "tag" this way:
+
+ cvs update -r <oldtag>
+ cvs tag -b <newtag> .
+
+ Then, to put your working directory onto the branch, you type:
+
+ cvs update -r <newtag>
+
+
+ You can't delete <oldtag> before adding <newtag>, and I would
+ not advise deleting the <oldtag> at all, because it is useful
+ in referring to the branch point. If you must, you can delete
+ the non-branch tag by:
+
+ cvs rtag -d <oldtag> <module>
+ or
+ cvs tag -d <oldtag> .
+
+
+ Scenario3:
+
+ If you made the same mistake as in Scenario2, but really want
+ <oldtag> to be the name of your branch, you can execute a
+ slightly different series of commands to rename it and move
+ your working directory onto the branch:
+
+ cvs rtag -r <oldtag> <branch_point_tag> <module>
+ cvs rtag -d <oldtag> <module>
+ cvs rtag -b -r <branch_point_tag> <oldtag> <module>
+
+ Then, if you really must, delete the <branch_point_tag>:
+
+ cvs rtag -d <branch_point_tag> <module>
+
+
+ Note: The unwieldy mixture of "tag" and "rtag" is mostly
+ because you can't specify a revision (-r <tag>) to the
+ "tag" command.
+
+ See 4C.3 for more details.
+
+
+=3D.7 Why does "commit -r <branch_tag>" put new files in the attic?
+
+ This was a design choice. The Attic is a way to keep track of
+ files that are no longer on the Main Branch, or ones that were
+ *never* on the Main Branch.
+
+ If the file doesn't already exist on the Main branch, committing
+ it directly to the BRANCH will stuff it into the Attic. Such
+ files are skipped over when checking out the Main Branch because
+ the file isn't on that branch.
+
+ If it didn't go into the Attic, you would be committing the new
+ file to the Main branch in addition to the Branch you are working
+ on. This is an undesirable side-effect.
+
+ The file can be retrieved by using the "-r <branch_tag>" option on
+ a "checkout" or "update" command.
+
+ See Section 4C, on Branching, for many more details.
+
+
++3D.8 Why does "commit -r <rev>" ignore <rev> on an added file?
+
+ The sequence
+
+ cvs add <file>
+ cvs commit -r <rev> <file>
+
+ does not commit the new file <file> with revision <rev> as you
+ might expect. For newly added files (for which "update" would
+ display an 'A') the '-r' option is assumed to be a branch tag. If
+ <rev> is numeric, it is ignored. This might or might not be
+ changed in future revisions of CVS, but for now, the following
+ commands will allow you to set the revision of the file: (with
+ some restrictions)
+
+ cvs add <file>
+ cvs commit <file>
+ cvs commit -r <rev> <file>
+
+ The first commit causes CVS to look for the highest main branch
+ major number in all files in the directory. Normally it is '1',
+ but if you have a file of revision 3.27 in your directory, CVS
+ will find the '3' and create revision 3.1 for the first rev of
+ <file>. Normally, the first revision is 1.1.
+
+ As long as <rev> is higher than the initial (calculated as in the
+ above) revision, the second commit will work as expected and force
+ a second commit even if the file hasn't changed, setting the file
+ revision to <rev>.
+
+
+----------------
+-- Section 3E -- "diff", "di", "dif"
+----------------
+
+ **** Questions:
+
+ 3E.1 What is "diff" for?
+=3E.2 Why did "diff" display nothing when I know there are later
+ committed revisions in the Repository?
+#3E.3 How do I display what changed in the Repository since I last
+ executed "checkout", "update" or "commit"?
+=3E.4 How do I display the difference between my working file and what
+ I checked in last Thursday?
+=3E.5 Why can't I pass the --unified option to "diff"?
+
+
+ **** Answers:
+
+ 3E.1 What is "diff" for?
+
+ To display the difference between your working file and a
+ committed revision:
+
+ cvs diff -r <tag/rev> <file>
+
+ or between two committed revisions:
+
+ cvs diff -r <tag1/rev1> -r <tag2/rev2> <file>
+
+ Without explicit file names, it "diffs" the whole directory.
+
+ Without explicit revision numbers, it "diffs" your working file
+ against the BASE revision, which is the one last checked out,
+ updated or committed.
+
+ In the examples above, "-D <date>" may be substituted wherever
+ "-r <tag/rev>" appears. The revision a <date> refers to is the
+ revision that existed on that date.
+
+
+=3E.2 Why did "diff" display nothing when I know there are later
+ committed revisions in the Repository?
+
+ By default, "diff" displays the difference between your working
+ file and the BASE revision. If you haven't made any changes to
+ the file since your last "checkout", "update" or "commit" there is
+ no difference to display.
+
+ To display the difference between your working file and the latest
+ revision committed to your current branch, type:
+
+ cvs diff -r HEAD <file>
+
+
+#3E.3 How do I display what changed in the Repository since I last
+ executed "checkout", "update" or "commit"?
+
+ A special tag (interpreted by CVS -- it does not appear in the Tag
+ list) named "BASE" always refers to the revision you last checked
+ out, updated or committed. Another special tag named "HEAD"
+ always refers to the latest revision on your working branch.
+
+ To compare BASE and HEAD, you type:
+
+ cvs diff -r BASE -r HEAD <file>
+
+
+=3E.4 How do I display the difference between my working file and what
+ I checked in last Thursday?
+
+ cvs diff -D "last Thursday" <file>
+
+ where "last Thursday" is a date string. To be more precise, the
+ argument to the '-D' option is a timestamp. Many formats are
+ accepted. See the man page under "-D date_spec" for details.
+
+
+=3E.5 Why can't I pass the --unified option to "diff"?
+
+ There are a few reasons:
+
+ 1. CVS passes through only arguments it knows about, because a few
+ arguments are captured and interpreted.
+
+ 2. CVS only parses single character '-X' arguments, not the FSF
+ long options.
+
+ 3. If you didn't configure RCS and CVS to use the GNU version of
+ diff, long options wouldn't work even if future versions of CVS
+ acquire the ability to pass them through.
+
+
+ Most of the long options have equivalent single-character options,
+ which do work. The "--unified" option is equivalent to '-u' in
+ revisions of GNU diff since 1.15.
+
+
+
+----------------
+-- Section 3F -- "export", "exp", "ex"
+----------------
+
+ **** Questions:
+
+ 3F.1 What is "export" for?
+=3F.2 Why does it remove the RCS keywords so I can't use the "ident"
+ command on the source files?
+=3F.3 Can I override the '-kv' flag CVS passes to RCS?
+=3F.4 Why the hell not?
+ 3F.5 Why does "export -D" check out every file in the Attic?
+
+
+ **** Answers:
+
+ 3F.1 What is "export" for?
+
+ "export" checks out a copy of a module in a form intended for
+ export outside the CVS environment. The "export" command produces
+ the same directory and file structure as the "checkout" command,
+ but it doesn't create "CVS" sub-directories and it removes all the
+ RCS keywords from the files.
+
+
+=3F.2 Why does it remove the RCS keywords so I can't use the "ident"
+ command on the source files?
+
+ It removes the RCS keywords, so that if the recipient of the
+ exported sources checks them into another set of RCS files (with
+ or without CVS), and then makes modifications through RCS or CVS
+ commands, the revision numbers that they had when you exported
+ them will be preserved. (That ident no longer works is just an
+ unfortunate side effect.)
+
+ The theory is that you are exporting the sources to someone else
+ who will make independent changes, and at some point you or they
+ will want to know what revisions from your Repository they started
+ with (probably to merge changes, or to try to decide whether to
+ merge changes).
+
+ A better way to handle this situation would be to give them their
+ own branch of your Repository. They would need to remember to
+ checkin the exported sources with RCS IDs intact (ci -k) so that
+ their changes would get revision numbers from the branch, rather
+ than starting at 1.1 again. Perhaps a future version of CVS will
+ provide a way to export sources this way.
+
+ Contributed by Dan Franklin
+
+
+=3F.3 Can I override the '-kv' flag CVS passes to RCS?
+
+ Not in CVS 1.3. Maybe later.
+
+
+=3F.4 Why the hell not?
+
+ Export is intended for a specific purpose -- to remove all trace
+ of revision control on the way *out* of CVS. Maybe in the future
+ CVS will allow the -kv default to be overridden.
+
+
+ 3F.5 Why does "export -D" check out every file in the Attic?
+
+ See the explanation of the same problem with "update -D"
+ contained in section 5B.
+
+
+
+----------------
+-- Section 3G -- "history", "hi", "his"
+----------------
+
+ **** Questions:
+
+ 3G.1 What is "history" for?
+ 3G.2 Of what use is it?
+ 3G.3 What is this, Big Brother?
+ 3G.4 I deleted my working directory and "history" still says I have
+ it checked out. How do I fix it?
+ 3G.5 So I *can* edit the History file?
+ 3G.6 Why does the history file grow so quickly?
+ 3G.7 What is the difference between "cvs history -r <tag/rev>" and
+ "cvs history -t <tag>"?
+ 3G.8 Why does "cvs history -c -t <tag>" fail to print anything?
+ 3G.9 "cvs history -a -o" only printed one line for each checked-out
+ module. Shouldn't it print all the directories where the
+ modules are checked out?
+=3G.10 I can't figure out "history", can you give me concrete examples?
+
+
+ **** Answers:
+
+ 3G.1 What is "history" for?
+
+ To provide information difficult or impossible to extract out of
+ the RCS files, such as a "tag" history or a summary of module
+ activities.
+
+
+ 3G.2 Of what use is it?
+
+ I have found it useful in a number of ways, including:
+
+ 1. Providing a list of files changed since
+
+ - A tagged release.
+ - Yesterday, last Thursday, or a specific date.
+ - Someone changed a specific file.
+
+ 2. Providing a list of special events:
+
+ - Files added or removed since one of the above events.
+ - Merge failures since one of the above events. (Where did the
+ conflicts occur?)
+ - Has anyone (and who) grabbed the revision of this file I
+ committed last week, or are they still working blind?
+
+ 3. Telling me how often a file/directory/module has been changed.
+
+ 4. Dumping a summary of work done on a particular module,
+ including who last worked on it and what changed.
+
+ 5. Displaying the checked-out modules and where they are being
+ worked on.
+
+ 6. To tell me what users "joe" and "malcolm" have done this week.
+
+
+ 3G.3 What is this, Big Brother?
+
+ War is Peace.
+ Freedom is Slavery.
+ Ignorance is Strength.
+
+ Normally manager types and those with the power to play Big
+ Brother don't care about this information. The Software Engineer
+ responsible for integration usually wants to know who is working
+ on what and what changed. Use your imagination.
+
+
+ 3G.4 I deleted my working directory and "history" still says I have
+ it checked out. How do I fix it?
+
+ In later versions of CVS, you can use the '-f' option which
+ forcibly adds a "release" record to the history file. If your
+ version of "release" doesn't have the '-f' option, you have
+ to edit the $CVSROOT/CVSROOT/history file.
+
+ You can remove the last 'O' line in the history file referring
+ to the module in question or add an 'F' record.
+
+
+ 3G.5 So I *can* edit the History file?
+
+ Yes, but if you are using history at all, you should take a little
+ care not to lose information. I normally use Emacs on the file,
+ since it can detect that a file has changed out from under it.
+ You could also copy and zero out the history file, edit the copy
+ and append any new records to the edited copy before replacing it.
+
+
+ 3G.6 Why does the history file grow so quickly?
+
+ It stores 'U' records, which come in handy sometimes when you
+ are tracking whether people have updated each other's code
+ before testing. There should (and probably will sometime) be a
+ way to choose what kinds of events go into the history file.
+
+ The contributed "cln_hist.pl" script will remove all the 'U'
+ records, plus matching pairs of 'O' and 'F' records during
+ your normal clean up of the history file.
+
+
+ 3G.7 What is the difference between "cvs history -r <tag/rev>" and
+ "cvs history -t <tag>"?
+
+ The '-t' option looks for a Tag record stored by "rtag" in the
+ history file and limits the search to dates after the last <tag>
+ of the given name was added.
+
+ The '-r' option was intended to search all files looking for the
+ <tag> in the RCS files. It takes forever and needs to be
+ rewritten.
+
+
+ 3G.8 Why does "cvs history -c -t <tag>" fail to print anything?
+
+ You have been using "tag" instead of "rtag". The "tag" command
+ currently doesn't store a history record. This is another remnant
+ of CVS's earlier firm belief in "modules".
+
+
+ 3G.9 "cvs history -a -o" only printed one line for each checked-out
+ module. Shouldn't it print all the directories where the
+ modules are checked out?
+
+ Not as designed.
+
+ Command Question it is supposed to answer.
+ ---------------- ------------------------------------------
+ cvs history -o What modules do I have checked out?
+ cvs history -a -o <same for all users>
+
+ cvs history -o -w What working directories have I created
+ and what modules are in them?
+ cvs history -a -o -w <same for every user>
+
+ The -o option chooses the "checked out modules" report, which is
+ the default history report.
+
+
+=3G.10 I can't figure out "history", can you give me concrete examples?
+
+ Default output selects records only for the user who executes the
+ "history" command. To see records for other users, add one or
+ more "-u user" options or the '-a' option to select *all* users.
+
+ To list (for the selected users): Type "cvs history" and:
+
+ * Checked out modules: -o (the default)
+ * Files added since creation: -x A
+ * Modified files since creation: -c
+ * Modified files since last Friday: -c -D 'last Friday'
+ * Modified files since TAG was added: -c -t <tag>
+ * Modified files since TAG on files: -c -r <tag>
+ * Last modifier of file/Repository X? -c -l -[fp] X
+ * Modified files since string "str": -c -b str
+ * Tag history: (Actually "rtag".) -T
+ * History of file/Repository/module X: -[fpn] X
+ * Module report on "module": -m module
+
+
+----------------
+-- Section 3H -- "import", "im", "imp"
+----------------
+
+ **** Questions:
+
+=3H.1 What is "import" for?
+=3H.2 How am I supposed to use "import"?
+=3H.3 Why does import put files on a branch? Why can't you put it on
+ the Main Trunk and let me work on a branch?
+ 3H.4 Is there any way to import binary files?
+=3H.5 Why does "import" corrupt some binary files?
+ 3H.6 How do I keep "import" from expanding all the $\Revision$ strings
+ to be 1.1.1.1?
+#3H.7 I imported some files for the Yarg compiler that compiles files
+ with a suffix of ".yarg" and whose comment prefix is "YARG> ".
+ When I check them out, they will no longer compile because they
+ have this junk in them. Why?
+ 3H.8 How do I make "import" save the timestamps on the original files?
+ 3H.9 Why didn't "import" ignore the directories I told it to?
+ 3H.10 Why can't I "import" 3 releases on different branches?
+ 3H.11 What do I do if the Vendor adds or deletes files between releases?
+ 3H.12 What about if the Vendor changes the names of files or
+ directories, or rearranges the whole structure between releases?
+ 3H.13 I thought "import" was for Vendor releases, why would I use it
+ for code of my own? Do I have to use import?
+=3H.14 How do I import a large Vendor release?
++3H.15 Explain: ERROR: cannot create link to <file>: Permission denied
+
+
+ **** Answers:
+
+=3H.1 What is "import" for?
+
+ The "import" command is a fast way to insert a whole tree of files
+ into CVS.
+
+ The first "import" to a particular file within the Repository
+ creates an RCS file with a single revision on the "Vendor branch."
+ Subsequent "import"s of the same file within the Repository append
+ a new revision onto the Vendor branch. It does not, as some seem
+ to believe, create a new branch for each "import". All "imports"
+ are appended to the single Vendor branch.
+
+ If the file hasn't changed, no new revision is created -- the new
+ "Release-Tag" is added to the previous revision.
+
+ After the import is finished, files you have not changed locally
+ are considered to have changed in the "Main line of development".
+ Files you *have* changed locally must have the new Vendor code
+ merged into them before they are visible on the "Main line".
+
+ See 4C.6 and 4C.15
+
+
+=3H.2 How am I supposed to use "import"?
+
+ Create a source directory containing only the files you want to
+ import. Make sure you clean up any cruft left over from previous
+ builds or editing. You want to make sure that the directory
+ contains only what you want to call "source" from which everything
+ else is built.
+
+ "cd" into your source directory and type:
+
+ cvs import -m "Message" <repos> <Vendor-Tag> <Release-Tag>
+
+
+ where <repos> is a relative directory pathname within the
+ Repository.
+
+ For example, if the FSF, CVS, Make and I are still active in the
+ year 2015, I'll import version 89.53 of GNU make this way:
+
+ cvs import -m "GNUmake V89.53" gnu/make GNU GNUMAKE_89_53
+
+ See 3H.14 for more details.
+
+
+=3H.3 Why does import put files on a branch? Why can't you put it on
+ the Main Trunk and let me work on a branch?
+
+ Design choice. If you don't like the Vendor branch, you can use
+ the RCS "ci" command to generate all the RCS (",v") files and move
+ them into the Repository directly.
+
+ Note that the CVS "Main Branch" and the RCS Main Trunk are not the
+ same. Placing files on the Vendor Branch doesn't keep you from
+ creating a development branch to work on.
+
+ See Section 4C, on Branching.
+
+
+ 3H.4 Is there any way to import binary files?
+
+ See 4D.1 on Binary files.
+
+
+=3H.5 Why does "import" corrupt some binary files?
+
+ The RCS "co" command, when it is invoked by a CVS "checkout" or
+ "update" (or after a "commit") command, searches for and expands a
+ list of keywords within the file. They are documented in the RCS
+ "co" man page. Strings such as "$\Id$" (or "$\Id:"), or
+ "$\Revision$" (or "$\Revision:") are altered to the include the
+ indicated information.
+
+ [[Note: The keywords should appear in the text without the '\'
+ character I have inserted to *avoid* expansion here. The only
+ real RCS keywords in this document are at the top of the file,
+ where I store the Revision and Date.]]
+
+ If RCS keyword strings show up in a binary file, they will be
+ altered unless you set the '-ko' option on the RCS files to tell
+ RCS to keep the original keyword values and not to expand new
+ ones. After "import", you can set the '-ko' option this way:
+
+ cvs admin -ko <file>
+ rm <file>
+ cvs update <file>
+
+ See 4D.1 on Binary files.
+
+
+ 3H.6 How do I keep "import" from expanding all the $\Revision$ strings
+ to be 1.1.1.1?
+
+ If you want to leave old RCS keywords as they are, you can use the
+ '-ko' trick described above. In the future, "import" might
+ sprout a '-ko' option of its own, so you don't have to execute two
+ commands.
+
+
+#3H.7 I imported some files for the Yarg compiler that compiles files
+ with a suffix of ".yarg" and whose comment prefix is "YARG> ".
+ When I check them out, they will no longer compile because they
+ have this junk in them. Why?
+
+ YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>
+ YARG> $\Log:
+ # Revision 1.3 1998/03/03 00:16:16 bubba
+ # What is 2+2 anyway?
+ #
+ # Revision 1.2 1998/03/03 00:15:15 bubba
+ # Added scorekeeping.
+ YARG>
+ YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>
+
+
+ Well bubba, "Yarg" hasn't hit the big time yet. Neither RCS nor
+ CVS know about your suffix or your comment prefix. So you have
+ two choices:
+
+ 1. Check out the Yarg-less module, and tell all the files about
+ your comment prefix. Visit each directory and type:
+
+ cvs admin -c"YARG> " *.yarg
+
+ If *all* files in the whole directory tree are Yarg files,
+ you can use this instead:
+
+ cvs admin -c"YARG> " .
+
+ Then save any changes you made, remove all the "*.yarg" files
+ and grab new copies from the Repository:
+
+ rm *.yarg (or: find . -name '*.yarg' -exec rm {} ';')
+ cvs update
+
+ It might be faster to remove the whole directory and check it
+ out again.
+
+ 2. Change the import.c file in the CVS sources and add the .yarg
+ suffix, along with the "YARG> " comment prefix to the
+ "comtable" array.
+
+ If you ever plan to add new files with $\Log in them, you
+ should also go into the RCS sources and make the same change in
+ the table contained in the "rcsfnms.c" file.
+
+ Then delete the imported files from the Repository and
+ re-"import" the sources.
+
+
+ 3H.8 How do I make "import" save the timestamps on the original files?
+
+ In the released CVS 1.3, there is no way. In the coming patch
+ release, there will supposedly be a '-d' option to save the dates
+ of the files rather than the current date.
+
+ See 4D.8 for more details.
+
+
+ 3H.9 Why didn't "import" ignore the directories I told it to?
+
+ See 2D.11.
+
+
+ 3H.10 Why can't I "import" 3 releases on different branches?
+
+ I'll bet you typed something like this:
+
+ cd /src/blasto.v2
+ cvs import -b 1.1.2 VENDOR2 Version2
+ cd /src/blasto.v3
+ cvs import -b 1.1.3 VENDOR3 Version3
+ cd /src/blasto.v4
+ cvs import -b 1.1.4 VENDOR4 Version4
+
+ This is wrong, or at least it won't help you much. You have
+ created three separate Vendor branches, which is probably not
+ what you wanted.
+
+ Earlier versions of CVS, as described in Brian Berliner's Usenix
+ paper, tried to support multiple Vendor branches on the theory
+ that you might receive source for the *same* program from multiple
+ vendors. It turns out that this is very rare, whereas the need to
+ branch in *your* development, for releases and for project
+ branches, is much greater.
+
+ So the model now is to use a single vendor branch to contain a
+ series of releases from the same vendor. Your work moves along
+ on the Main Trunk, or on a CVS branch to support a real
+ "branch in development".
+
+ To set this up, you should type this instead of the above:
+
+ cd /src/blasto.v2
+ cvs import VENDOR Version2
+ cd /src/blasto.v3
+ cvs import VENDOR Version3
+ cd /src/blasto.v4
+ cvs import VENDOR Version4
+
+
+ 3H.11 What do I do if the Vendor adds or deletes files between releases?
+
+ Added files show up with no extra effort. To handle "removed"
+ files, you should always compare the tree structure of the new
+ release against the one you have in your Repository. If the
+ Vendor has removed files since the previous release, go into a
+ working directory containing your current version of the sources
+ and "remove" (followed by "commit" to make it really take effect)
+ each file that is no longer in the latest release.
+
+ Using this scheme will allow you to "checkout" any version of
+ the vendor's code, with the correct revisions and files, by
+ using "checkout -r Version[234]".
+
+
+ 3H.12 What about if the Vendor changes the names of files or
+ directories, or rearranges the whole structure between releases?
+
+ Currently CVS can't handle this cleanly. It requires
+ "renaming" a bunch of files or directories.
+
+ See 4B.9 on "renaming" for more details.
+
+ What I generally do is to close the Repository for a while and
+ make changes in both the Repository and in a copy of the vendor
+ release until the structure matches, then execute the import.
+
+ If you ever have to check out and build an old version, you may
+ have to use the new, or completely different Makefiles.
+
+
+ 3H.13 I thought "import" was for Vendor releases, why would I use it
+ for code of my own? Do I have to use import?
+
+ For code you produce yourself, "import" is a convenience for
+ fast insertion. It is not necessary. You can just as easily
+ checkin all the files using the RCS "ci" command and move the
+ resulting ",v" files into the Repository.
+
+ See Section 4B, on Setting up and Managing the Repository.
+
+
+=3H.14 How do I import a large Vendor release?
+
+ When the sum of the changes made by the Vendor and the changes
+ made by local developers is small, "import" is not a big
+ problem. But when you are managing a large Repository, any care
+ taken up front will save you time later.
+
+ First read the following, then, before executing "import", see the
+ questions in Section 4C dealing with branch merges and Vendor
+ branch merges.
+
+
+ 1. The first step is to make sure the structure of the new files
+ matches the structure of the current Repository.
+
+ Run "find . -print | sort" on both trees and "diff" the output.
+
+ 2. Alter the "source" tree until the "diff" (of the list of
+ filenames, not of the whole trees) shows that the directory
+ structures are equivalent.
+
+ The "comm" command, if you have it, can help figure out what
+ has been added or deleted between releases.
+
+ 3. If they deleted any files, you can handle them cleanly with
+ "cvs remove". The command "comm -23 files.old files.new" will
+ show you a list of files that need to be removed.
+
+ 4. If they renamed any files, see 4B.9 on renaming files.
+
+ 5. When you have dealt with removed and renamed files, then you
+ can execute the import:
+
+ cd <new source>
+ cvs import -m "Message" <repos> <VendorTag> <ReleaseTag>
+
+ Where
+
+ Message is the log message to be stored in the RCS files.
+
+ <repos> is a relative path to a directory within the
+ Repository. The directory <new source> must be at
+ the same relative level within the new sources as
+ the <repos> you give is within the Repository. (I
+ realize this is not obvious. Experiment first.)
+
+ <VendorTag> is a Tag used to identify the Vendor who sent you
+ the files you are importing. All "imports" into
+ the same <repos> *must* use the same VendorTag.
+ You can find it later by using the "log" command.
+
+ <ReleaseTag> is a Tag used to identify the particular release
+ of the software you are importing. It must be
+ unique and should be mnemonic -- at least include
+ the revision number in it. (Note: you can't use
+ '.' characters in a Tag. Substitute '_' or '-'.)
+
+ 6. *SAVE* the output from the import command.
+
+ 7. There will be six categories of files to deal with.
+ (Actually there are eight, but you have already dealt with
+ "removed" and "renamed" files.)
+
+ If this is the first "import" into a given <repos> directory,
+ only the first three of these ('I', 'L' and 'N') can occur.
+
+
+ a. Ignored file.
+
+ CVS prints: I filename
+
+ You'll need to examine it to see if it *should* have been
+ ignored. Alternatively, you can examine every file in the
+ "find" at the beginning and use the "import -I !"
+ option to avoid ignoring anything.
+
+
+ b. Symbolic link.
+
+ CVS prints: L linkname
+
+ Links are "ignored", but you'll probably want to create
+ a "checkout helper" function to regenerate them.
+
+
+ c. New file.
+
+ CVS prints: N filename
+
+ CVS creates a new file in the Repository. You don't
+ have to do anything to the file, but you might have to
+ change Makefiles to refer to it.
+
+
+ d. A file unchanged by the Vendor since its last release.
+
+ CVS prints: U filename
+
+ CVS will notice this and simply add the new ReleaseTag
+ to the latest rev on the Vendor branch.
+
+ No work will be needed by you, whether you have changed
+ the file or not. No one will notice anything.
+
+ e. A file changed by the Vendor, but not by you.
+
+ CVS prints: U filename
+
+ CVS should add the file onto the vendor branch and
+ attach the Release Tag to it.
+
+ When you next execute "update" in any working directory
+ you'll get the new revision.
+
+
+ f. A file changed by both the Vendor and by you.
+
+ CVS prints: C filename
+
+ These are the trouble files. For each of these files
+ (or in groups -- I usually do one directory at a
+ time), you must execute:
+
+ cvs update -j <PreviousReleaseTag> -j <ReleaseTag>
+
+ It will print either 'M' (if no overlaps) or 'C', if
+ overlaps. If a 'C' shows up, you'll need to edit the
+ file by hand.
+
+ Then, for every file, you'll need to execute"cvs commit".
+
+ See the part of Section 4C dealing with branch merges.
+
+
++3H.15 Explain: ERROR: cannot create link to <file>: Permission denied
+
+ This error appears when you try to execute a second (or later)
+ "import" into the same module from a directory to which you don't
+ have write access.
+
+ The "link error" is caused by a feature purposely added to
+ speed up the import.
+
+ Though the error message is somewhat strange, it indicates that
+ "import" is supposed to be executed only in writable directories.
+
+
+----------------
+-- Section 3I -- "log", "lo", "rlog"
+----------------
+
+ **** Questions:
+
+=3I.1 What is "log" for?
+ 3I.2 How do I extract the log entries between two revisions?
+=3I.3 How do I extract the log entries on a whole branch?
+=3I.4 How do I generate ChangeLogs from RCS logs?
+=3I.5 Why does "log" tell me a file was committed exactly 5 hours later
+ than I know it was?
+
+
+ **** Answers:
+
+=3I.1 What is "log" for?
+
+ To provide an interface to the RCS "rlog" command, which displays
+ information about the underlying RCS files, including the revision
+ history and Tag (what RCS calls "symbol") list.
+
+
+ 3I.2 How do I extract the log entries between two revisions?
+
+ If both <rev1> and <rev2> are on the same branch, you can get
+ what you are looking for with:
+
+ cvs log -r<rev1>:<rev2> <file>
+
+ If either <rev1> or <rev2> contain '-' characters, it will
+ complain and fail due to RCS's continued support of '-' as an
+ alternate range character.
+
+ <rev1> and <rev2> can be tag/symbol names, but they have to be
+ on the same branch, whether they are numeric or symbolic.
+
+
+=3I.3 How do I extract the log entries on a whole branch?
+
+ cvs log -r<rev> <file>
+
+ where <rev> must be a branch revision (one with an even number
+ of dots) or a *non-branch* tag on a branch revision. Non-branch
+ tags on a branch revision are not normally attached by CVS, to add
+ one you will have to explicitly tag a physical branch number
+ within each file. Since these branch numbers are almost never the
+ same in different files, this command is not all that useful.
+
+
+ 3I.4 How do I generate ChangeLogs from RCS logs?
+
+ A program called rcs2log is distributed as part of GNU Emacs 19.
+ This program should also appear in the CVS FTP archive.
+
+
+=3I.5 Why does "log" tell me a file was committed exactly 5 hours later
+ than I know it was?
+
+ I can tell by this question that you were working in a time zone
+ that is 5 hours behind GMT (e.g. the U.S. East Coast in winter).
+
+ RCS file dates are stored in GMT to allow users in different time
+ zones to agree on the meaning of a timestamp. At first glance
+ this doesn't seem necessary, but many companies use distributed
+ file systems, such as NFS or AFS, across multiple timezones.
+
+ Some standard form must be used. GMT, as the "grid origin", is an
+ obvious candidate. The only other reasonable choice is to put the
+ timezone information in all the time stamps, but that changes the
+ RCS file format incompatibly, a step which has been avoided in the
+ last few RCS releases.
+
+
+----------------
+-- Section 3J -- "patch", "pa", "rdiff"
+----------------
+
+ **** Questions:
+
+ 3J.1 What is "patch" for?
+ 3J.2 Why does "patch" include files from the Attic when I use '-D'?
+ 3J.3 How do I make "patch" produce a patch for one or two files?
+ It seems to work only with modules.
+
+
+ **** Answers:
+
+ 3J.1 What is "patch" for?
+
+ To produce a "diff" between tagged releases to be handed to the
+ "patch" command at other sites. This is the standard way that
+ source patches are distributed on the network.
+
+
+ 3J.2 Why does "patch" include files from the Attic when I use '-D'?
+
+ See the explanation of the same problem with "update -D"
+ contained in section 5B.
+
+
+ 3J.3 How do I make "patch" produce a patch for one or two files?
+ It seems to work only with modules.
+
+ Patch is intended for producing patches of whole modules between
+ releases to be distributed to remote sites. Instead of "patch",
+ you can use the "diff" command with the '-c' context option:
+
+ cvs diff -c -r <rev/tag> -r <rev/tag> <file1> . . .
+
+ The patch command will be able to merge such a "diff" into the
+ remote source files.
+
+ If the version of "diff" you are using supports the '-u' option,
+ to produce the more compact "Unidiff" format, the latest
+ revisions of the patch command understand that too.
+
+
+
+----------------
+-- Section 3K -- "release", "re", "rel"
+----------------
+
+
+ **** Questions:
+
+ 3K.1 What is "release" for?
+ 3K.2 Why does release -d delete directories within my directory that
+ weren't ever in the CVS Repository?
+ 3K.3 Why can't I reverse a "cvs checkout path/name/subdir" with a
+ "cvs release path/name/subdir" without an "unknown module name"?
+ 3K.4 Why can't I "release" portions of a checked out directory? I
+ should be able to "release" any file or sub-directory within
+ my working directory.
+ 3K.5 I removed the tree that I was about to start working on. How do I
+ tell cvs that I want to release it if I don't have it anymore?
+ 3K.6 Why doesn't "release -d module" reverse a "checkout module"?
+ 3K.7 Why can't I release a module renamed with "cvs checkout -d"?
+
+
+ **** Answers:
+
+ 3K.1 What is "release" for?
+
+ To register that a module is no longer in use. It is intended
+ to reverse the effects of a "checkout" by adding a record to
+ the history file to balance the checkout record and by
+ optionally allowing you to delete the checked-out directory
+ associated with the module name.
+
+
+ 3K.2 Why does release -d delete directories within my directory that
+ weren't ever in the CVS Repository?
+
+ A simplistic implementation. (I can say this -- I wrote it.)
+
+ The "release" function was written under the assumptions that the
+ "module name" is a first class, unavoidable interface to the
+ Repository, allowing no way to retrieve anything other than by
+ module name and a module is a self-contained entity with no
+ foreign directories allowed. Though it is easier to program that
+ way, many users of CVS believe the modules support to be too
+ primitive to allow such a limitation.
+
+ Since "release" was written, other parts of CVS broke those
+ assumptions. It will be upgraded slightly in the next release and
+ rewritten in the future.
+
+
+ 3K.3 Why can't I reverse a "cvs checkout path/name/subdir" with a
+ "cvs release path/name/subdir" without an "unknown module name"?
+
+ Again, "release" is too primitive. It believes, truly
+ *believes* in modules, not relative paths. I can't *believe*
+ how many times I've been asked this. It was a hack of the
+ moment with a particular use in mind. I had no idea it was
+ going to cause so much trouble. I'll *fix* it already! :-)
+
+
+ 3K.4 Why can't I "release" portions of a checked out directory? I
+ should be able to "release" any file or sub-directory within
+ my working directory.
+
+ Again, "release" believes in modules. Breaking it into bits
+ wasn't part of the plan. In the future, "release" might become
+ sophisticated enough to handle both the reversal of a "checkout"
+ and the deletion of random portions of the working directory, but
+ it isn't that way now.
+
+
+ 3K.5 I removed the tree that I was about to start working on. How do I
+ tell cvs that I want to release it if I don't have it anymore?
+
+ See 3G.4.
+
+
+ 3K.6 Why doesn't "release -d module" reverse a "checkout module"?
+
+ It does, if you are using "module" in a way that "release"
+ expects: a non-alias string in the left column of the "modules"
+ database.
+
+ If "module" is really an alias, or if you are using a relative
+ path in the place of "module", or if you renamed the directory
+ with the -d option in the modules file or on the "checkout"
+ command line, then the current version of "release" won't work.
+
+ Future versions of "release" will probably fix most of these.
+
+
+ 3K.7 Why can't I release a module renamed with "cvs checkout -d"?
+
+ The current version of "release" doesn't know how to track the
+ renaming option ('-d') of the "checkout" command. It will
+ probably be fixed in the future.
+
+
+
+----------------
+-- Section 3L -- "remove", "rm", "delete"
+----------------
+
+ **** Questions:
+
+ 3L.1 What is "remove" for?
+ 3L.2 Why doesn't "remove" work on directories when it appears to try?
+ 3L.3 I don't like removing files. Is there another way to ignore them?
+ 3L.4 I just removed a file. How do I resurrect it?
+ 3L.5 Why doesn't "remove" delete the file? Instead, it prints:
+ cvs remove: no files removed; use `rm' to remove the file first
+
+
+ **** Answers:
+
+ 3L.1 What is "remove" for?
+
+ To remove a file from the working branch. It removes a file from
+ the main branch by placing it in an "Attic" directory.
+
+
+ 3L.2 Why doesn't "remove" work on directories when it appears to try?
+
+ Oversight. It should be able to delete an empty directory, but
+ you still don't have a way to remember when it was there and when
+ it disappeared to allow the "-D <date>" option to work.
+
+ You'll have to remove the working directory and the matching
+ directory in the Repository.
+
+
+ 3L.3 I don't like removing files. Is there another way to ignore them?
+
+ There's no reason to be hasty in using the "remove" command.
+
+ If there is a way to ignore files in your build procedures, I'd
+ just do that. Later, when you decide that the files are really
+ ancient, you can execute a "remove" command to clean up.
+
+ The CVS "ignore" concept can't ignore files already in CVS.
+
+
+ 3L.4 I just removed a file. How do I resurrect it?
+
+ If you executed "remove", but haven't typed "commit" (you can
+ tell this by the 'R' notation that "update" prints next to the
+ file), you can execute "add" to reverse the "remove".
+
+ If you followed the "remove" with a "commit", you'll have
+ to move it back out of the Attic by hand:
+
+ I use something like this: (csh-like syntax)
+
+ set repos = `cat CVS/Repository`
+ mv $repos/Attic/filename,v $repos/filename,v
+
+ (If you use relative paths in your Repository files, that first
+ line becomes: set repos = $CVSROOT/`cat CVS/Repository`)
+
+ While a file is in the Attic, you can't "add" another file by
+ the same name. To add such a file you either have to move it by
+ hand as in the above, or delete it from the Attic.
+
+ The main reason for the Attic is to retain files with tags in
+ them. If you execute: "update -r <oldtag>", files with <oldtag>
+ attached to some revision will be taken from the normal Repository
+ area and from the Attic. That's why you can't "add" a file with
+ the same name. "remove" only moves a file off the main branch, it
+ doesn't obliterate it.
+
+
+ 3L.5 Why doesn't "remove" delete the file? Instead, it prints:
+ cvs remove: no files removed; use `rm' to remove the file first
+
+ Design choice. Unix software written within last decade, usually
+ requires an extra verification step, such as answering a question
+ or adding a flag on the command line. CVS currently requires that
+ you delete the file first.
+
+ Future versions of CVS might contain a '-f' switch that deletes
+ the existing file without complaining.
+
+
+----------------
+-- Section 3M -- "rtag", "rt", "rfreeze"
+----------------
+
+(See the "tag" section below for questions in common with "rtag".)
+
+
+ **** Questions:
+
+ 3M.1 What is "rtag" for?
+ 3M.2 Why would you use "rtag"? It assumes a static Repository.
+
+
+ **** Answers:
+
+ 3M.1 What is "rtag" for?
+
+ To add a symbolic label (a "tag") to the last committed revisions
+ of a module directly in the Repository.
+
+
+ 3M.2 Why would you use "rtag"? It assumes a static Repository.
+
+ Though the "tag" command is more useful in marking the
+ revisions you have in a particular working directory, "rtag" is
+ much handier for whole-Repository actions, which occur at major
+ release boundaries.
+
+
+
+----------------
+-- Section 3N -- "status", "st", "stat"
+----------------
+
+ **** Questions:
+
+=3N.1 What is "status" for?
+ 3N.2 Why does "status" limit the File: at the top to 17 characters?
++3N.3 Shouldn't the status "Needs Checkout" be "Needs Update"?
+
+
+ **** Answers:
+
+=3N.1 What is "status" for?
+
+ To display the status of files, including the revision and branch
+ you are working on and the existence of "sticky" information.
+
+
+ 3N.2 Why does "status" limit the File: at the top to 17 characters?
+
+ Designed that way to line up with other data. You can find the
+ whole filename in the line beginning with "RCS version:", which is
+ not limited in length.
+
+
++3N.3 Shouldn't the status "Needs Checkout" be "Needs Update"?
+
+ Probably. Maybe in future revisions.
+
+
+
+----------------
+-- Section 3O -- "tag", "ta", "freeze"
+----------------
+
+ **** Questions:
+
+ 3O.1 What is "tag" for?
+=3O.2 What is the difference between "tag" and "rtag"?
+=3O.3 Why does "tag -b" not put a tag on the Branch Point revision?
+ How do I refer to the Branch Point?
+-3O.4 So "tag" labels a bunch of files. What do you use a Tag for?
+ 3O.5 How do I get "tag" and "rtag" to send mail the way "commit" does?
+ 3O.6 Why can't "tag" handle the '-r' option that "rtag" takes?
+-3O.7 After a "tag <tag>" in my working directory, why doesn't "checkout
+ -r <tag>" somewhere else produce copy of my current files?
+#3O.8 Why doesn't "tag" write a history record the way "rtag" does?
+
+
+ **** Answers:
+
+ 3O.1 What is "tag" for?
+
+ To add a symbolic label (a "tag") to the RCS files last checked
+ out, updated or committed in a working directory.
+
+
+=3O.2 What is the difference between "tag" and "rtag"?
+
+ The end result of both commands is that a <tag>, or symbolic name,
+ is attached to a particular revision of a collection of files.
+
+ The differences lie in:
+
+ 1. The collection of files they work on.
+
+ "rtag" works on the collection of files referred to by a
+ "module" name, as defined in the "modules" file.
+
+ "tag" works on files and directories in the current working
+ directory.
+
+ Both commands recursively follow directory hierarchies within
+ the named files and directories.
+
+ 2. The revisions they choose to tag.
+
+ "rtag" places a tag on the latest committed revision of
+ each file on the branch specified by the '-r' option. By
+ default it tags the Main Branch.
+
+ "tag" places a tag on the BASE (i.e. last checked out, updated
+ or committed) revision of each file found in the working
+ directory.
+
+ 3. A different set of command line options.
+
+ For example, "rtag" takes a "-r <oldtag>" option to retag an
+ existing tag. The "tag" command does not.
+
+ 4. How it is logged.
+
+ Currently "rtag" records the <tag> and the module in the
+ "history" file, while "tag" does not.
+
+
+=3O.3 Why does "tag -b" not put a tag on the Branch Point revision?
+ How do I refer to the Branch Point?
+
+ Design decision. If everything works perfectly, the "update -j"
+ command will do the merge you need and you don't need to check up
+ on it by playing with the branch point revision.
+
+ The '-b' option attaches a magic branch tag to allow CVS later to
+ figure out the branch point. The actual revision that <tag> is
+ attached to does not exist. References to the branch tag are
+ equivalent to references to the latest revision on the branch.
+
+ There is no way to refer to the branch point without adding a
+ non-branch tag. See 4C.3 on Creating a Branch.
+
+
+-3O.4 So "tag" labels a bunch of files. What do you use a Tag for?
+
+ You use it to "checkout" the labeled collection of files as a
+ single object, referring to it by name.
+
+ Anywhere a revision number can be used a Tag can be used. In fact
+ tags are more useful because they draw a line through a collection
+ of files, marking a development milestone.
+
+ The way to think about a Tag is as a curve drawn through a matrix
+ of filename vs. revision number. Consider this:
+
+ Say we have 5 files (in some arbitrary modules, some may be in 2
+ or more modules by name, some may be in 2 or more modules because
+ of the Repository tree structure) with the following revisions:
+
+ 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
+
+ At some time in the past, the '*' versions were tagged. 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 draw a
+ straight line through the set of revisions you care about and
+ shuffle the other revisions accordingly. Like this:
+
+ 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
+
+ I find that using these visual aids, it is much easier to
+ understand what a <tag> is and what it is useful for.
+
+
+ 3O.5 How do I get "tag" and "rtag" to send mail the way "commit" does?
+
+ The "commit" command is supported by two files ("commitinfo"
+ and "loginfo") not used by other commands. To do logging the
+ same way for "tag" and "rtag" would require another file like
+ loginfo, which currently doesn't exist.
+
+ The "rtag" command requires a "module" entry, which can specify a
+ "tag" program using the "-t programname" option on the module
+ line.
+
+ There is no equivalent support for "tag".
+
+
+ 3O.6 Why can't "tag" handle the '-r' option that "rtag" takes?
+
+ Oversight. The answer is probably "Fixed in a Future Release."
+
+
+-3O.7 After a "tag <tag>" in my working directory, why doesn't "checkout
+ -r <tag>" somewhere else produce copy of my current files?
+
+ The only reason this would fail, other than misspelling the <tag>
+ string, is that you didn't "commit" your work before "tagging" it.
+ Only committed revisions may be tagged. Modified files are not
+ marked for later tagging.
+
+
+#3O.8 Why doesn't "tag" write a history record the way "rtag" does?
+
+ The "rtag" command was originally intended to place major
+ "release" tags onto modules. The "tag" functionality was
+ developed to *move* the more significant tag when slight changes
+ to individual files sneaked in after the release tag was stamped
+ onto the Repository.
+
+ The significant event was the "rtag", which was recorded in the
+ "history" file for the "history -T" option to work.
+
+ It turns out that "tag" is more useful than "rtag", so the model
+ has changed. Future revisions of CVS will probably store both
+ kinds of tags in the history file.
+
+
+
+----------------
+-- Section 3P -- "update", "up", "upd"
+----------------
+
+ **** Questions:
+
+ 3P.1 What is "update" for?
+=3P.2 What do 'U', 'M' and 'C' mean when I type "update"? Are they
+ different for "cvs -n update"?
+ 3P.3 What's the difference between "update" and "checkout"?
+=3P.4 Why don't I get new files when I execute "update"?
+#3P.5 Why does "update" say 'M' both for plain modified files and for
+ successful (i.e. conflict-free) merges? Aren't they different?
+=3P.6 After a merge ("update" or "update -j"), why doesn't CVS remember
+ the conflict and not allow you to commit the result until the
+ conflict is resolved?
+ 3P.7 Is there a feature to tell me what I have changed, added and
+ removed without changing anything?
+=3P.8 Why does "cvs update" not flag directories that are not in the
+ Repository as it does with new files?
+ 3P.9 Why are all my files deleted when I execute "update"?
+
+
+ **** Answers:
+
+ 3P.1 What is "update" for?
+
+ The "update" command is by far the most important command and is
+ probably also the most used command.
+
+ It has five purposes: (And many options.)
+
+ 1. To display the status of your working files.
+
+ Though a plain "update" also displays the status, it does so
+ after possibly altering your working directory. To see the
+ status of your working files without changing anything, type:
+
+ cvs -n update {optional list of files}
+
+
+ 2. To merge changes made to the branch you are working on into
+ your working files.
+
+ Each working directory is attached to a branch, usually the
+ Main branch. To merge changes made on your working branch by
+ other people into your working files, type:
+
+ cvs update {optional list of files}
+
+
+ 3. To merge changes made to another branch into the branch you are
+ working on (your "working branch").
+
+ If you want to grab a whole branch, from the branch point,
+ which is assumed to be on the Main Branch, to the end of the
+ branch, you type:
+
+ cvs update -j <branch_tag> {optional files}
+
+ If you want to grab the changes made between two tags or
+ revisions, you type:
+
+ cvs update -j <tag1/rev1> -j <tag2/rev2> {optional files}
+
+ (If you are working with a single file, the Tags could also be
+ revisions numbers. Unless you take really unusual care to
+ match revision numbers across different files (a waste of time
+ given the way Tags work), using revision numbers in places of
+ the Tags for multiple files would be meaningless.)
+
+
+ 4. To move your working directory to another branch.
+
+ A working directory is presumed to be attached to (or working
+ on) a particular branch, usually the Main branch. To alter
+ what CVS believes to be your working branch, you "move" to that
+ branch.
+
+ To move to a tagged branch, type:
+
+ cvs update -r <branch_tag> {optional files}
+
+ To move to the Main Branch, type:
+
+ cvs update -A {optional files}
+
+
+ 5. To retrieve old revisions of files.
+
+ This option is similar to 4 above but you are not restricted to
+ using a <branch_tag>. You may specify any revision or Tag with
+ '-r' and get the specified revision or the tagged revision:
+
+ cvs update -r <tag/rev> {optional files}
+
+ Or you may specify any date with '-D':
+
+ cvs update -D <date> {optional files}
+
+ The '-p' option sends the revisions to standard output
+ (normally your terminal) rather than setting the "sticky" tag
+ and changing the files.
+
+
+=3P.2 What do 'U', 'M' and 'C' mean when I type "update"? Are they
+ different for "cvs -n update"?
+
+ "cvs update" merges changes made to the Repository, since your
+ last "checkout", "update" or "commit", into your working files.
+ You can think of it as "changing your BASE revision."
+
+ "cvs update" prints lines beginning with:
+
+ 'U' after replacing your unmodified file with a different
+ revision from the Repository.
+
+ 'M' for two different reasons:
+
+ 1. for files you have modified that have not changed in
+ the Repository.
+
+ 2. after a merge, if it detected no conflicts.
+
+ 'C' after a merge, if it detected conflicts.
+
+ You will need to remove the conflicts by editing the file.
+ Conflicts are surrounded by <<<<< and >>>>> markers.
+
+
+ "cvs -n update" shows what it *would* do, rather than doing it.
+ Or, another way of looking at it, "cvs -n update" displays the
+ relationship between your current BASE revisions and the latest
+ revisions in the Repository.
+
+ "cvs -n update" prints lines beginning with:
+
+ 'U' for files you have not modified that have changed in the
+ Repository.
+
+ 'M' for files you have modified that have not changed in the
+ Repository.
+
+ 'C' for files you have modified that have also been changed in
+ the Repository.
+
+
+ See 4C.6 for what the letters mean when merging in from another
+ branch. The output is almost the same for a normal update if you
+ consider the Repository as the branch and your working directory
+ as the "trunk".
+
+
+ 3P.3 What's the difference between "update" and "checkout"?
+
+ See 3C.4 above.
+
+
+=3P.4 Why don't I get new files when I execute "update"?
+
+ There are six reasons for nothing to happen during an "update":
+
+ 1. Nothing on your branch changed in the Repository.
+
+ If no one has committed anything to the branch you are working
+ on (normally the Main branch) since the last time you executed
+ "checkout", "update" or "commit", nothing will happen.
+
+ It's like shouting "xyzzy" or "plugh" in the wrong room.
+
+ 2. You have a "sticky" non-branch <tag> or <date> attached to the
+ working files you are trying to "update".
+
+ At some time in the past you checked out or updated your
+ directory with the "-r <tag>" or "-D <date>" option. Until you
+ do it again with a different tag or date, or go back to the
+ Main Branch with "update -A", you will never again see any
+ updates.
+
+ 3. The ./CVS/Entries.static file exists and you are expecting a
+ new file.
+
+ If your ./CVS administrative directory contains a file named
+ Entries.Static, no files will be checked out that aren't
+ already in the Entries or Entries.Static file.
+
+ 4. You forgot to use the '-d' option and are looking for new
+ directories.
+
+ If you execute "update" without the '-d' option, it will not
+ create new directories that have been added to the Repository.
+
+ 5. You typed "update" instead of "cvs update".
+
+ And now your disk caches are furiously being flushed by
+ multiple update daemons, destroying performance and proving to
+ management that you need more CPU power. :-)
+
+ 6. Someone backed out the revision CVS thought you had in your
+ working directory, then committed a "replacement". CVS is now
+ confused because the revision in the Repository matches the
+ revision CVS thinks you already have. See 3B.6.
+
+
+#3P.5 Why does "update" say 'M' both for plain modified files and for
+ successful (i.e. conflict-free) merges? Aren't they different?
+
+ A design choice. Yes, they are different internally, but that
+ shouldn't matter. Your files are in the same condition after the
+ "update" as they were before -- a "diff" will display only your
+ modifications. And you are expected to continue onward with the
+ normal cycle of "emacs" (a synonym for "edit" in most of the
+ civilized world) and "commit".
+
+
+=3P.6 After a merge ("update" or "update -j"), why doesn't CVS remember
+ the conflict and not allow you to commit the result until the
+ conflict is resolved?
+
+ Maybe in a future release. There is a "sticky_conflict" patch you
+ might want to look at in the CVS FTP archive.
+
+
+ 3P.7 Is there a feature to tell me what I have changed, added and
+ removed without changing anything?
+
+ The command "cvs -n update" will do exactly that.
+
+
+=3P.8 Why does "cvs update" not flag directories that are not in the
+ Repository as it does with new files?
+
+ Design choice or oversight, take your pick. Directories are
+ handled specially. You can aim "update" at any random directory
+ and "update" will traverse the whole directory tree beneath it,
+ looking for CVS administrative directories. When it finds one,
+ "update" will perform its "normal" function.
+
+ Maybe a future release will notice a directory not under CVS,
+ print a '?' and skip over it.
+
+
+ 3P.9 Why are all my files deleted when I execute "update"?
+
+ You probably executed "update -r <tag>" some time ago, then
+ removed <tag> from the Repository files. "update -r <tag>" will
+ delete a file that doesn't contain <tag>.
+
+ A way to fix this is to "cd" into your working directory and
+ type:
+
+ cvs update -A
+
+ If you don't want the latest revisions on the Main (or Vendor)
+ Branch, then decide what Tag (normal or branch) you want and type:
+
+ cvs update -r <the_tag_you_want>
+
+ Another way to make files disappear is to execute "update -D
+ <date>" where <date> is before the date stamped onto the first
+ revision in the RCS file.
+
+
+
+===============================================
+== Section 4 ==== Advanced Topics ====
+===============================================
+
+----------------
+-- Section 4A -- Installing CVS
+----------------
+
+ **** Questions:
+
+#4A.1 What do I have to do before I install CVS?
+ 4A.2 How do I configure the CVS programs?
+=4A.3 What do I have to install?
+-4A.4 How do I work around the merge problems in GNU diff version 2.1
+ or later?
+
+
+ **** Answers:
+
+#4A.1 What do I have to do before I install CVS?
+
+ 1. You must decide where to set up a Repository.
+
+ Though you can construct a Repository tree structure using
+ links and mount points, there must be a single copy of each
+ real file across your entire organization. You may not "rdist"
+ files and expect to edit both copies.
+
+ CVS does not support a truly distributed Repository. You can
+ have multiple Repositories, but each one must be mounted (not
+ copied or "rdist"ed) from a single place onto all machines
+ where it will be used.
+
+ Initially, a Repository takes about same amount of disk space
+ as the sources you want to put into it, plus a bit of overhead
+ for the RCS files.
+
+ See Section 4B. For multiple Repositories, see 4D.14.
+
+ 2. You need a directory in everyone's $PATH variable where you can
+ install all the executables. /usr/local/bin is a common place.
+
+ 3. You need some helper tools besides CVS such as "RCS" and a
+ good set of "diff" and "diff3" programs. See 1B.3 for
+ suggestions.
+
+ 4. Make sure you have versions of all the programs mentioned in
+ the "cvs/src/config.h" file.
+
+ 5. Though you can probably muddle along without it, you should
+ appoint one or more "Repository Administrators" who will be
+ responsible for maintaining the Repository structure,
+ administrative files and the "modules" interface.
+
+ Someone at your site should probably be on the info-cvs mailing
+ list. See 1B.5.
+
+
+ 4A.2 How do I configure the CVS programs?
+
+ 1. You should certainly start by reading the README file, the
+ INSTALL files and possibly the Makefiles and "cvsinit" program.
+
+ 2. Edit the "config.h" file in the "src" directory.
+
+ Read it carefully.
+
+ You will need to specify a number of site-specific pieces of
+ information including the names of a number of functions.
+
+ Hint1: You really want to set the DIFF macro to use your
+ version of the GNU diff program with the '-a' option.
+ Ours is set to "gdiff -a".
+
+ Hint2: You want to use RCS 5.5 or greater and set the
+ "HAVE_RCS5" macro.
+
+ 3. Execute the ./configure command.
+
+ 4. Type "make".
+
+
+=4A.3 What do I have to install?
+
+ 1. Install the "cvs" executable and "mkmodules" from the CVS
+ sources. (The man page is useful too.)
+
+ 2. Make sure you have versions of all the programs mentioned in
+ the config.h file, most of which are included in a standard
+ Unix system.
+
+ 3. Unless you plan to reimplement RCS [:-)], you must install RCS.
+
+ 4. Create the Repository (which you planned out in 4A.1) with the
+ "cvsinit" command at the top of the CVS sources.
+
+ 5. You'll need to edit the Repository control files created by
+ "cvsinit".
+
+ 6. Install any helper programs mentioned in the modules file.
+
+
+-4A.4 How do I work around the merge problems in GNU diff version 2.1
+ or later?
+
+ See 4D.11.
+
+
+----------------
+-- Section 4B -- Setting up and Managing the Repository
+----------------
+
+ **** Questions:
+
+=4B.1 What do I do first? How do I create a Repository?
+=4B.2 What are those files in $CVSROOT/CVSROOT?
+ 4B.3 Is there any other state stored in the Repository besides in the
+ $CVSROOT/CVSROOT directory?
+ 4B.4 How do I put sources into the Repository?
+=4B.5 What file permissions should I use on (and in) the Repository?
+=4B.6 How do I structure my Repository?
+=4B.7 How do I manage the modules file?
+ 4B.8 Why would anyone use "modules"? They are too restrictive. I
+ want to be able to select just the files I want to edit.
+=4B.9 How do I rename a file or directory? What are the consequences?
+=4B.10 What are "Attic" directories?
+ 4B.11 Is it OK to remove anything from the Repository?
+ 4B.12 Can I convert to CVS from RCS without losing my revision history?
+=4B.13 Can I move RCS files with branches in them into the Repository?
+=4B.14 Can I use raw RCS commands on the Repository?
+ 4B.15 How do I convert from SCCS to RCS?
+=4B.16 How do I limit access to the Repository?
+=4B.17 What are the Repository Administrator's responsibilities?
+ 4B.18 How do I move the whole Repository?
++4B.19 How do I change permissions on a file in the Repository by using
+ a CVS command? (i.e. without using "chmod 777 $CVSROOT/dir/file")
+
+
+ **** Answers:
+
+
+=4B.1 What do I do first? How do I create a Repository?
+
+ First, install all the programs. (See Section 4A.)
+
+ Then create a Repository by executing "cvsinit", which works only
+ from within the head of the CVS source directory. (It needs files
+ from the distribution to work.)
+
+ If you want a very primitive Repository and don't want to save a
+ history log, refer to modules, or use any of the "info" files for
+ logging, pre-commit checks, or editing templates, you can dispense
+ with "cvsinit" entirely. I would advise executing it.
+
+ The cvsinit program will create a short modules file containing
+ the module named "CVSROOT". Execute:
+
+ cvs checkout CVSROOT
+
+ and read the information stored in the files that are checked out.
+
+ You will certainly want to add modules of your own. Edit the
+ "modules" file and add lines to describe the items you want to
+ "checkout" by module name. Here's a short list that could be
+ used for storing a small number of GNU and PD sources:
+
+ local local
+
+ gnu local/gnu
+ emacs local/gnu/emacs
+ cvs local/gnu/cvs
+
+ public local/public
+ pdprog1 local/public/pdprog1
+ pdprog2 local/public/pdprog2
+
+ test test
+ junk test/junk
+
+
+ When you are done editing, "commit" the modules file. If you
+ configured CVS to use "dbm", you might have to edit and commit the
+ modules file twice, in order to change the pathname of the
+ mkmodules program in the modules file.
+
+ Try using the "import" command to insert the "junk" module
+ and play around until you are comfortable.
+
+
+
+=4B.2 What are those files in $CVSROOT/CVSROOT?
+
+ There are seven Repository control (or "database") files of
+ interest in the CVSROOT directory:
+
+ 1. commitinfo contains two columns: 1. a regular expression to
+ match against pathnames within the Repository and
+ 2. a <command> to execute for matching pathnames.
+
+ When you execute "commit", CVS passes the
+ Repository pathname for each directory (and the
+ files to commit within that directory) to
+ <command>. If <command> exits with a non-zero
+ status, the commit is blocked.
+
+ A <command> associated with a pathname of
+ "DEFAULT" is executed if nothing else matches.
+ Every <command> associated with a pathname of
+ "ALL" is executed separately.
+
+ 2. rcsinfo contains the same first column as commitinfo, but
+ the second column is a template file for
+ specifying the log entry you are required to enter
+ for each commit.
+
+ "DEFAULT" and "ALL" work the same as in the
+ commitinfo file.
+
+ 3. editinfo contains the same two columns as commitinfo, but
+ the <command> in the second column is intended to
+ do some consistency checking on the commit log.
+
+ "DEFAULT" works as in commitinfo.
+
+ 4. loginfo contains the same two columns as commitinfo, but
+ the <command> is expected to read a log message
+ from its standard input. The <command> can do
+ anything it wants with the log information, but
+ normally it is appended to a log file or sent to
+ mailing lists.
+
+ "DEFAULT" & "ALL" work the same as in commitinfo.
+
+ 5. cvsignore contains "ignore" patterns that are added to the
+ built-in ignore list. See 2D.10.
+
+ 6. history contains a stream of text records, one for each
+ event that the "history" command is interested
+ in. Though the contents of the history file can
+ be read, it is intended to be read and displayed
+ by the "history" command.
+
+ 7. modules contains the "modules" database. See 1D.11, 2C.7,
+ 4B.7 and 4B.8 for more details.
+
+
+ 4B.3 Is there any other state stored in the Repository besides in the
+ $CVSROOT/CVSROOT directory?
+
+ Only in the RCS files. The Repository holds exactly two things:
+ the tree of RCS files (each usually ending in ",v") and the
+ CVSROOT directory described above.
+
+
+ 4B.4 How do I put sources into the Repository?
+
+ There are three main ways to put files in the Repository:
+
+ 1. Use the "import" command described in Section 3H.
+
+ This method is the fastest way to put trees of new code into
+ the Repository and the *only* way to handle source releases
+ from a 3rd party software vendor.
+
+ 2. Use "add" followed by "commit".
+
+ This is how to add new files and directories to the Repository,
+ one at a time.
+
+ 3. You can move RCS files directly into the Repository.
+
+ It would probably be a good idea to create directories to hold
+ them.
+
+
+=4B.5 What file permissions should I use on (and in) the Repository?
+
+ If you run a completely open environment (which usually means that
+ you don't have, or don't want to waste, the time to deal with it):
+
+ - Set all directory permissions to 777.
+
+ - Have everyone set their umasks to 0.
+
+ (BTW, I don't suggest this. It am merely reporting it.)
+
+
+ If you are a normal Unix shop and want to use groups effectively:
+
+ - Set all the directory permissions in the Repository to 775.
+ (If you are using a system that handles both System V and BSD
+ filesystems, you might have to set the permissions to 2775.)
+
+ - Change all the groups on the directories to match the groups
+ you want to write to various directories.
+
+ - Make sure every user is in the appropriate groups.
+
+ - Have everyone set their umask to 002.
+
+
+ If you don't want non-group members to even read the files, do the
+ above, but change:
+
+ - Repository directory permissions to 770. (or 2770)
+
+ - umasks to 007.
+
+
+ If you work in an environment where people can't be trusted to
+ set their "umask" to something reasonable, you might want to set
+ the umask for them:
+
+ mv /usr/local/bin/cvs /usr/local/bin/cvs.real
+ cat > /usr/local/bin/cvs
+ #!/bin/sh
+ umask 2 # Or whatever your site standard is.
+ exec /usr/local/bin/cvs.real ${1+"$@"}
+ ^D
+
+ [[Future versions of CVS might sprout a "umask" configuration
+ variable.]]
+
+
+=4B.6 How do I structure my Repository?
+
+ The Repository holds your software. It can be all interrelated
+ or it can be a bunch of separately managed directories.
+
+ How you break a whole system down into its component parts, while
+ defining interfaces between them, is one aspect of "Software
+ Engineering", a discipline that requires the study of dozens of
+ strange and wonderful areas of the computer and management worlds.
+
+ CVS provides a way to keep track of changes to individual files,
+ a way to "tag" collections of files, and a way to "name"
+ collections of files and directories. That's all. Everything
+ else is in the way you apply it.
+
+ In other words, you should structure your Repository to match your
+ needs, usually tied in with the other tools you use to build,
+ install and distribute your work. Common needs include the
+ ability to:
+
+ - mount (or automount) directories from different
+ places in your organization.
+ - check out just what you need and no more.
+ - check out multiple sections in a fixed relation to each other.
+ - check out large sections to match the assumptions built into
+ your build system. (Makefiles?)
+
+ In my opinion, you should start small and keep everything in one
+ tree, placing each major sub-system into a separate directory.
+ Later, when you know what you are doing, you can make it more
+ sophisticated.
+
+
+=4B.7 How do I manage the modules file?
+
+ An equivalent question might be, "How do I structure my sources?"
+ This can be a difficult question in that it is not purely
+ technical.
+
+ Generally you want to think about what pieces of your system need
+ to be checked out together, built as one system or tagged
+ consistently. You should certainly make module names that
+ correspond to complete, buildable collections that you would tag
+ and release as one "product". It is also convenient to create
+ module names for small sections containing files that will usually
+ be worked on at the same time by the same person.
+
+ Once you have defined the structure of your work, you can usually
+ see how to lay it out in a Repository. After that the modules
+ file is easy. You set up module names and aliases to match what
+ you need to check out by name. If you like relative directories,
+ it is possible, but not recommended, to work completely without a
+ modules file. See 1D.11 and 2C.7.
+
+
+ 4B.8 Why would anyone use "modules"? They are too restrictive. I
+ want to be able to select just the files I want to edit.
+
+ Any form of structure is restrictive. If you believe that total
+ chaos is a viable working paradigm, or if you believe you can keep
+ track of the interrelations between all portions of your
+ Repository in your head, then you can do what you please.
+
+ If you believe that systems of files require management and
+ structure, then the "modules" idea is very useful. It is a way
+ to impose a naming scheme on a tree of files, a naming scheme that
+ can be simpler than a large list of relative pathnames.
+
+ The "modules" file represents a published interface to the
+ Repository set up by your Repository Administrator. If s/he did a
+ creditable job, the modules offered will be internally consistent
+ and will smoothly interact with the rest of your environment.
+
+
+=4B.9 How do I rename a file or directory? What are the consequences?
+
+ In CVS 1.3 there is no single CVS "rename" command.
+
+ See 2C.4 for the suggested way to rename a file or directory.
+
+ The rest of this section covers some of the consequences of
+ renaming.
+
+ A "renaming database" has been proposed that would keep track
+ of name changes so that "update -r <tag>" would continue to
+ work across the renaming. But as it stands, you have to pick
+ one of the following options:
+
+ 1. Use the technique described in 2C.4. (For each file, duplicate
+ the file in the Repository, "remove" the old version so it
+ winds up in the Attic and strip all Tags off the new version.)
+
+ - "update -r <tag>" produces the correct files.
+
+ - The duplicated revision history can be slightly misleading.
+
+ - A plain (i.e. without the "-r <tag>") "checkout" or "update
+ -d" will create directories "renamed" this way, but you can
+ delete it and a plain "update" won't bring it back.
+
+
+ 2. Move the files and directories in the Repository to the new
+ names.
+
+ - You save the revision history under a different file name.
+
+ - You save a little space.
+
+ - "update -r <tag>" produces the wrong files or directories.
+
+ This is not a good general solution, but if you plan never to
+ look back (someone may be gaining on you!), it is sometimes a
+ useful notion.
+
+ If you are clever with Makefiles, you might be able to rework
+ them to handle either the new or old names, depending on
+ which ones exist at the time. Then you can move an old <tag>
+ onto the new, more sophisticated, revision of the Makefile.
+ (Yes, this changes the "released" file if <tag> indicates a
+ release. But it is an option.)
+
+ - Important Note: If you rename a directory, you must rename
+ the corresponding directory in every checked-out working
+ directory. At the same time, you must edit the pathname
+ stored in the ./CVS/Repository file within each of the moved
+ directories.
+
+ The easiest way to move a lot of directories around is to
+ tell everyone to remove their working directories and check
+ them out again from scratch.
+
+ - The file exists in the working directory and in the
+ ./CVS/Entries file, but not in the Repository. For the old
+ file, "update" prints:
+
+ cvs update: xyz.c is no longer in the repository
+
+ and deletes the file. If the file was modified, "update"
+ prints:
+
+ cvs update: conflict: xyz.c is modified but
+ no longer in the repository
+ C xyz.c
+
+ and leaves the file alone. In the new directory, you see:
+
+ U xyz.c
+
+ as you would if someone else executed "add" and "commit".
+
+
+ 3. For each file, copy the working file to a new name, "remove"
+ the old file and "add" the new one. Since there is no way (in
+ CVS 1.3) to remove a directory, this only works for files.
+
+ - This is what most people think of first. Without a "rename"
+ command, the remove/add technique seems obvious.
+
+ - You lose the connection of your new working file to its past
+ revision history.
+
+
+=4B.10 What are "Attic" directories?
+
+ When you use the "remove" command on a file, CVS doesn't delete
+ the file, it only registers your desire to delete it.
+
+ When you "commit" a removed file, CVS moves the Repository's
+ matching RCS file into a sub-directory named "Attic" within the
+ Repository.
+
+ Attic files are examined when the '-r' or '-D' option is used
+ on "checkout" or "update". If the specified revision, tag or
+ date matches one on a file in the Attic, that file is checked out
+ with the others.
+
+ You can think of the Attic as a sort of dead branch, which is only
+ looked at when you refer to a <tag> or <date>.
+
+
+ 4B.11 Is it OK to remove anything from the Repository?
+
+ In general, removing anything from the Repository is a bad idea.
+ The information in a deleted object is lost forever. There are
+ many ways to skip over files, directories and revisions without
+ deleting them.
+
+ Here are some of the consequences of removing the following things
+ stored in the Repository:
+
+ 1. CVSROOT files (Repository control files)
+
+ The Repository will work without any of them, but you should
+ understand what you are losing by deleting them. See 4B.2.
+
+ 2. Revisions
+
+ The only way to remove revisions is to use the "admin -o"
+ command (or the equivalent RCS command "rcs -o").
+
+ They are lost forever. Any tags formerly attached to deleted
+ revisions are now pointing into Outer Space.
+
+ 3. Files
+
+ You should not remove a file unless you truly never want to see
+ it again. If you want to be able to check out an old revision
+ of this file, use "cvs remove" instead.
+
+ 4. Tags
+
+ Tags take up little space and you can't recover from deleting
+ them. If you depend on tags for releases you will lose vital
+ information.
+
+ 5. Directories
+
+ There is no Attic for directories, so the only way to remove
+ them is to use "rm -r". They are gone forever.
+
+ If you delete (or move) a directory, all checked-out versions
+ of that directory will cause CVS to halt. You'll have to visit
+ each checked-out directory and remove the matching working
+ directory by hand.
+
+ 6. Attic files
+
+ The "remove" command sends files to the Attic. To really
+ delete them, you have to go into the Attic and use "rm".
+
+ If a file in the Attic has a Tag on it that you might ever want
+ to check out again, you probably don't want to delete it.
+
+ 7. Lock files (named: "#cvs.[wr]fl.<pid>")
+
+ These are lock files. If you are getting "lock" errors and
+ the dates on the lock files indicate that they are old, you can
+ delete them.
+
+ Deleting lock files still in use by a CVS process might produce
+ unusual errors.
+
+
+ 4B.12 Can I convert to CVS from RCS without losing my revision history?
+
+ Yes, you can simply move (or copy) your RCS files into a directory
+ within the Repository, check out that directory and start working.
+
+
+=4B.13 Can I move RCS files with branches in them into the Repository?
+
+ Yes, but they may not work if you created branches in a way that
+ conflicts with CVS's assumptions:
+
+ 1. You can't use .0. branches. (They are reserved for "Magic"
+ branch tags.)
+
+ 2. If you use branch 1.1.1, you can't use the Vendor branch.
+
+ You can use other RCS branches under CVS. There is no need to
+ create "magic" branch tags because the physical branch already
+ exists.
+
+
+=4B.14 Can I use raw RCS commands on the Repository?
+
+ You can use raw rcs commands directly on the Repository if you
+ take a little care. The Repository itself contains no "CVS state"
+ (as opposed to RCS revision histories) outside the CVSROOT
+ directory.
+
+ But using raw RCS commands to change branches, tags or other
+ things that CVS depends on may render the files unusable.
+
+ See 4D.7 on RCS/CVS sharing of the Repository and Section 3B on
+ the "admin" command.
+
+
+ 4B.15 How do I convert from SCCS to RCS?
+
+ You'll have to execute something like "sccs2rcs" (in the CVS
+ contrib directory) on every file. Then you can move the resulting
+ RCS files into the Repository as described above.
+
+
+=4B.16 How do I limit access to the Repository?
+
+ There are all sorts of ways to restrict access to Repository
+ files, none of which are hooked directly into CVS. You can:
+
+ 1. Set Unix groups and permissions. See 4B.5.
+
+ 2. Try the "setgid" trick described in 4D.16.
+
+ 3. Catch every commit using the "commitinfo" file.
+
+ 4. Try to use the RCS access control lists, though I don't
+ think CVS will handle them cleanly.
+
+ 5. Edit the source code to CVS.
+
+
+=4B.17 What are the Repository Administrator's responsibilities?
+
+ Generally, the Administrator should set "policy", create the
+ Repository and monitor its size and control files.
+
+ Some specific responsibilities include:
+
+
+ 1. Examining the Repository once in a while to clean up:
+
+ a. Trash files left by misguided developers who mistake the
+ Repository for a working directory.
+
+ b. Non-RCS files. Other than the files CVS needs in the
+ $CVSROOT/CVSROOT directory, everything in the Repository
+ should be "under" CVS.
+
+ c. Lock files (both CVS '#*' and RCS ',*' files) left around
+ after crashes.
+
+ d. Wrong permissions, groups and ownerships.
+
+ e. Locked files. (RCS locks, that is.)
+
+ f. Attic files that should never have been under CVS at all.
+ Don't blindly delete files from Attic directories -- they
+ were mostly put there (via the "cvs remove") for a reason.
+ Files that should be deleted are binary files (e.g. '*.o',
+ 'core', executables) that were mistakenly inserted by
+ "import -I !".
+
+ 2. Maintaining the modules file.
+
+ 3. Maintaining the other Repository control files: commitinfo,
+ loginfo, rcsinfo and editinfo files.
+
+ 4. Storing site-specific ignore patterns in the "cvsignore" file.
+
+ 5. Pruning the history file every once in a while. (Try the
+ "cln_hist.pl" script in the "contrib" directory.)
+
+ 6. Staying aware of developments on the info-cvs mailing list and
+ what is available in the FTP archive.
+
+ 7. Run "ps ax" once in a while and kill off any "update"
+ programs not running as "root". It is too easy to leave the
+ "cvs" off the front of the "cvs update" command.
+
+ 8. Executing monitor programs to check the internal consistency of
+ the Repository files. Ideas:
+
+ a. Files that have a default RCS branch that is not 1.1.1
+ (From an abuse of "admin -b".)
+
+ b. Files that have only Revisions 1.1 and 1.1.1.1, with a
+ default branch of "MAIN". (From an abuse of "admin -o".)
+
+ c. Existing branch tags and various branch consistency checks.
+
+
+
+ 4B.18 How do I move the whole Repository?
+
+ The Repository itself contains pathnames only within the files in
+ the CVSROOT directory. If helper functions in the modules file or
+ logging programs executed out of the loginfo file point into the
+ Repository, you'll have to change the pathnames to point to the
+ new Repository location.
+
+ The main change you'll have to make is to all the ./CVS/Repository
+ files in the checked-out working directories.
+
+ You have four choices:
+
+ 1. If you can avoid changing $CVSROOT by using a symbolic link or
+ mount point you don't have to do anything else.
+
+ If you must change $CVSROOT, you must also tell everyone to
+ change the CVSROOT environment variable in all running shells
+ and in their '.' files where it is set. Then pick one of the
+ other three options that follow:
+
+ 2. If all ./CVS/Repository files in all working directories
+ contain relative pathnames, you don't have to do anything else.
+
+ 3. Have everyone "release" or delete their working directories
+ (after committing, or just saving, their work) and check them
+ all out again from the new Repository after the move.
+
+ 4. Use a PERL or shell script to run through all the
+ ./CVS/Repository files and edit the values in the files.
+
+
++4B.19 How do I change permissions on a file in the Repository by using
+ a CVS command? (i.e. without using "chmod 777 $CVSROOT/dir/file")
+
+ When you first "import" or "add"/"commit" a file, the read and
+ execute bits on the Repository file are inherited from the
+ original source file, while the write bits on the Repository file
+ are are turned off. This is a standard RCS action.
+
+ After that, there is no way to alter the permissions on a file in
+ the Repository other than by changing the Repository file
+ directly.
+
+ Whenever you "checkout" the file or retrieve a new revision via
+ "update" (or after a "commit"), your working file is set to match
+ the permissions of the Repository file, minus any "umask" bits you
+ have set.
+
+
+
+----------------
+-- Section 4C -- Branching
+----------------
+
+ **** Questions:
+
+ 4C.1 What is a branch?
+=4C.2 Why (or when) would I want to create a branch?
+=4C.3 How do I create and checkout a branch?
+ 4C.4 Once created, how do I manage a branch?
+ 4C.5 Are there any extra issues in managing multiple branches?
+ 4C.6 How do I merge a whole branch back into the trunk?
+ 4C.7 How do I merge changes from the trunk into my branch or between
+ branches?
+ 4C.8 How do I add a new file to a branch?
+=4C.9 How do I know what branch I'm (working) on?
+ 4C.10 Do I really have to know the name of the branch I'm working on?
+ 4C.11 How do I refer to the revision where I branched so I can see
+ what changed since the Branch Point on another branch?
+ 4C.12 Why didn't the command "cvs admin -bBRANCH1 *" create a branch?
+ 4C.13 Is it possible to set the "default CVS branch" for everyone?
+=4C.14 How do I perform a large merge?
+ 4C.15 Is a Vendor merge any different from a branch merge?
++4C.16 How do I go back to a previous version of the code on a branch?
++4C.17 Why do I get the latest files on the branch when I tried to
+ "update -r <tag>"?
+
+
+ **** Answers:
+
+ 4C.1 What is a branch?
+
+ Unfortunately, the word "branch" is an overloaded technical term.
+ It is used in too many different ways in three categories. It
+ might help to understand some of the issues by going through
+ the categories:
+
+ 1. How Humans use the word "branch":
+
+ Most development starts with everyone working on the same
+ software, making changes and heading toward a single goal.
+ This is called something like "Main Line Development". Note
+ that though many people do main line development on CVS's
+ "Main Branch", that is a choice, not a requirement.
+
+ After a release or when one or more developers want to go off
+ and work on some project for a while, the Software Engineers
+ assigned to deal with large software issues generate a "Branch
+ in Development" to support the release or project. (Keep in
+ mind that a programmer is no more a Software Engineer than a
+ carpenter is a Civil Engineer.)
+
+ Essentially, the word "branch" implies a way to allow
+ simultaneous development on the same files by multiple people.
+
+ The above terms are human-oriented. They refer to actions
+ that people would like to take. They do *not* imply any
+ particular implementation or set of procedures. Branches in
+ development can be supported in many different ways.
+
+
+ 2. How CVS uses the word "branch":
+
+ CVS uses the word "branch" in a number of ways. The two most
+ important are:
+
+ - The vendor branch holds releases from (normally) an
+ outside software vendor. It is implemented using a
+ specific RCS branch (i.e. 1.1.1).
+
+ - The "Main Branch", which normally holds your "Main Line
+ Development", but is defined as the collection of
+ revisions you get when you "checkout" something fresh, or
+ when you use the '-A' option to "update".
+
+ Important Note: The CVS "Main Branch" is *not* the same as
+ the RCS concept with the same name. If you are using Vendor
+ Branches, files you have never changed are on three branches at
+ the same time:
+
+ - The RCS 1.1.1 branch.
+ - The CVS Vendor branch.
+ - The CVS "Main Branch".
+
+ The concepts overlap, but they are not equivalent.
+
+ In referring to CVS, "branch" can be used in four other ways:
+
+ - A CVS working directory satisfies the definition of
+ "branch" for a single developer -- you are on a "virtual
+ branch" that does not appear in any of the RCS files or
+ the CVS control files.
+
+ - The CVS "default branch" is the Repository source for the
+ collection of files in your working directory. It is
+ *not* the same as the RCS "default branch". Normally the
+ CVS default branch is the same as the CVS Main branch. If
+ you use the "-r <branch_tag>" option to the "checkout"
+ command, you will record a "sticky" tag that changes your
+ default branch to the one you checked out.
+
+ - A "magic" branch can be a branch that hasn't happened
+ yet. It is implemented by a special tag you can check out
+ that is not attached to a real RCS branch. When you
+ commit a file to a magic branch, the branch becomes real
+ (i.e. a physical RCS branch).
+
+ - And, of course, CVS uses "branch" to indicate a
+ human-oriented "branch in development".
+
+ 3. How RCS uses the word "branch":
+
+ - The RCS "Main Branch" (Synonym: "The Trunk") contains a
+ series of two-part revision numbers separated by a single '.'
+ (e.g. 1.2). It is treated specially and is the initial
+ default branch. (The default default?)
+
+ - The RCS "Default" branch starts out attached to the RCS "Main
+ Branch". For RCS purposes, it can be changed to point to any
+ branch. Within CVS, you *must*not* alter the RCS default
+ branch. It is used to support the CVS idea of a "Main
+ Branch" and it must either point to the RCS Main Branch, or
+ the Vendor Branch (1.1.1) if you haven't made any changes to
+ the file since you executed "import".
+
+
+=4C.2 Why (or when) would I want to create a branch?
+
+ Remember that you can think of your working directory as a
+ "branch for one". You can consider yourself to be on a branch
+ all the time because you can work without interfering with others
+ until your project (big or small) is done.
+
+ The four major situations when should create a branch are when:
+
+ 1. You expect to take a long enough time or make a large enough
+ set of changes that the merging process will be difficult.
+
+ 2. You want to be able to "commit" and "tag" your work
+ repeatedly without affecting others.
+
+ If you ever think you need Source Control for your own work,
+ but don't want your changes to affect others, create a private
+ branch. (Put your username in the branch tag, to make it
+ obvious that it is private.)
+
+ 3. You need to share code among a group of developers, but not the
+ whole development organization working on the files.
+
+ Rather than trying to share a working directory, you can move
+ onto a branch and share your work with others by "committing"
+ your work onto the branch. Developers not working on the
+ branch won't see your work unless they switch to your branch or
+ explicitly merge your branch into theirs.
+
+ 4. You need to make minor changes to a released system.
+
+ Normally a "release" is labeled by a branch tag, allowing later
+ work on the released files. If the release is labeled by a
+ non-branch tag, it is easy to add a branch tag to a previously
+ tagged module with the "rtag" command. If the release is not
+ tagged, you made a mistake. Recovery requires identifying all
+ revisions involved in the release and adding a tag to them.
+
+
+=4C.3 How do I create and checkout a branch?
+
+ Suggested short form:
+
+ 1. Attach a non-branch tag to all the revisions you want to
+ branch from. (i.e. the branch point revisions)
+
+ 2. When you decide you really need a branch, attach a branch tag
+ to the same revisions marked by the non-branch tag.
+
+ 3. "Checkout" or move your working directory to the branch.
+
+
+ Suggested short form using modules:
+
+ A1. cvs rtag <branch_point_tag> module
+ A2. cvs rtag -b -r <branch_point_tag> <branch_tag> module
+ A3. cvs checkout -r <branch_tag> module
+
+
+ Suggested short form using your working directory, which contains
+ the revisions of your working files you want to branch from:
+
+ B1. cvs tag <branch_point_tag>
+ B2. cvs rtag -b -r <branch_point_tag> <branch_tag> module
+ B3. cvs update -r <branch_tag>
+
+
+ The <branch_tag> is an unusual creature. It labels a branch in a
+ way that allows you to "checkout" the branch, to "commit" files to
+ the end of the branch and to refer to the end of the branch. It
+ does not label the base of the branch (the branch point).
+
+ Step #1 applies a non-branch tag to all the branch point revisions
+ in the module/directory. Though this is not strictly necessary,
+ if you don't add a non-branch tag to the revisions you branch
+ from, you won't be able to refer to the branch point in the
+ future.
+
+ Between steps 1 & 2 you may commit files and the result is the
+ same because "rtag -r <oldtag> <newtag>" applies <newtag> to the
+ same revision that <oldtag> is attached to. You can use this
+ technique to avoid attaching *any* branch tags until you need
+ them.
+
+ Step B2 has two important corollaries:
+
+ 1. If you plan to create the branch tag before committing
+ anything in your working directory, you can use "cvs tag
+ -b <branch_tag>" instead of the "rtag" command.
+
+ 2. If you have trouble figuring out what "module" to use,
+ remember that "module" can also mean "relative path within
+ the Repository." If that doesn't help, you can aim it at
+ whatever parent directories you believe will cover all
+ your files. You can even aim it at the whole Repository
+ ($CVSROOT), if you have to. It might take some extra
+ time, but assuming that your Tag is a unique string and
+ you don't use the '-f' option to "rtag -r", "rtag" will
+ only add a Tag to files in which it actually *finds* the
+ earlier Tag.
+
+
+ Step 3 may occur any time after step 2. Unless you explicitly
+ remove them with "tag -d", the Tags are permanent.
+
+
+ There are two obvious ways of to choose the <branch_point_tag> and
+ <branch_tag> names. Since the <branch_tag> is typed by any
+ developer who wants to work on the branch, you should make it mean
+ something to them.
+
+ Style #1 presumes that the simple version string refers to a set
+ of designed, documented or promised features, not to a specific
+ set of files. In this case, you tag the branch with the generic
+ Version string and assume that whenever you refer to "Version",
+ you want the "latest" set of files associated with that Version,
+ including all patches. (You can substitute what ever you like for
+ "bp_", as long as your <branch_point_tag> is some modification of
+ the <branch_tag>.)
+
+ <branch_point_tag> Matching <branch_tag>
+
+ bp_V1_3 V1_3
+ bp_Release2-3-5 Release2-3-5
+ bp_Production4_5 Release4_5
+
+
+ Style #2 presumes that the simple version string refers to the
+ specific set of files used to construct the first release of
+ "version". In this case, you tag the branch-point revisions with
+ the generic Version string and assume that whenever you refer to
+ this Version, you want the original set of released revisions. To
+ get the latest patched revisions of the release, you refer to the
+ branch tag "latest_<branch_point_tag>". (You can substitute what
+ ever you like for "latest_", as long as your <branch_tag> is some
+ modification of the <branch_point_tag>.)
+
+ <branch_point_tag> Matching <branch_tag>
+
+ V1_3 latest_V1_3
+ Release2-3-5 latest_Release2-3-5
+ Release4_5 latest_Production4_5
+
+
+ In both styles you can find out what you had to change since the
+ original release of this Version by typing:
+
+ cvs diff -r <branch_point_tag> -r <branch_tag>
+
+ For Style 1, this is:
+
+ cvs diff -r bp_<branch_tag> -r <branch_tag>
+
+ For Style 2, this is:
+
+ cvs diff -r <branch_point_tag> -r latest_<branch_point_tag>
+
+
+ Notes:
+
+ - The "-r <tag>" option tells CVS to attach a "sticky tag" to
+ working directory (in ./CVS/Tag) and the checked-out files (on
+ each line of ./CVS/Entries).
+
+ - A "sticky" <tag> (including a <branch_tag>) causes most CVS
+ commands to act as if "-r <tag>" were on the command line.
+
+ - A "sticky" <branch_tag> indicates that the working directory
+ (and working files) are "on the branch".
+
+
+ 4C.4 Once created, how do I manage a branch?
+
+ The most important thing you should know about managing a branch
+ is that the creation of a branch is not a lightweight act. When
+ you create a branch, you must also create a set of procedures to
+ keep track of it.
+
+ Specifically, you must:
+
+ - Remember that the branch exists. (This is non-trivial if you
+ create a lot of them.)
+
+ - Plan when to merge it back into the main line of development.
+
+ - Schedule the order that multiple branch merges are to be done.
+
+ - If you ever intend to merge branches into each other, instead of
+ limiting merges of branch work back into the "main line", you
+ must keep careful track of which parts of which branches have
+ merged into which other branches.
+
+
+ The simplest way to deal with branches is to limit their number,
+ "collapse" them back into the main line as quickly as is
+ reasonable and forget them. If a group wants to continue working,
+ tell them to create another branch off the fully merged main line.
+
+ Remember that CVS is just a tool. Over time, it will probably
+ handle branching better, requiring less careful attendance.
+ But no matter how good it becomes, the whole idea of "branching"
+ is a complicated management problem. Don't take it lightly.
+
+
+ 4C.5 Are there any extra issues in managing multiple branches?
+
+ If you plan to split from the "main line" and merge back after a
+ time, the only problem will be scheduling the order of branch
+ merges. As each branch is merged, the main line must be rebuilt
+ and tested. Merging multiple branches (i.e. "lines of
+ development") before building and testing creates more problems
+ than you are ready for.
+
+ If you plan to collapse some branches into others, then move the
+ combined branches back into the main line, you have to be careful
+ with the revisions and tags you hand to your "update -j"
+ command, but it shouldn't be much trouble.
+
+ If you plan to allow every branch to incrementally take the work
+ done on other branches, you are creating an almost insurmountable
+ bookkeeping problem. Every developer will say "Hey, I can
+ handle taking just this little bit," but for the system as a
+ whole it is disaster. Try it once and see. If you are forced
+ into this situation, you will need to keep track of the beginning
+ and end points of every merge ever done. Good Luck.
+
+
+ 4C.6 How do I merge a whole branch back into the trunk?
+
+ If you don't have a working directory, you can checkout and merge
+ in one command:
+
+ cvs checkout -j <branch_tag> <module>
+ cd <module>
+
+ If you already have a working directory:
+
+ cd <working_directory>
+ cvs update <== Optional, to bring it up to date.
+ cvs update -j <branch_tag>
+
+ CVS will print lines beginning with
+
+ 'U' for files that you hadn't changed, but the branch did.
+
+ 'M' for files that you changed and the branch didn't
+ *and* for files that you both changed that were merged
+ without overlaps. (This overload is unfortunate.)
+
+ 'C' for files that you both changed in a way that conflicts
+ with each other.
+
+ You need to go edit all the 'C' files and clean up the conflicts.
+ Then you must commit them.
+
+
+ 4C.7 How do I merge changes from the trunk into my branch or between
+ branches?
+
+ The idea is similar to the above, but since CVS doesn't treat the
+ main branch like other branches, you'll have to be more precise.
+
+ Check out or "update" the files you want to merge into.
+
+ Identify the two tags on the branch you want to merge from.
+ (Revisions don't work too well because the same revision doesn't
+ mean the same thing in different files.) Then type:
+
+ cvs update -j <tag1> -j <tag2>
+
+ You can use a <branch_tag> to refer to the latest revision on the
+ branch, but there is no built-in way to refer to the branch point.
+
+
+ An alternative to merging is to identify a single revision you
+ want, grab it by using "update -p" and commit it. If you do
+ merges later, you'll get overlaps, but you get your file.
+
+
+ In the future, (but not yet) merging from the main branch will
+ look something like this:
+
+ cvs update -j MAIN
+ cvs commit -m "Log message"
+
+
+ 4C.8 How do I add a new file to a branch?
+
+ The obvious technique is broken in CVS 1.3. This is the way it is
+ supposed to work:
+
+ You are in a directory checked out (or updated) with the "-r
+ <branch_tag>" option. To add <file> to the branch named
+ <branch_tag> you type:
+
+ cvs add <file>
+ cvs commit <file>
+
+
+ Until the next release appears, you must explicitly specify the
+ branch_tag:
+
+ cvs add <file>
+ cvs commit -r <branch_tag> <file>
+
+ One not so obvious side-effect is that the file ends up in the
+ Attic. It wasn't added to the Main Branch so it doesn't show up
+ in the main part of the Repository, only in the Attic.
+
+ You can add it to the Main Branch and branch off from there onto
+ the side-branch this way:
+
+ 1. Move the working file back to the main branch:
+
+ cvs update -A <file>
+
+ 2. Add the file "normally":
+
+ cvs add <file>
+ cvs commit <file>
+
+ 3. Branch-tag the file using the same <branch_tag> as you did on
+ all the other files in your directory:
+
+ cvs tag -b <branch_tag> <file>
+
+ 4. And move the file back onto the branch:
+
+ cvs update -r <branch_tag> <file>
+
+
+=4C.9 How do I know what branch I'm (working) on?
+
+ Type:
+ cvs status
+
+ and look at the "Sticky Tag" field for each file. If:
+
+ 1. The *same* tag is on *every* file in your working tree, *and*
+ 2. That tag matches the contents of the ./CVS/Tag file, *and*
+ 3. That tag is a branch tag,
+
+ then you know what branch you are working on. You can get sticky
+ Tag information directly from the ./CVS/Entries file instead of
+ "cvs status".
+
+ If all the sticky Tags don't agree, then your directory is
+ temporarily inconsistent. This is a feature allowing you to make
+ changes (or perform merges) to individual files on multiple
+ branches without checking out the whole directory.
+
+ The sticky Tag on each file in the ./CVS/Entries file (as
+ displayed by the "status" command) indicates what branch the
+ working file is on. New files should be added to the Tag stored
+ in ./CVS/Tag, but they are not. See the above question on adding
+ a new file to a branch.
+
+ To force your entire working directory onto the same branch, type:
+
+ cvs update -r <branch_tag>
+
+
+ 4C.10 Do I really have to know the name of the branch I'm working on?
+
+ If a developer can't be relied on to know what branch of
+ development to work on, then either the developer's manager
+ isn't planning branches properly or the developer has serious
+ problems.
+
+ I have found that one of the hardest concepts to get across to
+ developers (and some managers) is that "a branch in development"
+ (as opposed to the use of RCS branches to support some other
+ scheme) is a heavyweight act. Every time you create a real branch
+ in development, you must spawn a set of managerial procedures and
+ a schedule by which you plan to merge each branch into each other
+ branch. Unless you plan to keep it simple and collapse (by
+ merging and forgetting) branches quickly, they are not to be
+ created lightly.
+
+ In other words, if there aren't group meetings in which the branch
+ to be worked on is a major topic of discussion, then the group is
+ not managing branches properly.
+
+ We created a couple major branches a few months ago and even the
+ customer service people refer to the "XYZ branch" as a shorthand
+ for "continuing development on the XYZ project".
+
+
+ 4C.11 How do I refer to the revision where I branched so I can see
+ what changed since the Branch Point on another branch?
+
+ Given the current <branch_tag> format, there is no direct way to
+ refer to the branch point, which is more useful in many ways
+ than referring to the branch, which always refers to the latest
+ revision on the branch.
+
+ When CVS adds a branch tag, it attaches an RCS symbol to a
+ non-existent revision number containing the revision number of the
+ branch point as a prefix. (See Section 3O, on the "tag" command.)
+ RCS can't use the CVS magic branch tag and many of the CVS
+ commands can't refer to it.
+
+ To be certain of your ability to refer to a branch point, you must
+ create a "branch point" tag at the same time as the Branch tag.
+ See 4C.3.
+
+
+ 4C.12 Why didn't the command "cvs admin -bBRANCH1 *" create a branch?
+
+ Because your command creates an RCS branch, not a CVS branch. See
+ the above discussion on branches. RCS branches are used to
+ support CVS branches, but they are not the same. You can't act as
+ if you have direct control over the RCS files.
+
+ The "admin" command was placed there as a convenience to allow
+ you to execute raw "rcs" commands on the Repository, taking
+ advantage of CVS's ability to find the files in the Repository.
+
+ But you have to remember that you are using RCS commands on a
+ CVS Repository, which is not generally safe unless you know
+ exactly what CVS depends on.
+
+ For one thing, CVS insists on control of the default branch. It
+ is set either to the Main branch or the Vendor branch depending
+ on whether you have changed the Vendor's code. If you change
+ the default branch, you are monkeying with the internals and
+ you will get unexpected results.
+
+ To set your "default CVS branch" to BRANCH1, you must use
+ "checkout" or "update" with the "-r BRANCH1" option. Then you
+ have changed CVS's idea of your "default branch", which has
+ little to do with RCS's default branch.
+
+
+ 4C.13 Is it possible to set the "default CVS branch" for everyone?
+
+ No. It doesn't work that way.
+
+ When using CVS, all administrative information (such as what
+ branch you checked out) is stored in CVS sub-directories, local to
+ the user. There is no global state, other than the description
+ and logging files in $CVSROOT/CVSROOT.
+
+ You tell "checkout" or "update", via the "-r <tag>" option,
+ what branch you want to check out. The default is CVS's "Main
+ Branch".
+
+ I don't see a problem in *designing* a new way to indicate what
+ branch you get by default, instead of the main one, but that's not
+ how it currently works.
+
+
+=4C.14 How do I perform a large merge?
+
+ Large merges require a bit more planning to be able to track
+ what has happened in the inevitable cases where something goes
+ wrong. No tool can make a "merge" make perfect sense.
+
+ Though you can handle the details in many different ways, the two
+ ends of the spectrum of merge techniques are: gonzo and paranoid.
+
+ The gonzo method assumes that you know everything about your
+ sources so that recovery from failures is "just a matter of
+ typing." You created the branch this way:
+
+ cvs checkout <module>
+ cd <module>
+ cvs tag -b <branch_tag>
+ cvs update -r <branch_tag>
+ >>> Edit away.
+ cvs commit <<== Onto branch
+
+ Now you want to merge your branch back into the Main branch, you
+ are certain you can make it work, or at least detect all the
+ failures, so you dive in and hack away: (For simplicity, we will
+ assume you are collapsing (i.e. merging and forgetting) a
+ side-branch into the Main branch from your single working
+ directory.)
+
+ cvs update -A
+ cvs update -j <branch_tag>
+ >>> Edit the 'C' files and remove the overlaps.
+ >>> Edit some more to make it all compile and work.
+ cvs commit
+
+ Looks simple. For more details on the output from the
+ "update -j" command, see 3P.2 and 4C.6.
+
+ (Note: You could also checkout a whole new working directory and
+ perform the merge at the same time by replacing the two update
+ commands with "cvs checkout -j <branch_tag> <module>".
+
+
+ The paranoid way is more difficult, but it can catch all sorts of
+ problems. You created the branch this way:
+
+ cvs checkout <module>
+ cd <module>
+ cvs tag <branch_point_tag>
+ cvs tag -b <branch_tag>
+ cvs update -r <branch_tag>
+ >>> Edit away.
+ cvs commit <<== Onto branch
+
+ The extra tag command places a non-magic tag on the Branch Point,
+ an act that makes it easier to do "diffs" later. Now we decide
+ to perform the merge:
+
+ cvs tag <latest_on_branch_tag>
+ cvs update -A
+ *1* cvs diff -r <branch_point_tag> -r <latest_on_branch_tag>
+ >>> *1* holds all the changes on the branch.
+ *2* cvs diff -r <branch_point_tag> -r HEAD
+ >>> *2* holds the changes on the trunk since branching.
+ cvs tag <premerge_tag>
+ cvs update -j <branch_tag>
+ >>> Edit the 'C' files and remove the overlaps.
+ *3* cvs diff
+ >>> Verify that *3* matches *1*, except for line numbers
+ and overlaps.
+ cvs commit
+ cvs tag <just_merge_changes_tag>
+ >>> Edit some more to make it all compile and work.
+ cvs commit
+ cvs tag <after_merge_cleanup_tag>
+
+
+ The reason *3* and *1* match so closely is that they are the
+ differences between two pairs of starting points and ending points
+ after the same data was inserted. If they are significantly
+ different, you will want to figure out why.
+
+ NOTE: You will have to tell everyone to stay the hell out of the
+ Repository while you do this. If they commit something while you
+ are in the middle of a merge, your job will be much more
+ difficult. If they "update" at the wrong time, their work will
+ be randomized until you finish. It's better to call a halt.
+
+
+ 4C.15 Is a Vendor merge any different from a branch merge?
+
+ No. In most ways, a Vendor branch is exactly the same as any
+ other branch. In a Vendor merge, the data is append to the branch
+ by the "import" command, rather than by hand-editing, but the
+ merge process is the same.
+
+ See the "import" command in section 3H.
+
+
++4C.16 How do I go back to a previous version of the code on a branch?
+
+ You can avoid digging into RCS revision numbers (executing "update
+ -r <rev>" on each file) by trying one of these:
+
+ 1. Use non-branch tags as you normally would. Non-branch tags
+ attach to specific revisions, so a "tag <tag>" command would
+ mark the revisions you have in your working directory, which
+ are on your branch. If you need to retrieve them, use "update
+ -r <non-branch-tag>"
+
+ Doing this overrides the sticky <branch_tag> attached to your
+ working directory with a non-branch tag, which means you won't
+ be able to commit until you again move forward to the end of
+ the branch with "update -r <branch_tag>".
+
+ 2. Use the "update -r <branch_tag>:<date>" trick.
+
+ This is almost like using the '-D' option, but it looks for
+ revisions extant on <date> only along the given branch.
+
+ As in #1, you can't commit to this kind of working area,
+ because it has a sticky date referring to revisions in the
+ middle of a branch.
+
+
+ 3. You can branch a branch.
+
+ If you add a branch tag to file in a working directory that was
+ checked out on a branch, you will branch the branch. This
+ works just fine, though you'll have to play some games to merge
+ everything back together again. You'll also create 6-part
+ revision numbers. (They'll be 8-part revision numbers if you
+ branch a branch that started out with some unmodified files the
+ Vendor branch. Think about it. How does revision
+ 1.2.4.2.4.2.2.1 grab you?)
+
+
++4C.17 Why do I get the latest files on the branch when I tried to
+ "update -r <tag>"?
+
+ If "update -r <tag>" always retrieves the latest files on a
+ branch, then <tag> is a branch tag. A branch tag is supposed to
+ be used to grab a branch to work on. Since you can't modify a
+ file in the middle of a branch, checking out a <branch_tag> will
+ give you the latest revision on the branch.
+
+ If you want to "checkout" a specific collection of revisions, you
+ must use a "non-branch" tag. See the first part of 4C.16.
+
+ You *can* branch off a branch, but it is rarely needed.
+
+
+
+----------------
+-- Section 4D -- Tricks of the Trade
+----------------
+
+This section covers topics ranging from simple ideas that occur to every
+CVS user to time-saving procedures I consider difficult to understand.
+
+Some are therefore dangerous. Avoid anything you don't fully understand.
+
+
+ **** Questions:
+
+=4D.1 How can you even check in binary files, let alone allow CVS to
+ do its auto-merge trick on them?
+ 4D.2 Can I edit the RCS (",v") files in the Repository?
+ 4D.3 Can I edit the ./CVS/{Entries,Repository,Tag} files?
+=4D.4 Someone executed "admin -o" and removed revisions to which
+ tags/symbols were attached. How do I fix them?
+=4D.5 How do I move a magic branch tag?
+ 4D.6 Can I use RCS locally to record my changes without making them
+ globally visible by committing them?
+ 4D.7 How can I allow access to the Repository by both CVS and RCS?
+=4D.8 I "updated" a file my friend "bubba" committed yesterday.
+ Why doesn't the file now have a modified date of yesterday?
+#4D.9 While in the middle of a large "commit", how do I run other
+ commands, like "diff" or "stat" without seeing lock errors?
+ 4D.10 Why does the merge occasionally resurrect lines of code?
+=4D.11 Why does the merge fail when my "rcsmerge" program is
+ configured to use GNU diff version 2.1 or later?
+ 4D.12 What the hell is Entries.Static?
+=4D.13 Why did I get the wrong Repository in the loginfo message?
+=4D.14 Can I have multiple source repositories, one for each project?
+ 4D.15 How do I run CVS setuid so I can only allow access through the
+ CVS program itself?
+ 4D.16 How about using groups and setgid() then?
+ 4D.17 How do I use the "commitinfo" file?
+ 4D.18 How do I use the "loginfo" files?
+
+
+ **** Answers:
+
+=4D.1 How can you even check in binary files, let alone allow CVS to
+ do its auto-merge trick on them?
+
+ If you configure RCS and CVS to use the GNU version of diff with
+ the '-a' option, CVS and RCS will handle binary files. See
+ section 4A for configuration info.
+
+ You also need to apply the '-ko' flag to the files to avoid
+ expanding RCS keywords, which can be done via:
+
+ cvs admin -ko filename
+
+ (You should be able to do it by handing "import" the -ko option,
+ but that isn't yet in the official release.)
+
+ The only real problem occurs when "cvs update" attempts to merge
+ binary revisions committed elsewhere into a modified working file.
+ This can be a particular problem if you are trying to use CVS on
+ Frame or Interleaf (document processing systems) that produce
+ non-text output.
+
+ [[I know of no solution to this other than to keep binaries in
+ some text form as "source" (real binaries could be uuencoded,
+ documents could be stored in "exported" (something like SGML)
+ form.]]
+
+
+ 4D.2 Can I edit the RCS (",v") files in the Repository?
+
+ Yes, but be very careful. The RCS files are not free-form files,
+ they have a structure that is easily broken by hand-editing. The
+ only time I would suggest doing this is to recover from emergency
+ failures that are difficult to deal with using CVS commands,
+ including the "admin" command, which can talk directly to RCS.
+
+ Though no one actively encourages the editing of RCS files, many
+ people have succumbed to the urge to do so when pressed for time.
+ The reasons given, usually with evident contrition, include:
+
+ - Editing mistakes in, or adding text to, log entries. (If you
+ have RCS 5.6 or later, you should use `cvs admin -m'.)
+ - Renaming or moving symbolic names. (You should `cvs admin -N'
+ instead.)
+ - Unlocking a file by changing the "locker" from someone else to
+ yourself. (It's safer to use `cvs admin -u -l'.)
+ - Making global changes to past history. Example: Eradicating
+ former employees names from old documents and Author entries.
+ (And someone thought the "history" command was evidence of Big
+ Brother! I had never realized how much help CVS/RCS could have
+ provided to The Ministry of Truth.)
+
+
+ 4D.3 Can I edit the ./CVS/{Entries,Repository,Tag} files?
+
+ Yes, but with CVS 1.3 and later, there is almost no reason to edit
+ any of the CVS administrative files.
+
+ If you move pieces of your Repository around it can be faster to
+ edit all the ./CVS/Repository files rather than checking out a
+ large tree. But that is nearly the only reason to do so.
+
+
+=4D.4 Someone executed "admin -o" and removed revisions to which
+ tags/symbols were attached. How do I fix them?
+
+ It depends on what you mean by "fix". I can think of three ways
+ to fix your predicament:
+
+
+ 1. Remove the tags.
+
+ Assuming you really wanted to get rid of the revision and its
+ associated tags, you can remove them with the "admin" command.
+ The "tag -d" command will only remove tags attached to existing
+ revisions. You can remove a tag, even if it is attached to a
+ non-existent filename, by typing:
+
+ cvs admin -N<tag> <file>
+
+ 2. Retrieve the outdated revision.
+
+ Using CVS and RCS, there is no way to reconstruct an outdated
+ revision. You will have to resort to backups.
+
+ 3. Move the Tags to another revision in each file.
+
+ If you want to move the tags to another valid revision, you
+ have two choices, both of which require that you find all the
+ revision numbers of the files you want to "tag" and execute the
+ following command sequences on each <file>.
+
+ a. Use "update" to grab the revision you want, then
+ execute a normal "tag" command to Tag that revision:
+
+ cvs update -r <rev> <file>
+ cvs tag <tag> <file>
+
+ b. Use "admin" to set the tag to a specific revision:
+
+ cvs admin -N<tag>:<rev> <file>
+
+
+=4D.5 How do I move a magic branch tag?
+
+ If the <branch_tag> refers to a physical branch within an RCS
+ file, renaming a tag will make the existing branch in the file
+ seem to disappear. This is not a good idea.
+
+ If the magic branch has never had a revision committed to it, you
+ can move the branch by re-executing the "tag" or "rtag" command
+ that created it. The <branch_tag> will be moved to the place
+ where it would have appeared if you were tagging the file for the
+ first time.
+
+
+ 4D.6 Can I use RCS locally to record my changes without making them
+ globally visible by committing them?
+
+ You can, but it will probably confuse CVS to have ",v" files in
+ your working directory. And you will lose all your log entries
+ when you finally commit it.
+
+ Your best bet is to create your own CVS branch and work there.
+ You can commit as many revisions as you want, then merge it back
+ into the main line when you are finished.
+
+
+ 4D.7 How can I allow access to the Repository by both CVS and RCS?
+
+ The first step is to try not to. If some people are using CVS,
+ there is no reason for everyone not to. It is not hard to learn
+ the basics and CVS makes certain operations *easier* than a series
+ of RCS commands. Personal preference in what software tools can
+ be applied to a shared Repository has to take second place to
+ system integration needs. If you disagree, try writing some Lisp
+ code for inclusion in your Unix kernel and see what kind of
+ reception you get.
+
+ If you really must allow routine RCS access to the CVS Repository,
+ you can link an RCS sub-directory into a piece of the Repository:
+
+ ln -s /Repository/some/directory/I/want RCS
+
+ and RCS will work just fine.
+
+
+ Those who are using RCS will have to keep the following in mind:
+
+ 1. If a file was originally added to the Repository by "import"
+ and has not been changed using CVS, the *RCS* default branch
+ will remain attached to the Vendor branch, causing revisions
+ checked-in by "ci" to wind up on the Vendor branch, instead of
+ the main branch. Only CVS moves the RCS default branch on
+ first commit.
+
+ The way around this is to checkin (using "ci") all the files
+ first and move them into the Repository. That way they won't
+ have Vendor branches. Then RCS will work OK.
+
+ 2. It is possible to use "rcs" and "ci" to make the files unusable
+ by CVS. The same is true of the CVS "admin" command.
+
+ 3. Normal RCS practice locks a file on checkout with "co -l". In
+ such an environment, RCS users should plan to keep survival
+ gear and food for at least 30 days near their desks. When
+ faced with bizarre and unexpected permission errors, howling
+ mobs of slavering CVS users will run the RCS users out of town
+ with pitchforks and machetes.
+
+ 4. Though files checked in by RCS users will correctly cause
+ "up-to-date" failures during CVS "commits" and they will be
+ auto-merged into CVS working directories during "update", the
+ opposite won't happen.
+
+ RCS users will get no warning and will not be required to merge
+ older work into their code. They can easily checkin an old
+ file on top of a new revision added by CVS, discarding work.
+
+ See the howling mob scenario described above.
+
+
+ RCS is great. I have used it for years. But I wouldn't mix it
+ this way. In a two-camp society, you are asking for real trouble,
+ both in technical hassles to clean up and in political hassles to
+ soothe.
+
+
+=4D.8 I "updated" a file my friend "bubba" committed yesterday.
+ Why doesn't the file now have a modified date of yesterday?
+
+ CVS restores dates from the RCS files only on first "checkout".
+ After that, it is more important to maintain a timestamp relative
+ to the other files in the working directory.
+
+ Example: I commit a source file at 5PM. You commit the same file
+ at 6PM. At 7PM, I compile my file. Then I execute "update". If
+ CVS sets the date to the one in the RCS file, the file would be
+ given a timestamp of 6PM and my Makefile wouldn't rebuild anything
+ that depended on it. Bad news.
+
+ Note that the same logic applies to retrieving a revision out of
+ the repository to replace a deleted file. If CVS changes your
+ file in an existing working directory, whether it was because a
+ new revision was committed by someone else or because you deleted
+ your working file, the timestamp on the retrieved working file
+ *must* be set to the current time.
+
+ When you first retrieve a file, there is no reason to expect any
+ particular timestamp on the file within your working area. But
+ later, when dependency checking is performed during a build, it is
+ more important for the timestamps on the local files to be
+ consistent with each other than than it is for working files to
+ match the timestamps on the files in the Repository.
+
+
+#4D.9 While in the middle of a large "commit", how do I run other
+ commands, like "diff" or "stat" without seeing lock errors?
+
+ Type:
+ cvs -n <command>
+
+
+ The '-n' option to the main cvs command turns off lock checking, a
+ reasonable act given the promise offered by '-n' not to alter
+ anything. The "diff", "log" and "stat" commands all provide the
+ same information with and without the '-n' option.
+
+ Warning: Ignoring locks can produce inconsistent information
+ across a collection of files if you are looking at the revisions
+ affected by an active commit. Be careful when creating "patches"
+ from the output of "cvs -n diff". If you are looking only at your
+ working files, tagged revisions, and BASE revisions (revisions
+ whose numbers are read from your CVS/Entries files), you should
+ get consistent results. Of course, if you catch a single file in
+ the middle of RCS activity, you might get some strange errors.
+
+ Note that this is "cvs -n <command>". The visually similar
+ command "cvs <command> -n" has no relation to the former usage and
+ has an entirely different meaning for each command.
+
+ "cvs -n update" also works in the middle of a commit, providing
+ slightly different information from a plain "cvs update". But, of
+ course, it also avoids modifying anything.
+
+ You could also use the RCS functions, "rlog" and "rcsdiff" to
+ display some of the information by referring directly to the
+ Repository files.
+
+ You need RCS version 5 or later for the commands described above
+ to work entirely reliably.
+
+
+ 4D.10 Why does the merge occasionally resurrect lines of code?
+
+ The diff3 program provided by GNU diff version 1.15 has a bug
+ that occasionally causes text to come back from the dead.
+
+ If you plan to upgrade to the latest GNU diff program, see the
+ next question.
+
+
+=4D.11 Why does the merge fail when my "rcsmerge" program is
+ configured to use GNU diff version 2.1 or later?
+
+ A change in the overlap format was introduced in GNU diff3
+ between versions 2.0 and 2.1.
+
+ To get consistent rcsmerge behavior, you have four choices:
+
+ 1. Go back to using GNU diff 1.15 or 2.0. If you want to use
+ GNU diff 2.1 or later, you'll have to pick one of the other
+ three choices in this list.
+
+ 2. Grab RCS version 5.6.0.1 from an FSF archive and set the
+ DIFF3_A macro to '1' as it tells you to in the Makefile:
+
+ #define DIFF3_A 1
+
+ 3. Patch the RCS 5.6 source. Change line 84 in "merger.c" from:
+
+ DIFF3, "-am", "-L", label[0], "-L", label[1],
+ to
+ DIFF3, "-amE", "-L", label[0], "-L", "", "-L", label[1],
+
+ 4. Wait both for RCS version 5.7 to be released and for a new
+ version of CVS that can deal with it.
+
+
+ 4D.12 What the hell is Entries.Static?
+
+ Each ./CVS administrative directory contains an Entries file,
+ listing the files under CVS in the directory above it. If a new
+ file is added to the Repository, an "update" command copies it
+ out of the Repository and adds it to the Entries file.
+
+ If your ./CVS directory has an Entries.Static file in it, CVS
+ checks it before bringing new files out of the Repository. If a
+ new file is *not* in Entries.Static, it is not checked out.
+
+ The Entries.Static file is created by checking out something that
+ doesn't include all files in a directory. Without an
+ Entries.Static file, the first "update" would bring more files
+ out of the Repository.
+
+ Examples:
+
+ - A multi-module checkout renamed with the "checkout -d" option.
+
+ - Checking out a module specified with directory and filenames.
+
+ The Entries.Static file is removed by an "update" with the
+ '-A', '-r' or '-D' option.
+
+
+=4D.13 Why did I get the wrong Repository in the loginfo message?
+
+ You probably:
+
+ - Use multiple Repositories.
+
+ - Configured CVS to use absolute pathnames in the
+ ./CVS/Repository file.
+
+ - Typed the "commit" command in one Repository with your
+ $CVSROOT pointing at the other.
+
+
+ "commit" and all other CVS commands will heed an absolute pathname
+ in the ./CVS/Repository file (or in the "-d CVSrootdir" override),
+ but the log function doesn't take arguments -- it just looks at
+ $CVSROOT.
+
+
+=4D.14 Can I have multiple source repositories, one for each project?
+
+ Yes, you can have as many Repositories as you like. But each
+ Repository must be managed separately, creating additional work.
+
+ Question 4A.1 provides a short description of setting up a
+ single Repository. A few additional considerations:
+
+ 1. It is a good idea to start by creating a single Repository and
+ split it up (or create additional Repositories) only if you
+ believe it is really necessary. I would only create a new
+ Repository if the data is completely disconnected from the rest
+ of the main Repository.
+
+ 2. If there is a lot of overlap among the developers working on
+ the collections of files you want to place in different
+ Repositories, or if there is any connection between those
+ collections, I would go out of my way to create a single
+ Repository. It is much easier to manage.
+
+ 3. Disk space should not be a factor since you can build up a
+ Repository using symbolic links and/or remote mounts.
+
+ 4. Each Repository is completely distinct. You can't check out
+ modules from different Repositories at the same time. A better
+ way of looking at it is that if you *can* check out two modules
+ or directories with a single "checkout" command (without
+ contortions or explicit absolute pathnames), then they are in
+ the same Repository.
+
+ 5. To "checkout" modules from multiple Repositories, you must use
+ the "cvs -d" option on all CVS commands or alter your $CVSROOT
+ variable when you change focus to another Repository. If you
+ work with multiple Repositories, it is a good idea to configure
+ CVS to use absolute pathnames in the ./CVS/Repository file,
+ since most commands (other than "checkout") will use that file
+ rather than $CVSROOT.
+
+ 6. If you configure CVS to use relative pathnames in your
+ ./CVS/Repository files, you must always be careful to set your
+ $CVSROOT properly or you will get unexpected results.
+
+ One monster of an unexpected result can happen when you have
+ two modules or directories by the same name at the same
+ relative path inside the Repository, in two different
+ Repositories. You can update a directory with completely
+ unrelated files. This is not a fanciful example -- a
+ Repository is occasionally duplicated for release purposes in
+ which case *all* the paths in the two Repositories are the
+ same.
+
+
+ 4D.15 How do I run CVS setuid so I can only allow access through the
+ CVS program itself?
+
+ Setuid to root is not a great idea. Any program that modifies
+ files and is used by a widely distributed group of users is not a
+ good candidate for a setuid program. (The worst suggestion I've
+ ever heard was to make *Emacs* setuid to root.)
+
+ Root access on Unix is too powerful. Also, it might not work in
+ some (secure?) environments.
+
+ Running it setuid to some user other than root might work, if you
+ add this line to main.c near the beginning:
+
+ setuid(geteuid());
+
+ Otherwise it uses *your* access rights, rather than the effective
+ uid's.
+
+ Also, you have to invent a fake user whose name will show up in
+ various places. But many sites, especially those who might want a
+ setuid CVS for "security", want personal accountability -- no
+ generic accounts. I don't know whether accountability outweighs
+ file security.
+
+ And finally, unless you take action to limit the "admin"
+ command, you are leaving yourself unprotected anyway.
+
+
+ 4D.16 How about using groups and setgid() then?
+
+ Here is a way to run CVS setgid in some environments:
+
+ 0. Stick this near the front of the main() in main.c:
+
+ setgid(getegid());
+
+ This will allow "access" to work on systems where it
+ only works on the real gid.
+
+ 1. Create a group named "cvsg", for example. Name it as you wish.
+
+ 2. Put *no* users in the "cvsg" group. You can put Repository
+ administrators in this group, if you really want to.
+
+ 3. Set the cvs executable to setgid (not setuid):
+
+ cd /usr/local/bin; chown root.cvsg cvs; chmod 2755 cvs
+
+ 4. Make sure every file in the Repository is in group "cvsg":
+
+ chown -R root.cvsg $CVSROOT
+
+ 5. Change all directory permissions to 770. This allows all
+ access to the files by the "cvsg" group (which has no members!)
+ and no access at all to anyone else.
+
+ find $CVSROOT -type d -exec chmod 2770 {} \;
+
+ This should allow only the cvs program (or other setgid to group
+ cvsg) programs to write into the area, but no one else. Yes the
+ user winds up owning the file, but s/he can't find it again later
+ since s/he can't traverse the tree. (If you allow the world
+ execute bit (octal 001) on directories, the user who last wrote
+ the file can still write to it.)
+
+ If you want to allow read access, check out an entire tree
+ somewhere. You have to do this anyway to build it.
+
+ Note: If you are using a stupid file system that can't inherit
+ file groups from the parent directory (even with the "setgid"
+ (Octal 2000) bit set), you might have to modify CVS (or RCS) to
+ reset the group every time you create a new file. I have not
+ tested this.
+
+ The setgid() method shares the "admin" problem with the
+ setuid() method.
+
+
+ 4D.17 How do I use the "commitinfo" file?
+
+ Go read 4B.2 first.
+
+ The "commitinfo" file allows you to execute "sanity check"
+ functions before allowing a commit. If the function exits with a
+ non-zero status, the commit is denied.
+
+ To fill out a "commitinfo" file, ask yourself (and those sharing
+ your Repository) these questions:
+
+ - Is there anything you want to check or change before someone is
+ allowed to commit a file? If not, forget commitinfo.
+
+ - Do you want to execute the same exact thing before committing to
+ every file in the Repository? (This is useful if you want to
+ program the restrictions yourself.) If so, set up a single line
+ in the commitinfo:
+
+ DEFAULT /absolute/path/to/program
+
+ CVS executes the program once for each directory that "commit"
+ traverses, passing as arguments the directory and the files to
+ be committed within that directory.
+
+ Write your program accordingly.
+
+ - Do you want a different kind of sanity check performed for
+ different directories? If so, you'll have to decide what to do
+ for all directories and enter lines like this:
+
+ regexp1 /absolute/path/to/program-for-regexp1
+ regexp2 /absolute/path/to/program-for-regexp2
+ DEFAULT /absolute/path/to/program-for-all-else
+
+
+ - Is there anything you want to happen before *all* commits, in
+ addition to other pattern matches? If so, include a line like
+ this:
+
+ ALL /absolute/path/to/program
+
+ It is executed independently of all the above. And it's
+ repeatable as many times as you like.
+
+
+ 4D.18 How do I use the "loginfo" files?
+
+ See 4B.2 and the "commitinfo" question above.
+
+ The "loginfo" file has the same format as the "commitinfo"
+ file, but its function is different. Where the "commitinfo"
+ information is used before a commit, the "loginfo" file is used
+ after a commit.
+
+ All the commands in the "loginfo" file should read data from
+ standard input, then either append it to a file or send a message
+ to a mailing list. If you want to make it simple, you can put
+ shell (the shell used by "popen") command lines directly in the
+ "loginfo" (or "commitinfo") file. These seem to work:
+
+ ^special /usr/ucb/Mail -s %s special-mailing-list
+ ^other /usr/ucb/Mail -s %s other-mailing-list
+ DEFAULT (echo '===='; echo %s; cat) > /path/name/to/log/file
+
+
+
+----------------
+-- Section 4E -- Weirdness
+----------------
+
+ **** Questions:
+
+ 4E.1 Explain: "ci error: unexpected EOF in diff output"
+=4E.2 Explain: "RCS file /Repository/module/file.c,v is in use"
+=4E.3 I don't want a Vendor branch. Why can't I work on the main trunk?
+ 4E.4 Merges can't work. I don't trust them. If you won't change it to
+ something I can understand, I won't use CVS.
+ 4E.5 Explain: "co error, line 2: Missing access list"
++4E.6 Explain: "error: RCS file name `xyz .c' contains white space"
++4E.7 Explain: cvs checkout: warning: <X> is not (any longer) pertinent
+
+
+ **** Answers:
+
+ 4E.1 Explain: "ci error: unexpected EOF in diff output"
+
+ RCS versions earlier than 5.5 print the above error when a file
+ does not end in a newline character. It can be caused by:
+
+ - Editing with Emacs and not using "require-final-newline".
+ - Committing a binary file.
+ - Filesystem failures (NFS!) that put nulls in your file.
+
+ The solution is to upgrade to RCS 5.5 or later. (Of course, this
+ won't fix filesystem failures. It will merely allow RCS (and
+ therefore CVS) to handle the file without error.)
+
+
+=4E.2 Explain: "RCS file /Repository/module/file.c,v is in use"
+
+ This is an RCS error that occurs when its internal lock file has
+ been left around by an RCS command interrupted by some sort of
+ system crash, disk failure or SIGKILL signal.
+
+ Go into the Repository and look for files with names similar to
+ "file.c,v", usually starting with ',', '_' or '#'. Make
+ sure they are really crash remnants and do not belong to
+ transactions in progress -- a recent last-modified timestamp
+ is a good indicator of a live transaction. Delete them.
+
+
+=4E.3 I don't want a Vendor branch. Why can't I work on the main trunk?
+
+ The Vendor branch is the way "import" deals with a Vendor
+ release. If you do it any other way, you are wasting your time.
+ CVS was designed to work this way.
+
+ If you are not working with 3rd party (i.e. Vendor) sources, you
+ can skip the "import" and either move pre-existing RCS files into
+ the Repository, or apply the RCS "ci" command to your source files
+ by hand (creating ",v" files) and move them into the Repository.
+
+
+ 4E.4 Merges can't work. I don't trust them. If you won't change it to
+ something I can understand, I won't use CVS.
+
+ Some developers have the feeling that three-way merging doesn't
+ work. They don't trust the way the "update" command
+ automatically merges committed changes from the Repository into
+ the working file.
+
+ Experience has shown that most merges are utterly painless and
+ most of the rest are easily resolved. The few conflicts that
+ cause headaches are nearly all due to poor communication between
+ developers, a problem no source control system can obliterate.
+
+ Some developers were troubled in the past by flaky Unix software.
+ I can't say that everything is perfect, but the tools CVS depends
+ on (RCS and diff, mainly) are fairly solid nowadays. They work.
+
+ Since it does seem to work for most of us, the algorithm is
+ unlikely to change soon. Why not test it on a couple trouble
+ spots and if it works for you, use it for a while? Then you can
+ make an informed decision.
+
+
+ 4E.5 Explain: "co error, line 2: Missing access list"
+
+ This is an error message from RCS Version 3 when it tries to read
+ a file created by a later version of RCS.
+
+ You should upgrade to the latest version of RCS, which is Version
+ 5.6.0.1 as I write this.
+
+
++4E.6 Explain: "error: RCS file name `xyz .c' contains white space"
+
+ RCS 5.6 doesn't allow white space in filenames. Apparently this
+ restriction will be removed in RCS 5.7, but CVS may still require
+ that filenames have no white space in them.
+
+
++4E.7 Explain: cvs checkout: warning: <X> is not (any longer) pertinent
+
+ This message occurs in two instances:
+
+ 1. When there is an entry in the ./CVS/Entries for file <X> and
+ there is no RCS file in the Repository to back it up.
+
+ If the working file exists, and hasn't changed (determined from
+ the timestamp) it is removed.
+
+
+ 2. When you try to check out a piece of the Repository with:
+
+ cvs checkout some/place/in/repository/tree
+
+ and at least the first element of the path (i.e. "some" in the
+ above) exists, but some part of the rest of it does not.
+
+ The checkout command checks the modules file first for the
+ whole path, then for a prefix of the path as a module name. If
+ it doesn't find *any* portion of your path in the modules file,
+ it says:
+
+ cvs checkout: cannot find module `<module/path>' - ignored
+
+ If it finds some set of prefix directories, it prints the
+ message you see.
+
+ In practice this is usually a spelling error.
+
+ 3. If the Repository files you are trying to check out or update
+ are not readable by you, the same problems can occur.
+ Check the permissions on the files involved.
+
+
+----------------
+-- Section 4F -- Related Software
+----------------
+
+ **** Questions:
+
++4F.1 How do I use CVS under Emacs? Is there an Emacs cvs-mode?
++4F.2 What is GIC (Graphical Interface to CVS)?
++4F.3 What is CAVEMAN?
+
+
+ **** Answers:
+
+This section covers a small handful of subsystems that connect to CVS in
+some way. Most are "front ends" in that they offer a different user
+interface to CVS, but use CVS to perform the normal tasks.
+
+ NOTE: The short summaries below combine details culled from public
+ announcements of the listed software with the personal opinions of
+ the author of the FAQ entry.
+
+
++4F.1 How do I use CVS under Emacs? Is there an Emacs cvs-mode?
+
+ The pcl-cvs package distributed with CVS 1.3 is an emacs package
+ that helps with the update/commit process. When you are ready to
+ update, you use the 'cvs-update' command within emacs. This
+ executes "update" and fills a cvs-mode buffer with a line for each
+ file that changed. The most helpful features are: descriptive
+ words for what happened (i.e. Merged or Conflict rather than 'U'),
+ single keys bound to diffs and commits, and the ability to mark
+ arbitrary groups of files, possibly from different directories,
+ for commit as a whole.
+
+ All the developers in my group that use emacs find pcl-cvs a much
+ friendlier and more helpful way to update/commit than raw cvs.
+ One vi user even converted to emacs just to use pcl-cvs.
+
+ Contributed by Jeffrey M Loomis
+
++4F.2 What is GIC (Graphical Interface to CVS)?
+
+ GIC is a window interface to CVS written in Tcl/Tk, which attempts
+ to hide the normal CVS command line options from novice users.
+
+ GIC works only in a single directory at a time, but it offers most
+ of the CVS commands you would normally use.
+
+ GIC can be obtained by anonymous ftp to
+
+ ftp.cpsc.ucalgary.ca:/pub/marwood/gic-1.0b5.tar.Z
+
+ contact
+ David Marwood
+ marwood@cpsc.ucalgary.ca
+
+ [[Does someone want to try to describe this better?]]
+
+
++4F.3 What is CAVEMAN?
+
+ CAVEMAN is a front end to CVS written in PERL providing a
+ collection of features desired by the site where it was developed.
+
+ - The ability to spread a "project" over multiple Repositories.
+ - Optional automatic tagging after each commit.
+ - Additional locking of files.
+ - Extra before and after program hooks.
+ - A layer of event logging.
+ - All sorts of error messages.
+ - Many changes to the semantics of commands.
+
+ It is available via anonymous ftp on llnl.gov [128.115.18.253] as
+ gnu/caveman_vX.Y.Z.tar.gz (The numbers X, Y, & Z vary with time.)
+
+ contact
+ Kathleen Dyer kdyer@llnl.gov
+ (510)423-6803
+ (510)423-5112 FAX
+
+
+ [[Does someone want to try to describe this better?]]
+
+
+
+----------------
+-- Section 4G -- Other Systems
+----------------
+
+ **** Questions:
+
+ 4G.1 I use a NeXT. Is there anything I need to know?
+ 4G.2 I use OS/2. Is there anything I need to know?
+ 4G.3 I use SCO Unix. Is there anything I need to know?
+ 4G.4 I use AIX. Is there anything I need to know?
+=4G.5 I use IRIX. Is there anything I need to know?
+=4G.6 I use an HP system. Is there anything I need to know?
+
+
+ **** Answers:
+
+Out of the box, CVS works on most varieties of Unix. Some near-Unix
+systems have a few problems and non-Unix systems have a *lot* of problems.
+
+ 4G.1 I use a NeXT. Is there anything I need to know?
+
+ Under NeXTSTEP 2.2, the tmpnam() function always returns the
+ same filename, which breaks "cvs patch". Apparently the
+ "mktemp()" function works OK, but you'll have to hack it up to
+ build something that acts like "tmpnam()".
+
+ NeXTSTEP 3.0's Interface Builder uses "nib" directories,
+ rather than files in previous revisions. It removes files it
+ doesn't recognize, making it impossible to place such a
+ directory under CVS -- the CVS admin directory will be removed.
+
+ [[Anything else?]]
+
+
+ 4G.2 I use OS/2. Is there anything I need to know?
+
+ [[Well?]]
+
+
+ 4G.3 I use SCO Unix. Is there anything I need to know?
+
+ [[Well?]]
+
+
+ 4G.4 I use AIX. Is there anything I need to know?
+
+ [[Well?]]
+
+
+=4G.5 I use IRIX. Is there anything I need to know?
+
+ If you see "uid" numbers where you would expect user names, try
+ adding -lsun to the link line. Without it CVS is unable to
+ retrieve "passwd" data through NIS.
+
+
+=4G.6 I use an HP system. Is there anything I need to know?
+
+ HP distributes RCS version 3 (a circa 1983 release!) with HP-UX.
+ CVS does not work with RCS version 3; it requires RCS version 4
+ or later. Your best bet is to find the latest version of RCS
+ and install it somewhere.
+
+ HP-UX 8.07 has a serious bug with the mmap system call and NFS
+ files; the bug can crash the operating system. Make sure that
+ you configure RCS to avoid mmap by setting has_mmap to 0 in
+ RCS's conf.h. This bug is fixed in HP-UX 9.
+
+ Contributed by Paul Eggert
+
+ If using the setgid() trick described in 4D.16, you will have to
+ create an entry in the /etc/privgroup file to give the group
+ assigned to the cvs executable setgid permission (see
+ setprivgrp(1m)). Additionally, if you are restricting "read"
+ access to the Repository by limiting access to the executable
+ (this requires yet another group), then you will require that
+ /etc/logingroup exists and is configured correctly (usually it's
+ just alink to /etc/group).
+
+ Contributed by Dale Woolridge
+
+
+=============================================
+== Section 5 ==== Past & Future ====
+=============================================
+
+----------------
+-- Section 5A -- Contributors
+----------------
+
+ **** Questions:
+
+ 5A.1 Who wrote CVS?
+=5A.2 You didn't write all of this FAQ, did you?
+
+
+ **** Answers:
+
+
+ 5A.1 Who wrote CVS?
+
+ Brian Berliner <berliner@sun.com> converted a collection of
+ scripts written by Dick Grune <dick@cs.vu.nl> into a C program,
+ then added all sorts of features. He continues to maintain CVS.
+
+ Jeff Polk <polk@bsdi.com> wrote much of the code added between
+ revisions 1.2 and 1.3. Many others were involved at some level.
+
+ Take a look at the README and the ChangeLog files in the CVS
+ sources for more details.
+
+
+=5A.2 You didn't write all of this FAQ, did you?
+
+ In the original hunt for questions to answer (performed in
+ Jan/Feb, 1993), I polled hundreds of people and I rephrased all
+ sorts of text found on the net. Because there are so many posers
+ of questions, I will list only those who contribute answers or
+ help significantly with the content and structure of this
+ document.
+
+ Unless a name is included in the answer itself, I didn't use
+ anyone else's answers verbatim. On the other hand, I did use
+ ideas and information provided by many. The people whose email
+ postings have added to this document or who have added to my
+ understanding are:
+
+ Brian Berliner <berliner@sun.com>, CVS maintainer.
+ Paul Eggert <eggert@twinsun.com>, RCS maintainer.
+
+ Gray Watson <gray@antaire.com>
+ Per Cederqvist <ceder@signum.se>
+ Pete Clark <pclark@is.com>
+
+ all of whom have sent me copies of their tutorials
+ and local CVS documentation.
+
+ Additional contributors, who have sent me ideas, text, corrections
+ and support include (in alphabetical order):
+
+ Donald Amby <amby@mixcom.mixcom.com>
+ Tom Cunningham <tomc@bouwsma,sps.mot.com>
+ Don Dwiggins <dwig@markv.com>
+ Dan Franklin <dan@diamond.bbn.com>
+ Jeffrey M Loomis <jml@world.std.com>
+ Barry Margolin <barmar@think.com>
+ Mark K. Mellis <mkm@ncd.com>
+ Chris Moore <Chris.Moore@src.bae.co.uk>
+ Gary Oberbrunner <garyo@think.com>
+ Steve Turner <stevet@carrier.sps.mot.com>
+ Dave Wolfe <dwolfe@pffft.sps.mot.com>
+ Dale Woolridge <dwoolridge@cid.aes.doe.ca>
+
+ Plus a myriad Thinking Machines people who posed hundreds of
+ questions.
+
+
+ Please send corrections. If I forgot you, remind me and I'll add
+ your name to the list.
+
+
+----------------
+-- Section 5B -- Bugs and Patches
+----------------
+
+This section addresses some known bugs and patches for them.
+Large patches will be stored in the FTP area.
+See the Development section later for stuff being worked on.
+
+ **** Questions:
+
+ 5B.1 Why can't CVS handle deletion of directories?
+=5B.2 Why can't CVS handle the moving of sources from one place in the
+ directory hierarchy to another?
+=5B.3 Why does "checkout" recurse indefinitely if an alias contains
+ its own name?
+ 5B.4 When I typed "cvs update -D <date>", why did it check out all
+ sorts of ancient files from the Attic? Shouldn't it just create
+ the set of files and revisions that existed at that date?
+ 5B.5 When I typed "cvs update -D <date>" in my branch, why did it
+ screw up all my files?
+ 5B.6 When I executed "checkout" into an existing directory I got "No
+ such file or directory" errors. Why?
+ 5B.7 Why does "update" send all output to the terminal after 26 files
+ have been updated?
++5B.8 Why doesn't the "-I !" option work in update and import?
+
+
+ **** Answers:
+
+ 5B.1 Why can't CVS handle deletion of directories?
+
+ An oversight, probably. [[Fixed in a future release?]]
+
+
+=5B.2 Why can't CVS handle the moving of sources from one place in the
+ directory hierarchy to another?
+
+ A "renaming database" has been proposed to track the history of
+ pathname changes in the Repository. A general solution is a
+ difficult problem. See 4B.9 and 2C.4.
+
+
+=5B.3 Why does "checkout" recurse indefinitely if an alias contains
+ its own name?
+
+ A bug in the handling of aliases. [[I'll remove this one when
+ the bug is fixed.]]
+
+
+ 5B.4 When I typed "cvs update -D <date>", why did it check out all
+ sorts of ancient files from the Attic? Shouldn't it just create
+ the set of files and revisions that existed at that date?
+
+ This seems to be a bug, but is really the lack of any obvious
+ place to store the date when a file is "removed".
+
+ There are four ranges of dates that CVS has to deal with when
+ trying to determine what revision was available on <date>:
+
+ 1. Dates before the earliest revision in the file.
+
+ 2. Dates between any two revisions in the file.
+
+ 3. Dates between the latest revision in the file and the date
+ when the file was moved to the Attic by "commit".
+
+ 4. Dates after moving the file to the Attic.
+
+ Since the date when a file is moved to the Attic is not stored
+ anywhere, CVS can't tell the difference between #3 and #4.
+ To avoid not producing a file that should exist in case #3, it
+ produces extraneous files in case #4.
+
+
+ For the above reason, if you have removed files in the Attic, it
+ is better to use "-r <tag>, or even "-r HEAD" than to use a
+ date spec.
+
+
+ 5B.5 When I typed "cvs update -D <date>" in my branch, why did it
+ screw up all my files?
+
+ Currently, the internal routine ("version_ts") that looks up
+ info about a file, overrides both the tag and date if *either*
+ the tag or date is specified on the command line. If only the
+ date is specified, it should not override a branch tag, but it
+ does.
+
+
+ 5B.6 When I executed "checkout" into an existing directory I got "No
+ such file or directory" errors. Why?
+
+ Though the man page says that "checkout" turns into an
+ "update -d" in directories that already exist, it is referring
+ to directories that already exist *and* were created by CVS.
+
+ When you try to run "checkout" on top of an existing directory
+ structure, some of which wasn't created by CVS, it will handle
+ directories and non-CVS files within directories already under
+ CVS, but it will display the above error on non-CVS files within
+ non-CVS directories.
+
+
+ 5B.7 Why does "update" send all output to the terminal after 26 files
+ have been updated?
+
+ CVS uses the "tmpnam()" function to generate temporary file names.
+ The ANSI standard for the "tmpnam()" function says:
+
+ "The tmpnam function generates a different string each time it is
+ called, up to TMP_MAX times. If it is called more than TMP_MAX
+ times, the behavior is implementation defined."
+
+ Later it says that the value of "TMP_MAX shall be at least 25."
+
+ On some platforms, the above specification is taken literally by
+ turning "at least 25" into "exactly 26" and by doing something
+ foolish (i.e. "implementation defined") after that. Some
+ systems return the same name repeatedly, which causes one form of
+ trouble. Others return NULL or garbage, which causes a different
+ form of trouble.
+
+ The broken systems appear to be cycling a single character through
+ the alphabet. SunOS cycles 3 characters through the alphabet, so
+ it won't cause trouble until 26 cubed or 17576 calls to
+ "tmpnam()".
+
+ Since CVS doesn't depend on the exact format of the tmp files, the
+ workaround is to provide a "tmpnam()" that doesn't have a limit
+ on the number of calls to it.
+
++5B.8 Why doesn't the "-I !" option work in update and import?
+
+ A bug. See the patch named "unoff/import_ignore" in the CVS FTP
+ archive
+
+
+ [[Section 5B needs more, but should probably wait until the
+ patch release comes out. Then we can document them for real and
+ provide pointers to patches in the FTP area.]]
+
+
+----------------
+-- Section 5C -- Development
+----------------
+
+ I hope to record three types of information here:
+
+ 1. Plans (with the developer's name attached) for fixing larger
+ bugs. (Smaller bugs should just show up, with a patch or a
+ reference to a patch stored in the FTP archive, in the
+ "Bugs" section above.)
+
+ 2. Plans for new development, with the developer's name attached.
+ (If the developer is particularly gonzo, it might also show a
+ completion date.)
+
+ 3. Requests for ideas and code to fix unresolved issues.
+
+
+ **** Questions:
+
+=5C.1 Where do I send bug reports?
+=5C.2 Where do I send fixes and patches?
+ 5C.3 Where do I send ideas for future development?
+ 5C.4 What plans are there for fixing bugs?
+=5C.5 What plans are there for new features?
+=5C.6 I have some time and I'd like to help. What can I do for you?
+
+
+ **** Answers:
+
+=5C.1 Where do I send bug reports?
+
+ First make sure it is a bug. Talk to your friends, coworkers and
+ anyone you know who uses CVS. Search this FAQ for related issues.
+ Then test it carefully. Try out variations to narrow down the
+ problem. Make sure it is repeatable. Look for workarounds so you
+ can report them.
+
+ If you are still sure it's a bug and you tried to fix it, skip to
+ the next question. Otherwise, send a message to the info-cvs
+ mailing list containing one of the following:
+
+ 1. If you have a good repeatable case and you think you know what
+ is going on, then describe the problem in detail. Include
+ a workaround if you have one.
+
+ 2. If you have no idea what is going on, go ahead and send a
+ question to the info-cvs mailing list. Include any information
+ you have describing the symptoms.
+
+ If careful testing reveals an RCS bug rather than a CVS bug, you
+ can sendbug reports to: rcs-bugs@cs.purdue.edu
+
+
+=5C.2 Where do I send fixes and patches?
+
+ First make sure the "fix" does something useful. Have someone to
+ review your fix. It is better to spend a bit of one person's
+ thinking time than to waste the time of thousands of people trying
+ to understand your fix.
+
+ If you tried to fix it and the patch is small, include the patch
+ in your message. Make sure the patch is based on the latest
+ released version of CVS.
+
+ If you tried to fix it and the patch is large, you should think
+ about why it is so large. Did you add a generally useful feature,
+ or did it grow out of hand?
+
+ If you still believe it is solid, send it to the maintainer of the
+ FTP archive (currently the author of this FAQ) for inclusion in
+ the CVS FTP archive and to Brian Berliner, the maintainer of CVS.
+
+
+ 5C.3 Where do I send ideas for future development?
+
+ [[Brian?]]
+
+
+ 5C.4 What plans are there for fixing bugs?
+
+ David G. Grubbs <dgg@think.com> plans/hopes to:
+
+ - Fix the release command to be more sophisticated about
+ foreign directories, renaming and to allow the release of
+ anything in the working directory.
+
+ - Fix the history command to track changes made in the
+ underlying layers since I originally wrote it, including
+ making "tag" work with history.
+
+
+
+ [[Brian?]]
+ [[Others?]]
+
+
+=5C.5 What plans are there for new features?
+
+ David G. Grubbs <dgg@think.com> plans/hopes to:
+
+ - Implement the design described in the Branching spec
+ distributed to this list in January, 93. It attempts to
+ address the problem of merging between arbitrary branches
+ and to fully support the idea of "branching".
+
+ - Add a feature to "cvs add" (Maybe a '-a' switch.) to
+ add a file by the same name as one in the Attic, by
+ dragging it back out of the Attic. (This connects to the
+ branching code, since a way has to be added to drag a
+ file out of the Attic that is merged onto the Main branch
+ from being only on a side-branch.)
+
+ - If no one else wants to deal with it, I would like to
+ enhance the whole "modules" concept to cover more of
+ the naming problem and to allow more complicated access
+ control. (Optional, of course.)
+
+ - Create a set of configuration files (in addition to or to
+ supersede the cvsignore files) to allow the setting of
+ a wide variety of site-specific options.
+
+
+ Brian Berliner <berliner@sun.com> plans/hopes to:
+
+ - [[Rename database?]]
+
+ [[Brian? Any plans?]]
+
+
+ Paul F. Kunz <pfkeb@slac.stanford.edu> has produced a version of
+ CVS (RCVS) that runs remotely.
+
+ On the host "ftp.slac.stanford.edu", you can find:
+ Sources: pub/sources/rcvs-0.5.0.tar.Z
+ Paper: pub/preprints/slac-pub-5923.ps
+
+
+ [[Others?]]
+
+
+=5C.6 I have some time and I'd like to help. What can I do for you?
+
+ You can review this document, correct errors and fill in any of
+ the incomplete sections.
+
+ You can add to the contrib area, which contains useful ways to use
+ some of the programmable CVS facilities (loginfo, commitinfo) or
+ ways of connecting to work environments (pcl-cvs).
+
+ You could write a regression test suite. Or at least a scaffold
+ into which we can drop tests.
+
+ You can write specs for new features, fix bugs, review the man
+ page or . . .
+
+ [[Brian?]]
+
+ [[Is there some way we can register someone as working
+ on something or should we just stay in the "implement it and
+ send it to me" mode?]]
+
+
+=================================================
+== Section 6 ==== Table of Contents ====
+=================================================
+
+===========================================================================
+== Frequently Asked Questions about CVS (The Concurrent Versions System) ==
+===========================================================================
+
+============================================
+== Section 0 ==== Introduction ====
+============================================
+
+Questions are divided into five numbered Sections. Sections are divided
+into lettered sub-sections. The questions are numbered sequentially
+within each sub-section, though they are in no particular order.
+
+ 1. What is CVS?
+ A. What is CVS? What's it for? Why CVS?
+ B. Where do I find it? Where can I find Help?
+ C. How does CVS differ from other similar software?
+ D. What do you mean by . . .? (Definitions)
+
+ 2. User Tasks
+ A. Getting Started
+ B. Common User Tasks
+ C. Less Common User Tasks
+ D. General Questions
+
+ 3. Commands
+ A. through P. One section for each CVS command.
+
+ 4. Advanced Topics
+ A. Installing CVS
+ B. Setting up and Managing the Repository
+ C. Branching
+ D. Tricks of the Trade
+ E. Weirdness
+ F. Related Software
+ G. Other Systems
+
+ 5. Past & Future
+ A. Contributors.
+ B. Bugs and Patches
+ C. Development
+
+ 6. Table of Contents
+
+
+
+============================================
+== Section 1 ==== What is CVS? ====
+============================================
+
+----------------
+-- Section 1A -- What is CVS? What's it for? Why CVS?
+----------------
+ 1A.1 What does CVS stand for? Can you describe it in one sentence?
+ 1A.2 What is CVS for? What does it do for me?
+ 1A.3 How does CVS work?
+=1A.4 What is CVS useful for?
+=1A.5 What is CVS *not* useful for?
+=1A.6 Why isn't it called OSCO (Online Source COntrol)?
+
+----------------
+-- Section 1B -- Where do I find CVS? Where can I find Help?
+----------------
+ 1B.1 How do I get more information about CVS?
+ 1B.2 Is there an archive of CVS material?
+ 1B.3 How do I get a copy of the latest version of CVS?
+ 1B.4 Is there any other documentation? How about tutorials?
+ 1B.5 Is there a mailing list devoted to CVS? How do I get on it?
+ 1B.6 What prayers are appropriate for each of the major denominations
+ (e.g. 20's, 50's, 100's) when issuing complex CVS commands?
++1B.7 How do I get files out of the archive if I don't have FTP?
+
+----------------
+-- Section 1C -- How does CVS differ from other similar software?
+----------------
+=1C.1 How does CVS differ from RCS?
+ 1C.2 How does CVS differ from SCCS?
+=1C.3 How does CVS differ from ClearCase?
+ 1C.4 How does CVS differ from TeamWare?
+ 1C.5 How does CVS differ from SunPro?
+ 1C.6 How does CVS differ from Aegis?
+ 1C.7 How does CVS differ from Shapetools?
++1C.8 How does CVS differ from TeamNet?
++1C.9 How does CVS differ from ProFrame?
++1C.10 How does CVS differ from CaseWare/CM?
++1C.11 How does CVS differ from Sublime?
+
+----------------
+-- Section 1D -- What do you mean by . . .? (Definitions)
+----------------
+#1D.1 What are "The Repository", "$CVSROOT" and "CVSROOT"?
+ 1D.2 What is an RCS file?
+ 1D.3 What is a working file?
+ 1D.4 What is a working directory (or working area)?
+ 1D.5 What is "checking out"?
+=1D.6 What is a revision?
+ 1D.7 What is a "Tag"?
+=1D.8 What are "HEAD" and "BASE"?
+=1D.9 What is a Branch?
+=1D.10 What is "the trunk"?
+=1D.11 What is a module?
++1D.12 What does "merge" mean?
+
+
+==========================================
+== Section 2 ==== User Tasks ====
+==========================================
+
+----------------
+-- Section 2A -- Getting Started
+----------------
+ 2A.1 What is the first thing I have to know?
+ 2A.2 Where do I work?
+=2A.3 What does CVS use from my environment?
+ 2A.4 OK, I've been told that CVS is set up, my module is named
+ "ralph" and I have to start editing. What do I type?
+ 2A.5 I have been using RCS for a while. Can I convert to CVS without
+ losing my revision history? How about converting from SCCS?
+
+----------------
+-- Section 2B -- Common User Tasks
+----------------
+#2B.1 What is the absolute minimum I have to do to edit a file?
+=2B.2 If I edit multiple files, must I type "commit" for each one?
+ 2B.3 How do I get rid of the directory that "checkout" created?
+=2B.4 How do I find out what has changed?
+=2B.5 I just created a new file. How do I add it to the Repository?
+=2B.6 How do I merge changes made by others into my working directory?
+ 2B.7 How do I label a set of revisions so I can retrieve them later?
+ 2B.8 How do I checkout an old release of a module, directory or file?
+ 2B.9 What do I have to remember to do periodically?
+
+----------------
+-- Section 2C -- Less Common User Tasks
+----------------
+ 2C.1 Can I create sub-directories in my working directory?
+ 2C.2 How do I add new sub-directories to the Repository?
+ 2C.3 How do I remove a file I don't need?
+=2C.4 How do I rename a file?
+ 2C.5 How do I make sure that all the files and directories in my
+ working directory are really in the Repository?
+=2C.6 How do I create a branch?
+=2C.7 How do I modify the modules file? How about the other files in
+ the CVSROOT administrative area?
++2C.8 How do I split a file into pieces, retaining revision histories?
+
+----------------
+-- Section 2D -- General Questions
+----------------
+=2D.1 How do I see what CVS is trying to do?
+ 2D.2 If I work with multiple modules, should I check them all out and
+ commit them occasionally? Is it OK to leave modules checked out?
+ 2D.3 What is a "sticky" tag? What makes it sticky? How do I loosen it?
+ 2D.4 How do I get an old revision without updating the "sticky tag"?
+=2D.5 What operations disregard sticky tags?
+=2D.6 Is there a way to avoid reverting my Emacs buffer after
+ committing a file? Is there a "cvs-mode" for Emacs?
+ 2D.7 How does conflict resolution work? What *really* happens if two
+ of us change the same file?
+ 2D.8 How can I tell who has a module checked out?
+#2D.9 Where did the .#<file>.1.3 file in my working directory come from?
+ 2D.10 What is this "ignore" stuff?
+ 2D.11 Why does .cvsignore not ignore directories?
+ 2D.12 Is it safe to interrupt CVS using Control-C?
+ 2D.13 How do I turn off the "admin" command?
+ 2D.14 How do I turn off the ability to disable history via "cvs -l"?
+ 2D.15 How do I keep certain people from accessing certain directories?
+
+
+========================================
+== Section 3 ==== Commands ====
+========================================
+
+----------------
+-- Section 3A -- "add", "ad", "new"
+----------------
+ 3A.1 What is "add" for?
+ 3A.2 How do I add a new file to the branch I'm working on?
+ 3A.3 Why did my newly added file end up in the Attic?
+ 3A.4 How do I put a new file on the Main Branch and branch off from
+ there onto my default branch?
+
+----------------
+-- Section 3B -- "admin", "adm", "rcs"
+----------------
+ 3B.1 What is "admin" for?
+ 3B.2 Wow! Isn't that dangerous?
+=3B.3 What would I normally use "admin" for?
+=3B.4 What should I avoid when using "admin"?
+-3B.5 How do I restrict the "admin" command? The -i flag in the modules
+ file can restrict commits. What's the equivalent for "admin"?
++3B.6 I backed out a revision with "admin -o" and committed a
+ replacement. Why doesn't "update" retrieve the new revision?
+
+----------------
+-- Section 3C -- "checkout", "co", "get"
+----------------
+ 3C.1 What is "checkout" for?
+ 3C.2 What is the "module" that "checkout" takes on the command line?
+ 3C.3 Isn't a CVS "checkout" just a bunch of RCS checkouts?
+ 3C.4 What's the difference between "update" and "checkout"?
+ 3C.5 Why can't I check out a file from within my working directory?
+ 3C.6 How do I avoid dealing with those long relative pathnames?
+ 3C.7 Can I move a checked-out directory? Does CVS remember where it
+ was checked out?
+#3C.8 How can I lock files on checkout the way RCS does?
++3C.9 What is "checkout -s"? How is it different from "checkout -c"?
+
+----------------
+-- Section 3D -- "commit", "ci", "com"
+----------------
+ 3D.1 What is "commit" for?
+=3D.2 If I edit ten files, do I have to type "commit" ten times?
+ 3D.3 Explain: cvs commit: Up-to-date check failed for `<file>'
+ 3D.4 What happens if two people try to "commit" conflicting changes?
+ 3D.5 I committed something and I don't like it. How do I remove it?
+=3D.6 Explain: cvs commit: sticky tag `V3' for file `X' is not a branch
+=3D.7 Why does "commit -r <branch_tag>" put new files in the attic?
++3D.8 Why does "commit -r <rev>" ignore <rev> on an added file?
+
+----------------
+-- Section 3E -- "diff", "di", "dif"
+----------------
+ 3E.1 What is "diff" for?
+=3E.2 Why did "diff" display nothing when I know there are later
+ committed revisions in the Repository?
+#3E.3 How do I display what changed in the Repository since I last
+ executed "checkout", "update" or "commit"?
+=3E.4 How do I display the difference between my working file and what
+ I checked in last Thursday?
+=3E.5 Why can't I pass the --unified option to "diff"?
+
+----------------
+-- Section 3F -- "export", "exp", "ex"
+----------------
+ 3F.1 What is "export" for?
+=3F.2 Why does it remove the RCS keywords so I can't use the "ident"
+ command on the source files?
+=3F.3 Can I override the '-kv' flag CVS passes to RCS?
+=3F.4 Why the hell not?
+ 3F.5 Why does "export -D" check out every file in the Attic?
+
+----------------
+-- Section 3G -- "history", "hi", "his"
+----------------
+ 3G.1 What is "history" for?
+ 3G.2 Of what use is it?
+ 3G.3 What is this, Big Brother?
+ 3G.4 I deleted my working directory and "history" still says I have
+ it checked out. How do I fix it?
+ 3G.5 So I *can* edit the History file?
+ 3G.6 Why does the history file grow so quickly?
+ 3G.7 What is the difference between "cvs history -r <tag/rev>" and
+ "cvs history -t <tag>"?
+ 3G.8 Why does "cvs history -c -t <tag>" fail to print anything?
+ 3G.9 "cvs history -a -o" only printed one line for each checked-out
+ module. Shouldn't it print all the directories where the
+ modules are checked out?
+=3G.10 I can't figure out "history", can you give me concrete examples?
+
+----------------
+-- Section 3H -- "import", "im", "imp"
+----------------
+=3H.1 What is "import" for?
+=3H.2 How am I supposed to use "import"?
+=3H.3 Why does import put files on a branch? Why can't you put it on
+ the Main Trunk and let me work on a branch?
+ 3H.4 Is there any way to import binary files?
+=3H.5 Why does "import" corrupt some binary files?
+ 3H.6 How do I keep "import" from expanding all the $\Revision$ strings
+ to be 1.1.1.1?
+#3H.7 I imported some files for the Yarg compiler that compiles files
+ with a suffix of ".yarg" and whose comment prefix is "YARG> ".
+ When I check them out, they will no longer compile because they
+ have this junk in them. Why?
+ 3H.8 How do I make "import" save the timestamps on the original files?
+ 3H.9 Why didn't "import" ignore the directories I told it to?
+ 3H.10 Why can't I "import" 3 releases on different branches?
+ 3H.11 What do I do if the Vendor adds or deletes files between releases?
+ 3H.12 What about if the Vendor changes the names of files or
+ directories, or rearranges the whole structure between releases?
+ 3H.13 I thought "import" was for Vendor releases, why would I use it
+ for code of my own? Do I have to use import?
+=3H.14 How do I import a large Vendor release?
++3H.15 Explain: ERROR: cannot create link to <file>: Permission denied
+
+----------------
+-- Section 3I -- "log", "lo", "rlog"
+----------------
+=3I.1 What is "log" for?
+ 3I.2 How do I extract the log entries between two revisions?
+=3I.3 How do I extract the log entries on a whole branch?
+ 3I.4 How do I generate ChangeLogs from RCS logs?
+=3I.5 Why does "log" tell me a file was committed exactly 5 hours later
+ than I know it was?
+
+----------------
+-- Section 3J -- "patch", "pa", "rdiff"
+----------------
+ 3J.1 What is "patch" for?
+ 3J.2 Why does "patch" include files from the Attic when I use '-D'?
+ 3J.3 How do I make "patch" produce a patch for one or two files?
+ It seems to work only with modules.
+
+----------------
+-- Section 3K -- "release", "re", "rel"
+----------------
+ 3K.1 What is "release" for?
+ 3K.2 Why does release -d delete directories within my directory that
+ weren't ever in the CVS Repository?
+ 3K.3 Why can't I reverse a "cvs checkout path/name/subdir" with a
+ "cvs release path/name/subdir" without an "unknown module name"?
+ 3K.4 Why can't I "release" portions of a checked out directory? I
+ should be able to "release" any file or sub-directory within
+ my working directory.
+ 3K.5 I removed the tree that I was about to start working on. How do I
+ tell cvs that I want to release it if I don't have it anymore?
+ 3K.6 Why doesn't "release -d module" reverse a "checkout module"?
+ 3K.7 Why can't I release a module renamed with "cvs checkout -d"?
+
+----------------
+-- Section 3L -- "remove", "rm", "delete"
+----------------
+ 3L.1 What is "remove" for?
+ 3L.2 Why doesn't "remove" work on directories when it appears to try?
+ 3L.3 I don't like removing files. Is there another way to ignore them?
+ 3L.4 I just removed a file. How do I resurrect it?
+ 3L.5 Why doesn't "remove" delete the file? Instead, it prints:
+ cvs remove: no files removed; use `rm' to remove the file first
+
+----------------
+-- Section 3M -- "rtag", "rt", "rfreeze"
+----------------
+ 3M.1 What is "rtag" for?
+ 3M.2 Why would you use "rtag"? It assumes a static Repository.
+
+----------------
+-- Section 3N -- "status", "st", "stat"
+----------------
+=3N.1 What is "status" for?
+ 3N.2 Why does "status" limit the File: at the top to 17 characters?
++3N.3 Shouldn't the status "Needs Checkout" be "Needs Update"?
+
+----------------
+-- Section 3O -- "tag", "ta", "freeze"
+----------------
+ 3O.1 What is "tag" for?
+=3O.2 What is the difference between "tag" and "rtag"?
+=3O.3 Why does "tag -b" not put a tag on the Branch Point revision?
+ How do I refer to the Branch Point?
+-3O.4 So "tag" labels a bunch of files. What do you use a Tag for?
+ 3O.5 How do I get "tag" and "rtag" to send mail the way "commit" does?
+ 3O.6 Why can't "tag" handle the '-r' option that "rtag" takes?
+-3O.7 After a "tag <tag>" in my working directory, why doesn't "checkout
+ -r <tag>" somewhere else produce copy of my current files?
+#3O.8 Why doesn't "tag" write a history record the way "rtag" does?
+
+----------------
+-- Section 3P -- "update", "up", "upd"
+----------------
+ 3P.1 What is "update" for?
+=3P.2 What do 'U', 'M' and 'C' mean when I type "update"? Are they
+ different for "cvs -n update"?
+ 3P.3 What's the difference between "update" and "checkout"?
+=3P.4 Why don't I get new files when I execute "update"?
+#3P.5 Why does "update" say 'M' both for plain modified files and for
+ successful (i.e. conflict-free) merges? Aren't they different?
+=3P.6 After a merge ("update" or "update -j"), why doesn't CVS remember
+ the conflict and not allow you to commit the result until the
+ conflict is resolved?
+ 3P.7 Is there a feature to tell me what I have changed, added and
+ removed without changing anything?
+=3P.8 Why does "cvs update" not flag directories that are not in the
+ Repository as it does with new files?
+ 3P.9 Why are all my files deleted when I execute "update"?
+
+
+===============================================
+== Section 4 ==== Advanced Topics ====
+===============================================
+
+----------------
+-- Section 4A -- Installing CVS
+----------------
+#4A.1 What do I have to do before I install CVS?
+ 4A.2 How do I configure the CVS programs?
+=4A.3 What do I have to install?
+ 4A.4 How do I get around the bugs I've heard of GNU diff version 2.2?
+
+----------------
+-- Section 4B -- Setting up and Managing the Repository
+----------------
+=4B.1 What do I do first? How do I create a Repository?
+=4B.2 What are those files in $CVSROOT/CVSROOT?
+ 4B.3 Is there any other state stored in the Repository besides in the
+ $CVSROOT/CVSROOT directory?
+ 4B.4 How do I put sources into the Repository?
+=4B.5 What file permissions should I use on (and in) the Repository?
+=4B.6 How do I structure my Repository?
+=4B.7 How do I manage the modules file?
+ 4B.8 Why would anyone use "modules"? They are too restrictive. I
+ want to be able to select just the files I want to edit.
+=4B.9 How do I rename a file or directory? What are the consequences?
+=4B.10 What are "Attic" directories?
+ 4B.11 Is it OK to remove anything from the Repository?
+ 4B.12 Can I convert to CVS from RCS without losing my revision history?
+=4B.13 Can I move RCS files with branches in them into the Repository?
+=4B.14 Can I use raw RCS commands on the Repository?
+ 4B.15 How do I convert from SCCS to RCS?
+=4B.16 How do I limit access to the Repository?
+=4B.17 What are the Repository Administrator's responsibilities?
+ 4B.18 How do I move the whole Repository?
++4B.19 How do I change permissions on a file in the Repository by using
+ a CVS command? (i.e. without using "chmod 777 $CVSROOT/dir/file")
+
+----------------
+-- Section 4C -- Branching
+----------------
+ 4C.1 What is a branch?
+=4C.2 Why (or when) would I want to create a branch?
+=4C.3 How do I create and checkout a branch?
+ 4C.4 Once created, how do I manage a branch?
+ 4C.5 Are there any extra issues in managing multiple branches?
+ 4C.6 How do I merge a whole branch back into the trunk?
+ 4C.7 How do I merge changes from the trunk into my branch or between
+ branches?
+ 4C.8 How do I add a new file to a branch?
+=4C.9 How do I know what branch I'm (working) on?
+ 4C.10 Do I really have to know the name of the branch I'm working on?
+ 4C.11 How do I refer to the revision where I branched so I can see
+ what changed since the Branch Point on another branch?
+ 4C.12 Why didn't the command "cvs admin -bBRANCH1 *" create a branch?
+ 4C.13 Is it possible to set the "default CVS branch" for everyone?
+=4C.14 How do I perform a large merge?
+ 4C.15 Is a Vendor merge any different from a branch merge?
++4C.16 How do I go back to a previous version of the code on a branch?
++4C.17 Why do I get the latest files on the branch when I tried to
+ "update -r <tag>"?
+
+----------------
+-- Section 4D -- Tricks of the Trade
+----------------
+=4D.1 How can you even check in binary files, let alone allow CVS to
+ do its auto-merge trick on them?
+ 4D.2 Can I edit the RCS (",v") files in the Repository?
+ 4D.3 Can I edit the ./CVS/{Entries,Repository,Tag} files?
+=4D.4 Someone executed "admin -o" and removed revisions to which
+ tags/symbols were attached. How do I fix them?
+=4D.5 How do I move a magic branch tag?
+ 4D.6 Can I use RCS locally to record my changes without making them
+ globally visible by committing them?
+ 4D.7 How can I allow access to the Repository by both CVS and RCS?
+=4D.8 I "updated" a file my friend "bubba" committed yesterday.
+ Why doesn't the file now have a modified date of yesterday?
+#4D.9 While in the middle of a large "commit", how do I run other
+ commands, like "diff" or "stat" without seeing lock errors?
+ 4D.10 Why does the merge occasionally resurrect lines of code?
+ 4D.11 Why does the merge fail when my "rcsmerge" program is
+ configured to use GNU diff version 2.1 or later?
+ 4D.12 What the hell is Entries.Static?
+=4D.13 Why did I get the wrong Repository in the loginfo message?
+=4D.14 Can I have multiple source repositories, one for each project?
+ 4D.15 How do I run CVS setuid so I can only allow access through the
+ CVS program itself?
+ 4D.16 How about using groups and setgid() then?
+ 4D.17 How do I use the "commitinfo" file?
+ 4D.18 How do I use the "loginfo" files?
+
+----------------
+-- Section 4E -- Weirdness
+----------------
+ 4E.1 Explain: "ci error: unexpected EOF in diff output"
+=4E.2 Explain: "RCS file /Repository/module/file.c,v is in use"
+=4E.3 I don't want a Vendor branch. Why can't I work on the main trunk?
+ 4E.4 Merges can't work. I don't trust them. If you won't change it to
+ something I can understand, I won't use CVS.
+ 4E.5 Explain: "co error, line 2: Missing access list"
++4E.6 Explain: "error: RCS file name `xyz .c' contains white space"
++4E.7 Explain: cvs checkout: warning: <X> is not (any longer) pertinent
+
+----------------
+-- Section 4G -- Other Systems
+----------------
+ 4G.1 I use a NeXT. Is there anything I need to know?
+ 4G.2 I use OS/2. Is there anything I need to know?
+ 4G.3 I use SCO Unix. Is there anything I need to know?
+ 4G.4 I use AIX. Is there anything I need to know?
+=4G.5 I use IRIX. Is there anything I need to know?
+ 4G.6 I use an HP system. Is there anything I need to know?
+
+
+=============================================
+== Section 5 ==== Past & Future ====
+=============================================
+
+----------------
+-- Section 5A -- Contributors
+----------------
+ 5A.1 Who wrote CVS?
+=5A.2 You didn't write all of this FAQ, did you?
+
+----------------
+-- Section 5B -- Bugs and Patches
+----------------
+ 5B.1 Why can't CVS handle deletion of directories?
+=5B.2 Why can't CVS handle the moving of sources from one place in the
+ directory hierarchy to another?
+=5B.3 Why does "checkout" recurse indefinitely if an alias contains
+ its own name?
+ 5B.4 When I typed "cvs update -D <date>", why did it check out all
+ sorts of ancient files from the Attic? Shouldn't it just create
+ the set of files and revisions that existed at that date?
+ 5B.5 When I typed "cvs update -D <date>" in my branch, why did it
+ screw up all my files?
+ 5B.6 When I executed "checkout" into an existing directory I got "No
+ such file or directory" errors. Why?
+ 5B.7 Why does "update" send all output to the terminal after 26 files
+ have been updated?
++5B.8 Why doesn't the "-I !" option work in update and import?
+
+----------------
+-- Section 5C -- Development
+----------------
+=5C.1 Where do I send bug reports?
+=5C.2 Where do I send fixes and patches?
+ 5C.3 Where do I send ideas for future development?
+ 5C.4 What plans are there for fixing bugs?
+=5C.5 What plans are there for new features?
+=5C.6 I have some time and I'd like to help. What can I do for you?
+
+
+=================================================
+== Section 6 ==== Table of Contents ====
+=================================================
+
+% End of Table of Contents
+% End of CVS FAQ document
+
+# Local Variables:
+# mode: text
+# fill-column: 74
+# fill-prefix: "\t"
+# End:
diff --git a/gnu/usr.bin/cvs/README b/gnu/usr.bin/cvs/README
new file mode 100644
index 0000000..6b70021
--- /dev/null
+++ b/gnu/usr.bin/cvs/README
@@ -0,0 +1,207 @@
+$CVSid: @(#)README 1.32 94/10/22 $
+
+ CVS Kit, Version 1.4 Alpha
+
+ Copyright (c) 1993-1994 Brian Berliner
+ Copyright (c) 1992 Brian Berliner and Jeff Polk
+ Copyright (c) 1989-1992, Brian Berliner
+ All Rights Reserved
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+-------------------------------------------------------------------------------
+
+Welcome to the CVS 1.4 Alpha release! We thank you for taking the time to
+test this (potentially unstable) release and report bugs (ideally, with
+fixes). To report bugs, run the "cvsbug" program and fill out the template:
+
+ $ cvsbug
+
+The "cvsbug" program is installed in the same location as the "cvs"
+program. If your installation failed, you may need to run "cvsbug"
+directly out of the "src" directory as "src/cvsbug.sh".
+
+While we cannot promise to be responsive to said bugs, we do appreciate
+your support through this Alpha process. Please consult the INSTALL file
+for information on tested configurations. If you have a comment about an
+already tested configuration, or have tried CVS on a new configuration,
+please write to the above address and let us know! Free software only
+works if we all help out.
+
+Finally, we cannot guarantee that this release will not completely wipe out
+all of your work from your system. We do some simple testing before each
+release, but you are completely on your own. We recommend testing this
+release on a source repository that is not critical to your work. THIS
+SOFTWARE IS SUPPLIED COMPLETELY "AS IS". NO WARRANTY....
+
+Thanks for your support!
+
+ -The CVS Alpha Team
+
+-------------------------------------------------------------------------------
+
+CVS is a freely available collection of programs that provide for software
+release and revision control functions in a UNIX environment. It is
+designed to work on top of the RCS distribution, V4 and later. CVS does
+understand how to parse older RCS formats, but cannot do any of the fancier
+features (like vendor branch support) without RCS branch support.
+
+Short blurb from the manual page (larger blurb is included there):
+ cvs is a front end to the rcs(1) revision control system
+ which extends the notion of revision control from a collec-
+ tion of files in a single directory to a hierarchical col-
+ lection of directories consisting of revision controlled
+ files. These directories and files can be combined together
+ to form a software release. cvs provides the functions
+ necessary to manage these software releases and to control
+ the concurrent editing of source files among multiple
+ software developers.
+
+And a whole lot more. See the man/cvs.1 file for more information.
+
+-------------------------------------------------------------------------------
+
+Special note to current CVS 1.3 users:
+
+--> You can skip this section and go straight to "Installation" if you <--
+--> have not been running any previous releases of CVS. <--
+
+See the ChangeLog file in this directory to find out what has changed from
+CVS 1.3.
+
+Some files have been renamed from the CVS 1.3 distribution. If you're not
+careful, this can cause your build of CVS 1.4 to fail in strange ways. In
+particular, be sure to remove the src/config.h file (which is now
+src/options.h), as the correct config.h file is generated automatically by
+the "configure" stage of installation (and installed in this directory).
+
+-------------------------------------------------------------------------------
+
+Installation:
+
+Please read the INSTALL file for installation instructions. Brief summary:
+
+ $ ./configure
+ $ make
+ $ make install
+ $ cvsinit
+
+-------------------------------------------------------------------------------
+
+Mailing Lists:
+
+I have setup the following mailing list for CVS users and other interested
+parties. I have no idea what kind of volume will be generated on this
+list. Nor can I guarantee to personally respond to questions posted to the
+list. Anyway, the mailing list is:
+
+ info-cvs-request@prep.ai.mit.edu
+ Requests for addition to or removal from the mailing list
+ must be sent to this address. Problems with the list
+ (like bounced mail) should also be sent here. Please be
+ specific about your email address.
+
+ info-cvs@prep.ai.mit.edu
+ Questions, bugs, porting problems, hints, or whatever
+ can be sent to this address. A Frequently Asked Questions
+ (FAQ) my be available from host "think.com" in the
+ "/pub/cvs" directory. Please consult the FAQ before
+ sending questions to info-cvs. DO NOT SEND ADDITION AND
+ REMOVAL REQUESTS TO THIS ALIAS.
+
+-------------------------------------------------------------------------------
+
+Credits:
+
+The conflict-resolution algorithms and much of the administrative file
+definitions of CVS were based on the original package written by Dick Grune
+at Vrije Universiteit in Amsterdam <dick@cs.vu.nl>, and posted to
+comp.sources.unix in the volume 6 release sometime in 1986. This original
+version was a collection of shell scripts. I am thankful that Dick made
+his work available.
+
+Brian Berliner from Prisma, Inc. (now at Sun Microsystems, Inc.)
+<berliner@sun.com> converted the original CVS shell scripts into reasonably
+fast C and added many, many features to support software release control
+functions. See the manual page in the "man" directory. A copy of the
+USENIX article presented at the Winter 1990 USENIX Conference, Washington
+D.C., is included in the "doc" directory.
+
+Jeff Polk from BSDI <polk@bsdi.com> converted the CVS 1.2
+sources into much more readable and maintainable C code. He also added a
+whole lot of functionality and modularity to the code in the process.
+See the ChangeLog file.
+
+david d `zoo' zuhn <zoo@armadillo.com> contributed the working base code
+for CVS 1.4 Alpha. His work carries on from work done by K. Richard Pixley
+and others at Cygnus Support. The CVS 1.4 upgrade is due in large part to
+Zoo's efforts.
+
+David G. Grubbs <dgg@odi.com> contributed the CVS "history" and "release"
+commands. As well as the ever-so-useful "-n" option of CVS which tells CVS
+to show what it would do, without actually doing it. He also contributed
+support for the .cvsignore file.
+
+The Free Software Foundation (GNU) contributed most of the portability
+framework that CVS now uses. This can be found in the "configure" script,
+the Makefile's, and basically most of the "lib" directory.
+
+K. Richard Pixley, Cygnus Support <rich@cygnus.com> contributed many bug
+fixes/enhancement as well as completing early reviews of the CVS 1.3 manual
+pages.
+
+Roland Pesch, then of Cygnus Support <roland@wrs.com> contributed brand new
+cvs(1) and cvs(5) manual pages. We should all thank him for saving us from
+my poor use of our language!
+
+Paul Sander, HaL Computer Systems, Inc. <paul@hal.com> wrote and
+contributed the code in lib/sighandle.c. I added support for POSIX, BSD,
+and non-POSIX/non-BSD systems.
+
+In addition to the above contributors, the following Beta testers deserve
+special mention for their support. If I have left off your name, I
+apologize. Just write to me and let me know!
+
+ Mark D. Baushke <mdb@cisco.com>
+ Per Cederqvist <ceder@signum.se>
+ J.T. Conklin (jtc@cygnus.com>
+ Vince DeMarco <vdemarco@fdcsrvr.cs.mci.com>
+ Paul Eggert <eggert@twinsun.com>
+ Lal George <george@research.att.com>
+ Dean E. Hardi <Dean.E.Hardi@ccmail.jpl.nasa.gov>
+ Mike Heath <mike@pencom.com>
+ Jim Kingdon <kingdon@cygnus.com>
+ Bernd Leibing <bernd.leibing@rz.uni-ulm.de>
+ Benedict Lofstedt <benedict@tusc.com.au>
+ Dave Love <d.love@dl.ac.uk>
+ Robert Lupton the Good <rhl@astro.princeton.edu>
+ Tom McAliney <tom@hilco.com>
+ Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
+ Jim Meyering <meyering@comco.com>
+ Thomas Mohr <mohr@lts.sel.alcatel.de>
+ Thomas Nilsson <thoni@softlab.se>
+ Raye Raskin <raye.raskin@lia.com>
+ Harlan Stenn <harlan@landmark.com>
+ Gunnar Tornblom <gunnar.tornblom@senet.abb.se>
+ Greg A. Woods <woods@kuma.web.net>
+
+Many contributors have added code to the "contrib" directory. See the
+README file there for a list of what is available. There is also a
+contributed GNU Emacs CVS-mode in contrib/pcl-cvs.
+
+-------------------------------------------------------------------------------
+
+ Brian Berliner
+ berliner@sun.com
diff --git a/gnu/usr.bin/cvs/TODO b/gnu/usr.bin/cvs/TODO
new file mode 100644
index 0000000..90795c4
--- /dev/null
+++ b/gnu/usr.bin/cvs/TODO
@@ -0,0 +1,610 @@
+$CVSid: @(#)TODO 1.26 94/09/21 $
+
+01. testing. An automated testing enviroment would be a big win.
+
+14. Pathname stripper, for checkout, as well as for writing the
+ Repository file.
+ [[ I have a simple one, but need to make sure to call it at all the
+ appropriate points ]]
+
+16. List of current users of a directory needs to be maintained.
+ [[ sort of solved by history database ]]
+
+22. Catch signals for cleanup when "add"ing files.
+
+24. Insist on a log message.
+
+30. Add "patch" program option to the modules database.
+
+31. Think hard about ^C recovery.
+
+35. Add "admin" command as an interface to "rcs".
+ [[ a cheesy version is there, but it should be re-done ]]
+
+38. Think hard about using RCS state information to allow one to checkin
+ a new vendor release without having it be accessed until it has been
+ integrated into the local changes.
+
+39. Think about allowing parallel source trees that can easily track
+ each other.
+ [[ sort of solved with the automagic branch support, but I want more ]]
+
+45. Consider enhancing the "patch" and "tag" command support in the module
+ database -- they seem hard to use since these commands deal directly
+ with the RCS ,v files.
+
+46. Perhaps checkout/checkin/tag/patch commands should be imbedded in the
+ file system directly, using special known command names?
+
+49. cvs xxx commands should be able to deal with files in other
+ directories. I want to do a cvs ci foo/bar.c. This complicates things
+ a bit because one might specify files in different directories, but you
+ could just bucket sort them and do everything for each directory
+ together. Other than that, it's just a matter of using the adm
+ directory from the directory containing the file rather than the cwd.
+ [[ most commands now use the generic recursion processor, but not all;
+ this note is left here to remind me to fix the others ]]
+
+51. a way to identify what files other people are working on. Imagine "cvs
+ modified", which prints out a table like
+
+ file modifiers
+ ===== =========
+ foo.c
+ bar.c wsd
+ baz.c nrt jda
+
+ I think this would be pretty difficult; I don't know if this
+ information is stored anywhere. Also it's hard to say how one gets a
+ user name, maybe a path to their local hierarchy is all you could get.
+ [[ the history stuff does some of this, but not all ]]
+
+52. SCCS has a feature that I would *love* to see in CVS, as it is very
+ useful. One may make a private copy of SCCS suid to a particular user,
+ so other users in the authentication list may check files in and out of
+ a project directory without mucking about with groups. Is there any
+ plan to provide a similar functionality to CVS? Our site (and, I'd
+ imagine, many other sites with large user bases) has decided against
+ having the user-groups feature of unix available to the users, due to
+ perceived administrative, technical and performance headaches. A tool
+ such as CVS with features that provide group-like functionality would
+ be a huge help.
+
+53. I'd suggest a way to notify users if/when a file(s) is being worked on.
+ I suggest:
+ + Always checkout/update files a readonly.
+ + To work on a file, the user should do:
+ cvs advise filename
+ + This would maintain their email address associated with that
+ file name in the repository and change the file mode to writable.
+ + If other references to that file exist, the registered individuals
+ are notified via email that another user(s) is going to be working
+ on same.
+ + When a committ occurs, the user is automatically 'unadvise'd (the
+ inverse command should be supported as well) and other's are notified
+ that a merge will be necessary before their checkin can be
+ successful.
+
+56. There should be a .cvsrc file that is sourced to customize various
+ variables. Perhaps there should be a system-wide .cvsrc file that is
+ sourced, then the one in one's home directory, then the environment
+ variables are checked for overriding values.
+
+62. Consider using revision controlled files and directories to handle the
+ new module format -- consider a cvs command front-end to
+ add/delete/modify module contents, maybe.
+
+63. The "import" and vendor support commands (co -j) need to be documented
+ better.
+
+64. Need to greatly increase the performance of an initial checkout.
+ [[ it got better, then we added functionality, making it worse again ]]
+
+66. Length of the CVS temporary files must be limited to 14 characters for
+ System-V stupid support. As weel as the length on the CVS.adm files.
+
+67. cvs import should populate the vendor sources with CVS.adm files so
+ that one could use the vendor sources directly without having the check
+ them out.
+
+69. Consider enhacing import to add a module automatically to the module
+ database. Perhaps with a new option, or perhaps with an editor.
+
+72. Consider re-design of the module -o, -i, -t options to use the file
+ system more intuitively.
+
+73. Consider an option (in .cvsrc?) to automatically add files that are new
+ and specified to commit.
+
+74. Consider adding a way to remove directories/files that you are done
+ with... somehow.
+ [[ cvs release sort of does this ]]
+
+76. Consider adding a layer of abstraction so that CVS can work with both
+ RCS and SCCS files. Larry says this should be #ifdef'ed.
+
+79. Might be nice to have some sort of interface to TFS and tagged
+ revisions.
+
+82. Maybe the import stuff should allow an arbitrary revision to be
+ specified.
+
+84. Improve the documentation about administration of the repository and
+ how to add/remove files and the use of symbolic links.
+
+85. Add revision controlled symbolic links to CVS using one of the tag
+ fields in the RCS file.
+
+87. Consider renaming directories and files.
+
+88. Consider using mmap to read files on Sun systems and using a smaller
+ buffer to read files on other systems. A patch has been supplied.
+
+89. Study the new Dick Grune version of CVS and port any new interesting
+ features to my version of CVS.
+
+91. Better document the format of the source repository and how one might
+ convert their current SCCS or RCS files into CVS format.
+
+92. Look into this:
+ After a bit of soul searching via dbx, I realized my sin was that I'd
+ specified "echo" as the program to call from loginfo. The commit
+ procedure worked fine till it hit my echo, then silently aborted
+ leaving the lockfiles intact. Since I needn't use the loginfo
+ facility, I simply removed those commands and it all works.
+
+93. Need to think hard about release and development environments. Think
+ about execsets as well.
+
+94. Need to think hard about remote source control and environments
+ together.
+ [[ a contributor has this working over Internet TCP links! ]]
+
+97. Think about some way to undo a change. This looks hard given the
+ current framework of CVS.
+
+98. If diff3 bombs out (too many differences) cvs then thinks that the file
+ has been updated and is OK to be commited even though the file
+ has not yet been merged.
+
+100. Checked out files should have revision control support. Maybe.
+
+102. Perhaps directory modes should be propagated on all import check-ins.
+ Not necessarily uid/gid changes.
+
+103. setuid/setgid on files is suspect.
+
+104. cvs should recover nicely on unreadable files/directories.
+
+105. cvs should have administrative tools to allow for changing permissions
+ and modes and what not.
+
+106. Need to figure out how to delete and rename directories from a release
+ and yet have old releases still be accessible.
+
+107. It should be possible to specify a list of symbolic revisions to
+ checkout such that the list is processed in reverse order looking for
+ matches within the RCS file for the symbolic revision. If there is
+ not a match, the next symbolic rev on the list is checked, and so on,
+ until all symbolic revs are exhausted. This would allow one to, say,
+ checkout "4.0" + "4.0.3" + "4.0.3Patch1" + "4.0.3Patch2" to get the
+ most recent 4.x stuff. This is usually handled by just specifying the
+ right release_tag, but most people forget to do this.
+
+108. If someone creates a whole new directory (i.e. adds it to the cvs
+ repository) and you happen to have a directory in your source farm by
+ the same name, when you do your cvs update -d it SILENTLY does
+ *nothing* to that directory. At least, I think it was silent;
+ certainly, it did *not* abort my cvs update, as it would have if the
+ same thing had happened with a file instead of a directory.
+
+109. I had gotten pieces of the sys directory in the past but not a
+ complete tree. I just did something like:
+
+ cvs get *
+
+ Where sys was in * and got the message
+
+ cvs get: Executing 'sys/tools/make_links sys'
+ sh: sys/tools/make_links: not found
+
+ I suspect this is because I didn't have the file in question,
+ but I do not understand how I could fool it into getting an
+ error. I think a later cvs get sys seemed to work so perhaps
+ something is amiss in handling multiple arguments to cvs get?
+
+112. When merging in changes (Glist) and the file ends up exactly as the
+ RCS revision, an "M" is displayed as the "cvs update" output. This
+ should really just be a "U". Just an optimization.
+
+113. The "cvs update" command should tee its output to a log file in ".".
+
+114. I wanted to check in my metapreen code tonight, which I had put into
+ a new file called preen.c. So, recalling your excellent instructions,
+ I typed "cvs add preen.c". However, cvs complained that there was
+ already a preen.c in /master/etc/fsck/Attic and therefore it wouldn't
+ take mine. Now what?
+
+115. I still think "cvs modules" is a good idea.
+ Since everything else is inside cvs, "mkmodules" should be in there too:
+
+ Add a "modules" (synonym "mod") command directly in cvs.
+ ("checkout -c" is not really intuitive. I'd move it into "mod -s".)
+
+ "mod" Print database as typed. (line count as record id?)
+ "mod -s" Print the sorted database (as "checkout -c" does now)
+ "mod -m" Internal replacement for "mkmodules" command.
+ "mod module ..." Print the raw dbm record for the named modules
+ "mod -p module ..." Print relative filenames contained in modules.(no ",v")
+ "mod -l module ..." Prints more info about relative filenames ("ls -l"?)
+ "mod -f file ..." Tells you what module(s) the filenames are in.
+
+116. The first thing import did was to complain about a missing CVSROOT.adm.
+ How about having "import()" copy some "CVSROOT.adm/{loginfo,modules}"
+ templates into place if it discovers none pointed to by $CVSROOT? As it
+ stands, one has to hand-craft them. It would be real nice to have it
+ happen automatically.
+ [[ I hope to add a "cvsinit" command to the installation instructions ]]
+
+119. Consider an option to have import checkout the RCS or SCCS files
+ if necessary.
+
+122. If Name_Repository fails, it currently causes CVS to die completely. It
+ should instead return NULL and have the caller do something reasonable.
+
+123. Add a flag to import to not build vendor branches for local code.
+
+124. Anyway, I thought you might want to add something like the following
+ to the cvs and mkmodules man pages:
+
+ BUGS
+ The sum of the sizes of a module key and its contents are
+ limited. See ndbm(3).
+
+126. Do an analysis to see if CVS is forgetting to close file descriptors.
+ Especially when committing many files (more than the open file limit
+ for the particular UNIX).
+
+127. Look at *info files; they should all be quiet if the files are not
+ there. Should be able to point at a RCS directory and go.
+
+128. When I tag a file, the message tells me that I'm tagging a directory.
+
+129. Something strange seems to have happened here. When I check this out,
+ the update lines (U CFTS/...) seem to report a bogus leading CFTS
+ (e.g. U CFTS/Medusa_TS/...) when the later files are checked out.
+
+ The directory structure doesn't seem to be botched, just the
+ messages. I don't recall seeing this before.
+
+130. cvs diff with no -r arguments does not need to look up the current RCS
+ version number since it only cares about what's in the Entries file.
+ This should make it much faster.
+
+ It should ParseEntries itself and access the entries list much like
+ Version_TS does (sticky tags and sticky options may need to be
+ supported here as well). Then it should only diff the things that
+ have the wrong time stamp (the ones that look modified).
+
+134. Make a statement about using hard NFS mounts to your source
+ repository. Look into checking NULL fgets() returns with ferror() to
+ see if an error had occurred.
+
+135. The email CVS sends with each checkin, should include the version
+ number of each file it is checking in.
+ [[ Sort of solved by contrib/log.pl, which does a good job of this ]]
+
+136. Is it possible to specify a command to be run on each file when it is
+ checked out and another command to be run before it is checked in?
+ My idea of how this feature would be used:
+ On checkout:
+ run indent with user's preferred style
+ On checkin:
+ run indent with space-saving, style-free for checkin
+
+137. Some sites might want CVS to fsync() the RCS ,v file to protect
+ against nasty hardware errors. There is a slight performance hit with
+ doing so, though, so it should be configurable in the .cvsrc file.
+ Also, along with this, we should look at the places where CVS itself
+ could be a little more synchronous so as not to lose data.
+ [[ I've done some of this, but it could use much more ]]
+
+138. Some people have suggested that CVS use a VPATH-like environment
+ variable to limit the amount of sources that need to be duplicated for
+ sites with giant source trees and no disk space.
+
+139. murf@dingus.sps.mot.com (Steve Murphy) suggests adding a mode where
+ CVS can work across e-mail to a single repository located at some
+ "known" mail address. The update/commit operations would work through
+ email aliases, causing them to be slow, but would work nonetheless.
+ This could allow for very cheap remote development sites.
+ [[ We may get to TCP connections over the Internet for the next
+ release, but probably won't do an e-mail linkup right away ]]
+
+141. Import should accept modules as its directory argument.
+
+143. Update the documentation to show that the source repository is
+ something far away from the files that you work on.
+
+144. Have cvs checkout look for the environment variable CVSPREFIX
+ (or CVSMODPREFIX or some such). If it's set, then when looking
+ up an alias in the modules database, first look it up with the
+ value of CVSPREFIX attached, and then look for the alias itself.
+ This would be useful when you have several projects in a single
+ repository. You could have aliases abc_src and xyz_src and
+ tell people working on project abc to put "setenv CVSPREFIX abc_"
+ in their .cshrc file (or equivalent for other shells).
+ Then they could do "cvs co src" to get a copy of their src
+ directory, not xyz's. (This should create a directory called
+ src, not abc_src.)
+
+145. After you create revision 1.1.1.1 in the previous scenario, if
+ you do "cvs update -r1 filename" you get revision 1.1, not
+ 1.1.1.1. It would be nice to get the later revision. Again,
+ this restriction comes from RCS and is probably hard to
+ change in CVS. Sigh.
+
+ |"cvs update -r1 filename" does not tell RCS to follow any branches. CVS
+ |tries to be consistent with RCS in this fashion, so I would not change
+ |this. Within CVS we do have the flexibility of extending things, like
+ |making a revision of the form "-r1HEAD" find the most recent revision
+ |(branch or not) with a "1." prefix in the RCS file. This would get what
+ |you want maybe.
+
+ This would be very useful. Though I would prefer an option
+ such as "-v1" rather than "-r1HEAD". This option might be
+ used quite often.
+
+146. The merging of files should be controlled via a hook so that programs
+ other than "rcsmerge" can be used, like Sun's filemerge or emacs's
+ emerge.el.
+
+148. It would be nice if cvs import (and perhaps commit when the rcs file
+ is created) would set the comment leader automagically to the prefix
+ string of $Log entry, if some option is given. For example, if a file
+ has a line `%*&# $Log...' the comment leader would be set to `%*&# '.
+ It would help a lot for unknown files with unknown suffix, and if the
+ comment leader is not standard. Perhaps for cvs 1.4.
+
+149. On Sun, 2 Feb 92 22:01:38 EST, rouilj@dl5000.bc.edu (John P. Rouillard)
+ said:
+ Maybe there should be an option to cvs admin that allows a user to
+ change the Repository file with some degree of error checking?
+ Something like "cvs admin reposmv /old/path /new/pretty/path". Before
+ it does the replace it check to see that the files
+ /new/pretty/path/<dir>/<files> exist.
+
+150. I have a customer request for a way to specify log message per
+ file, non-interactively before the commit, such that a single, fully
+ recursive commit prompts for one commit message, and concatenates the
+ per file messages for each file. In short, one commit, one editor
+ session, log messages allowed to vary across files within the commit.
+ Also, the per file messages should be allowed to be written when the
+ files are changed, which may predate the commit considerably.
+
+ A new command seems appropriate for this. The state can be saved in the
+ CVS directory. I.e.,
+
+ % cvs msg foo.c
+ Enter log message for foo.c
+ >> fixed an uninitialized variable
+ >> ^D
+
+ The text is saved as CVS/foo.c,m (or some such name) and commit is
+ modified to append (prepend?) the text (if found) to the log message
+ specified at commit time. Easy enough.
+
+151. Also, is there a flag I am missing that allows replacing Ulrtx_Build
+ by Ultrix_build? I.E. I would like a tag replacement to be a one step
+ operation rather than a two step "cvs rtag -r Ulrtx_Build Ultrix_Build"
+ followed by "cvs trag -d Ulrtx_Build"
+
+152. The "cvs -n" option does not work as one would expect for all the
+ commands. In particular, for "commit" and "import", where one would
+ also like to see what it would do, without actually doing anything.
+
+153. There should be some command (maybe I just haven't figured
+ out which one...) to import a source directory which is already
+ RCS-administered without losing all prior RCS gathered data. Thus, it
+ would have to examine the RCS files and choose a starting version and
+ branch higher than previous ones used.
+
+154. When committing the modules file, a pre-commit check should be done to
+ verify the validity of the new modules file before allowing it to be
+ committed. This could easily be done by adding an option to mkmodules
+ to perform the verification.
+
+155. The options for "cvs history" are mutually exclusive, even though
+ useful queries can be done if they are not, as in specifying both a
+ module and a tag. A workaround is to specify the module, then run the
+ output through grep to only display lines that begin with T, which are
+ tag lines.
+
+156. Also, how hard would it be to allow continuation lines in the
+ {commit,rcs,log}info files? It would probably be useful with all of
+ the various flags that are now available, or if somebody has a lot of
+ files to put into a module.
+
+157. The "cvs release" command does not understand about module names with
+ the same flexibility that the "checkout" and "rdiff" commands do.
+ It should, though, since it's confusing right now.
+
+158. If I do a recursive commit and find that the same RCS file is checked
+ out (and modified!) in two different places within my checked-out
+ files (but within the realm of a single "commit"), CVS will commit the
+ first change, then overwrite that change with the second change. We
+ should catch this (typically unusual) case and issue an appropriate
+ diagnostic and die.
+
+159. On "update", when a merge is done, CVS should remember that your file
+ was merged into and should keep reminding you of this fact until you
+ actually look at the file (change its access time). Once you do this,
+ it should go back to being a normal, unmodified file. This way, after
+ a big update, you can run update again to see which files just got
+ merged and may need attention.
+
+160. The checks that the commit command does should be extended to make
+ sure that the revision that we will lock is not already locked by
+ someone else. Maybe it should also lock the new revision if the old
+ revision was already locked by the user as well, thus moving the lock
+ forward after the commit.
+
+161. The date parser included with CVS (lib/getdate.y) does not support
+ such RCS-supported dates as "1992/03/07". It probably should.
+
+162. We have had a number of cases where some idiot does a "cd" into $CVSROOT
+ and tries to run checkout. I suggest you make it impossible for someone
+ to check out anything directly into $CVSROOT. This works (though there
+ is no error checking):
+
+ getwd(curdir);
+ chdir(getenv("CVSROOT"));
+ getwd(cvsrootdir);
+ strcat(cvsrootdir, "/");
+ chdir(curdir);
+
+ if (!strncmp (curdir, cvsrootdir, strlen(cvsrootdir))) {
+ abort with a nasty message about writing into the repository.
+ }
+
+ (In other words, if the real path where $CVSROOT is stored is a parent of
+ the real pathname of your current directory, die horribly.)
+
+163. The rtag/tag commands should have an option that removes the specified
+ tag from any file that is in the attic. This allows one to re-use a
+ tag (like "Mon", "Tue", ...) all the time and still have it tag the
+ real main-line code.
+
+164. The rcsinfo file should be able to expand environment variables to
+ find the pathname to the template file. Perhaps it should just
+ popen("cat <line>"); and read the resulting output, to let the shell
+ do the dirty work.
+
+165. The "import" command will create RCS files automatically, but will
+ screw-up when trying to create long file names on short file name
+ file systems. Perhaps import should be a bit more cautious.
+
+166. There really needs to be a "Getting Started" document which describes
+ some of the new CVS philosophies. Folks coming straight from SCCS or
+ RCS might be confused by "cvs import". Also need to explain:
+ - How one might setup their $CVSROOT
+ - What all the tags mean in an "import" command
+ - Tags are important; revision numbers are not
+
+167. "cvs log" doesn't understand about CVS magic branch numbers. As such,
+ the command:
+
+ cvs log -r1.63.2
+ cvs log -rC2
+
+ where "C2" is a magic branch that resolves to 1.63.2 do not print the
+ same things. Sigh.
+
+168. After making changes to a set of files, some of which were in
+ sub-directories, I wanted to build a patch file for the whole works:
+
+ cvs diff -c -rPROD-REL .
+
+ However, any diffs for files in sub-directories did not have relative
+ pathnames. For example, with local changes to perl's hints/aix_rs.sh:
+
+ ===================================================================
+ RCS file: /local/src-CVS/misc/perl/hints/aix_rs.sh,v
+ retrieving revision 1.1.1.1
+ diff -c -r1.1.1.1 aix_rs.sh
+ *** 1.1.1.1 1992/12/17 19:43:32
+ --- aix_rs.sh 1993/01/05 21:33:12
+ ***************
+ *** 1,3 ****
+
+ It was easy enough to fix in this case, but I'd suggest that the file
+ name have the relative directory prepended and a proper patch "Index:"
+ line be added, such as this:
+
+ ===================================================================
+ RCS file: /local/src-CVS/misc/perl/hints/aix_rs.sh,v
+ retrieving revision 1.1.1.1
+ diff -c -r1.1.1.1 hints/aix_rs.sh
+ Index: hints/aix_rs.sh
+ *** 1.1.1.1 1992/12/17 19:43:32
+ --- hints/aix_rs.sh 1993/01/05 21:33:12
+ ***************
+ *** 1,3 ****
+
+169. We are using CVS as the configuration control for a software reuse library.
+ What we do is do system calls passing the needed arguments. In the next
+ release, it would be nice to see an option to put cvs .o files into a
+ archive library with an API. This enhancement would go nicely with the
+ notion of being able to integrate tools into a large software engineering
+ environment.
+
+170. Is there an "info" file that can be invoked when a file is checked out, or
+ updated ? What I want to do is to advise users, particularly novices, of
+ the state of their working source whenever they check something out, as
+ a sanity check.
+
+ For example, I've written a perl script which tells you what branch you're
+ on, if any. Hopefully this will help guard against mistaken checkins to
+ the trunk, or to the wrong branch. I suppose I can do this in
+ "commitinfo", but it'd be nice to advise people before they edit their
+ files.
+
+ It would also be nice if there was some sort of "verboseness" switch to
+ the checkout and update commands that could turn this invocation of the
+ script off, for mature users.
+
+171. We have been actively using CVS since September, and we still have the
+ opinion that automerge is dangerous. We have been burned by it a
+ couple of times so far, when people missed the notification of a
+ conflict during an update, and then they committed the files with the
+ >>>>>>> and <<<<<<< reports in them. This kind of problem usually gets
+ noticed before commit in compiled files when the compiler croaks, but
+ we also maintain many documentation files in CVS, and in one case the
+ problem was not noticed until months later.
+
+172. "cvs add foo/bar" doesn't work, but "cvs remove foo/bar" works. Maybe
+ "cvs add" should be rewritten to use the recursive directory code that
+ most of CVS uses.
+
+173. We have a tagged branch in CVS. How do we get the version of that branch
+ (for an entire directory) that corresponds to the files on that branch on a
+ certain day? I'd like to specify BOTH -r and -D to 'cvs checkout', but I
+ can't. It looks like I can only specify the date for the main line (as
+ opposed to any branches). True? Any workarounds to get what I need?
+
+174. I would like to see "cvs release" modified so that it only removes files
+ which are known to CVS - all the files in the repository, plus those which
+ are listed in .cvsignore. This way, if you do leave something valuable in
+ a source tree you can "cvs release -d" the tree and your non-CVS goodies
+ are still there. If a user is going to leave non-CVS files in their source
+ trees, they really should have to clean them up by hand.
+
+175. And, in the feature request department, I'd dearly love a command-line
+ interface to adding a new module to the CVSROOT/modules file.
+
+176. If you use the -i flag in the modules file, you can control access
+ to source code; this is a Good Thing under certain circumstances. I
+ just had a nasty thought, and on experiment discovered that the
+ filter specified by -i is _not_ run before a cvs admin command; as
+ this allows a user to go behind cvs's back and delete information
+ (cvs admin -o1.4 file) this seems like a serious problem.
+
+177. We've got some external vendor source that sits under a source code
+ hierarchy, and when we do a cvs update, it gets wiped out because
+ its tag is different from the "main" distribution. I've tried to
+ use "-I" to ignore the directory, as well as .cvsignore, but this
+ doesn't work.
+
+178. At our site we tag all releases of the sw with
+ product name and version number, the tag is pretty
+ long and if you by accident write an old tag which
+ was in use on an old release, the default behaviour
+ of cvs is to change the old tag!!!
+
+ Could the CVS system reject to reuse an old tag?
+ You have the possibility to manually remove it,
+ but you will not have to be afraid of one tag
+ silently changing.
+
+179. "cvs admin" does not log its actions with loginfo, nor does it check
+ whether the action is allowed with commitinfo. It should.
diff --git a/gnu/usr.bin/cvs/contrib/clmerge b/gnu/usr.bin/cvs/contrib/clmerge
new file mode 100644
index 0000000..1a29311
--- /dev/null
+++ b/gnu/usr.bin/cvs/contrib/clmerge
@@ -0,0 +1,156 @@
+#!/usr/local/bin/perl
+
+# Merge conflicted ChangeLogs
+# tromey Mon Aug 15 1994
+
+# Due to popular demand, I'm posting my ChangeLog auto-merge tool. Run
+# this on your ChangeLog files when an update leaves them conflicted.
+# The code is appended.
+#
+# Usage is:
+#
+# cl-merge [-i] file ...
+#
+# With -i, it works in place (backups put in a ~ file). Otherwise the
+# merged ChangeLog is printed to stdout.
+#
+# Style comments are welcome. This is my third perl program ever.
+#
+# Please report any bugs to me. I wrote this yesterday, so there are no
+# guarantees about its performance. I recommend checking its output
+# carefully. If you do send a bug report, please includie the failing
+# ChangeLog, so I can include it in my test suite.
+#
+# Tom
+# ---
+# tromey@busco.lanl.gov Member, League for Programming Freedom
+# Sadism and farce are always inexplicably linked.
+# -- Alexander Theroux
+
+# If '-i' is given, do it in-place.
+if ($ARGV[0] eq '-i') {
+ shift (@ARGV);
+ $^I = '~';
+}
+
+$lastkey = '';
+$lastval = '';
+$conf = 0;
+%conflist = ();
+
+$tjd = 0;
+
+# Simple state machine. The states:
+#
+# 0 Not in conflict. Just copy input to output.
+# 1 Beginning an entry. Next non-blank line is key.
+# 2 In entry. Entry beginner transitions to state 1.
+while (<>) {
+ if (/^<<<</ || /^====/) {
+ # Start of a conflict.
+
+ # Copy last key into array.
+ if ($lastkey ne '') {
+ $conflist{$lastkey} = $lastval;
+
+ $lastkey = '';
+ $lastval = '';
+ }
+
+ $conf = 1;
+ } elsif (/^>>>>/) {
+ # End of conflict. Output.
+
+ # Copy last key into array.
+ if ($lastkey ne '') {
+ $conflist{$lastkey} = $lastval;
+
+ $lastkey = '';
+ $lastval = '';
+ }
+
+ foreach (reverse sort clcmp keys %conflist) {
+ print STDERR "doing $_" if $tjd;
+ print $_;
+ print $conflist{$_};
+ }
+
+ $lastkey = '';
+ $lastval = '';
+ $conf = 0;
+ %conflist = ();
+ } elsif ($conf == 1) {
+ # Beginning an entry. Skip empty lines. Error if not a real
+ # beginner.
+ if (/^$/) {
+ # Empty line; just skip at this point.
+ } elsif (/^[MTWFS]/) {
+ # Looks like the name of a day; assume opener and move to
+ # "in entry" state.
+ $lastkey = $_;
+ $conf = 2;
+ print STDERR "found $_" if $tjd;
+ } else {
+ die ("conflict crosses entry boundaries: $_");
+ }
+ } elsif ($conf == 2) {
+ # In entry. Copy into variable until we see beginner line.
+ if (/^[MTWFS]/) {
+ # Entry beginner line.
+
+ # Copy last key into array.
+ if ($lastkey ne '') {
+ $conflist{$lastkey} = $lastval;
+
+ $lastkey = '';
+ $lastval = '';
+ }
+
+ $lastkey = $_;
+ print STDERR "found $_" if $tjd;
+ $lastval = '';
+ } else {
+ $lastval .= $_;
+ }
+ } else {
+ # Just copy.
+ print;
+ }
+}
+
+%months = ('Jan', 0,
+ 'Feb', 1,
+ 'Mar', 2,
+ 'Apr', 3,
+ 'May', 4,
+ 'Jun', 5,
+ 'Jul', 6,
+ 'Aug', 7,
+ 'Sep', 8,
+ 'Oct', 9,
+ 'Nov', 10,
+ 'Dec', 11);
+
+# Compare ChangeLog time strings like <=>.
+#
+# 0 1 2 3
+# Thu Aug 11 13:22:42 1994 Tom Tromey (tromey@creche.colorado.edu)
+# 0123456789012345678901234567890
+#
+sub clcmp {
+ # First check year.
+ $r = substr ($a, 20, 4) <=> substr ($b, 20, 4);
+
+ # Now check month.
+ $r = $months{$a} <=> $months{$b} if !$r;
+
+ # Now check day.
+ $r = substr ($a, 8, 2) <=> substr ($b, 8, 2) if !$r;
+
+ # Now check time (3 parts).
+ $r = substr ($a, 11, 2) <=> substr ($b, 11, 2) if !$r;
+ $r = substr ($a, 14, 2) <=> substr ($b, 14, 2) if !$r;
+ $r = substr ($a, 17, 2) <=> substr ($b, 17, 2) if !$r;
+
+ $r;
+}
diff --git a/gnu/usr.bin/cvs/contrib/cvs-format.el b/gnu/usr.bin/cvs/contrib/cvs-format.el
new file mode 100644
index 0000000..5e70429
--- /dev/null
+++ b/gnu/usr.bin/cvs/contrib/cvs-format.el
@@ -0,0 +1,75 @@
+;; -*- lisp-interaction -*-
+;; -*- emacs-lisp -*-
+;;
+;;
+;; originally from...
+;; Rich's personal .emacs file. feel free to copy.
+;;
+;; Last Mod Wed Feb 5 16:11:47 PST 1992, by rich@cygnus.com
+;;
+
+;;
+;;
+;; This section sets constants used by c-mode for formating
+;;
+;;
+
+
+;; If `c-auto-newline' is non-`nil', newlines are inserted both
+;;before and after braces that you insert, and after colons and semicolons.
+;;Correct C indentation is done on all the lines that are made this way.
+
+(setq c-auto-newline nil)
+
+
+;;*Non-nil means TAB in C mode should always reindent the current line,
+;;regardless of where in the line point is when the TAB command is used.
+;;It might be desirable to set this to nil for CVS, since unlike GNU
+;; CVS often uses comments over to the right separated by TABs.
+;; Depends some on whether you're in the habit of using TAB to
+;; reindent.
+;(setq c-tab-always-indent nil)
+
+;; C does not have anything analogous to particular function names for which
+;;special forms of indentation are desirable. However, it has a different
+;;need for customization facilities: many different styles of C indentation
+;;are in common use.
+;;
+;; There are six variables you can set to control the style that Emacs C
+;;mode will use.
+;;
+;;`c-indent-level'
+;; Indentation of C statements within surrounding block. The surrounding
+;; block's indentation is the indentation of the line on which the
+;; open-brace appears.
+
+(setq c-indent-level 4)
+
+;;`c-continued-statement-offset'
+;; Extra indentation given to a substatement, such as the then-clause of
+;; an if or body of a while.
+
+(setq c-continued-statement-offset 4)
+
+;;`c-brace-offset'
+;; Extra indentation for line if it starts with an open brace.
+
+(setq c-brace-offset -4)
+
+;;`c-brace-imaginary-offset'
+;; An open brace following other text is treated as if it were this far
+;; to the right of the start of its line.
+
+(setq c-brace-imaginary-offset 0)
+
+;;`c-argdecl-indent'
+;; Indentation level of declarations of C function arguments.
+
+(setq c-argdecl-indent 4)
+
+;;`c-label-offset'
+;; Extra indentation for line that is a label, or case or default.
+
+(setq c-label-offset -4)
+
+;;;; eof
diff --git a/gnu/usr.bin/cvs/contrib/intro.doc b/gnu/usr.bin/cvs/contrib/intro.doc
new file mode 100644
index 0000000..a6d4ec1
--- /dev/null
+++ b/gnu/usr.bin/cvs/contrib/intro.doc
@@ -0,0 +1,112 @@
+Date: Tue, 16 Jun 1992 17:05:23 +0200
+From: Steven.Pemberton@cwi.nl
+Message-Id: <9206161505.AA06927.steven@sijs.cwi.nl>
+To: berliner@Sun.COM
+Subject: cvs
+
+INTRODUCTION TO USING CVS
+
+ CVS is a system that lets groups of people work simultaneously on
+ groups of files (for instance program sources).
+
+ It works by holding a central 'repository' of the most recent version
+ of the files. You may at any time create a personal copy of these
+ files; if at a later date newer versions of the files are put in the
+ repository, you can 'update' your copy.
+
+ You may edit your copy of the files freely. If new versions of the
+ files have been put in the repository in the meantime, doing an update
+ merges the changes in the central copy into your copy.
+ (It can be that when you do an update, the changes in the
+ central copy clash with changes you have made in your own
+ copy. In this case cvs warns you, and you have to resolve the
+ clash in your copy.)
+
+ When you are satisfied with the changes you have made in your copy of
+ the files, you can 'commit' them into the central repository.
+ (When you do a commit, if you haven't updated to the most
+ recent version of the files, cvs tells you this; then you have
+ to first update, resolve any possible clashes, and then redo
+ the commit.)
+
+USING CVS
+
+ Suppose that a number of repositories have been stored in
+ /usr/src/cvs. Whenever you use cvs, the environment variable
+ CVSROOT must be set to this (for some reason):
+
+ CVSROOT=/usr/src/cvs
+ export CVSROOT
+
+TO CREATE A PERSONAL COPY OF A REPOSITORY
+
+ Suppose you want a copy of the files in repository 'views' to be
+ created in your directory src. Go to the place where you want your
+ copy of the directory, and do a 'checkout' of the directory you
+ want:
+
+ cd $HOME/src
+ cvs checkout views
+
+ This creates a directory called (in this case) 'views' in the src
+ directory, containing a copy of the files, which you may now work
+ on to your heart's content.
+
+TO UPDATE YOUR COPY
+
+ Use the command 'cvs update'.
+
+ This will update your copy with any changes from the central
+ repository, telling you which files have been updated (their names
+ are displayed with a U before them), and which have been modified
+ by you and not yet committed (preceded by an M). You will be
+ warned of any files that contain clashes, the clashes will be
+ marked in the file surrounded by lines of the form <<<< and >>>>.
+
+TO COMMIT YOUR CHANGES
+
+ Use the command 'cvs commit'.
+
+ You will be put in an editor to make a message that describes the
+ changes that you have made (for future reference). Your changes
+ will then be added to the central copy.
+
+ADDING AND REMOVING FILES
+
+ It can be that the changes you want to make involve a completely
+ new file, or removing an existing one. The commands to use here
+ are:
+
+ cvs add <filename>
+ cvs remove <filename>
+
+ You still have to do a commit after these commands. You may make
+ any number of new files in your copy of the repository, but they
+ will not be committed to the central copy unless you do a 'cvs add'.
+
+OTHER USEFUL COMMANDS AND HINTS
+
+ To see the commit messages for files, and who made them, use:
+
+ cvs log [filenames]
+
+ To see the differences between your version and the central version:
+
+ cvs diff [filenames]
+
+ To give a file a new name, rename it and do an add and a remove.
+
+ To lose your changes and go back to the version from the
+ repository, delete the file and do an update.
+
+ After an update where there have been clashes, your original
+ version of the file is saved as .#file.version.
+
+ All the cvs commands mentioned accept a flag '-n', that doesn't do
+ the action, but lets you see what would happen. For instance, you
+ can use 'cvs -n update' to see which files would be updated.
+
+MORE INFORMATION
+
+ This is necessarily a very brief introduction. See the manual page
+ (man cvs) for full details.
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/NEWS b/gnu/usr.bin/cvs/contrib/pcl-cvs/NEWS
new file mode 100644
index 0000000..4f563ff
--- /dev/null
+++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/NEWS
@@ -0,0 +1,113 @@
+This is the NEWS file for pcl-cvs, an Elisp front-end to CVS.
+
+User-visible changes in pcl-cvs from 1.04 to 1.05:
+
+* Elib is no longer distributed with pcl-cvs. You must get Elib
+ separately, for instance from ftp.lysator.liu.se in pub/emacs.
+
+* The Lucid Emacs support works again.
+
+* A new function, cvs-change-cvsroot, can be used to interactively
+ switch between CVS repositories.
+
+* The mode line in the *cvs* buffer now indicates when a "cvs update"
+ is running.
+
+* The .cvsignore file is automatically sorted alphabetically (to
+ reduce the risk of conflicts when two people add different files
+ simultaneously). This behaviour can be turned off with
+ cvs-sort-ignore-file.
+
+* A trailing newline is always added in commit log messages. This
+ behaviour can be turned off with
+ cvs-commit-buffer-require-final-newline.
+
+* This version of pcl-cvs should work together with RCVS. I have not
+ tested this myself, though.
+
+* Plus some bug fixes. (Note that the version of cookie.el that is
+ distributed with pcl-cvs 1.04 contains errors that affects pcl-cvs.
+ You should get Elib 0.07).
+
+
+User-visible changes in pcl-cvs from 1.03 to 1.04:
+
+* Support for Emerge. Hitting "e" on a file that is Modified, Merged
+ or in Conflict will start Emerge, an interactive file merger written
+ in Emacs Lisp. This requires Emerge version 4. Emerge is not
+ included in this package. If you can't find it anywhere else, you
+ can get in from ftp.lysator.liu.se in pub/emacs. This package makes
+ it a lot easier to resolve conflicts.
+
+* Emacs will now automatically revert your buffers when the CVS
+ commands pcl-cvs issues causes the file to change. This automatic
+ revert never occurs if the buffer contents did not agree with the
+ file prior to the command.
+
+* If you are running Lucid GNU Emacs, you will get some fonts and
+ mouse support. This was contributed from people at Lucid.
+
+* The variable cvs-cvsroot can be used to select the location if the
+ repository. You no longer need to exit Emacs, setenv CVSROOT, and
+ start a new Emacs if you work with multiple repositories.
+
+* The "q" key can be used to hide the *cvs* buffer.
+
+* The name of the commands in the *cvs* have changed. If it was called
+ cvs-foo, it will now be called cvs-mode-foo. See the ChangeLog
+ entry from Tue Aug 4 03:02:25 1992 for a complete list of changes.
+
+* The variable cvs-cvs-diff-flags is no longer used. Instead,
+ cvs-diff-flags is always used.
+
+* Plus a lot of bug fixes.
+
+
+User-visible changes in pcl-cvs from 1.02 to 1.03:
+
+* Output from CVS to stdout and stderr is separated and parsed
+ independently. In that way pcl-cvs should work regardless of
+ whether stdout is buffered or line-buffered. Pcl-cvs should now
+ work with CVS 1.3 without modifications on hosts such as
+ DECstations.
+
+* Pcl-cvs now fully supports RCS version 5.6 as well as 5.5.
+
+* New functions:
+
+ + cvs-undo-local-changes ("U") - Undo all your modifications
+ to a file and get the newest
+ version from the repository.
+ + cvs-update-other-window - Similar to cvs-update.
+ + cvs-byte-compile-files - Byte compile the selected files.
+
+* cvs-update now displays the *cvs* buffer, which initially contains a
+ small message ("Running `cvs update' in /foo/bar/gazonk/...") until
+ the update is ready. The *cvs* buffer no longer pops up when the
+ update is ready. It often failed to pop up, due to race conditions
+ that are very hard to solve (and I doubt that they were at all
+ solvable).
+
+* cvs-unmark-all-files is moved from "U" to "ESC DEL" to be
+ "compatible" with dired.
+
+* cvs-diff ("d") and cvs-diff-backup ("b") can be configured to work
+ on only the file the cursor is positioned on, and ignore any marked
+ files. A prefix argument toggles this.
+
+* Only one `cvs update' can be run at a time. (It was previously
+ possible to start more than one simultaneously, but pcl-cvs could
+ not really handle more than one.)
+
+* Some rudimentary support for programs that CVS runs at update (due
+ to the -u switch in the modules file).
+
+* Pcl-cvs now automatically generates a bug report if it can't parse
+ the output from CVS.
+
+* The *cvs* buffer is read-only.
+
+* Pcl-cvs now creates temporary files in $TMPDIR if that environment
+ variable is set (otherwise it uses /tmp).
+
+---End of file NEWS---
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-lucid.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-lucid.el
new file mode 100644
index 0000000..d1f69e3
--- /dev/null
+++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-lucid.el
@@ -0,0 +1,133 @@
+;;; Mouse and font support for PCL-CVS 1.3 running in Lucid GNU Emacs
+;; @(#) Id: pcl-cvs-lucid.el,v 1.2 1993/05/31 19:37:34 ceder Exp
+;; Copyright (C) 1992-1993 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+;; This simply adds a menu of the common CVS commands to the menubar and to
+;; the right mouse button. Clicking right moves point, and then pops up a
+;; menu from which commands can be executed.
+;;
+;; This could stand to be a lot more clever: for example, the "Commit Changes"
+;; command should only be active on files for which there is something to
+;; commit. Also, some indication of which files the command applies to
+;; (especially in the presence of multiple marked files) would be nice.
+;;
+;; Middle-click runs find-file.
+
+
+(require 'pcl-cvs)
+
+(defvar cvs-menu
+ '("CVS"
+ ["Find File" cvs-mode-find-file t]
+ ["Find File Other Window" cvs-mode-find-file-other-window t]
+ ["Interactively Merge (emerge)" cvs-mode-emerge t]
+ ["Diff against Repository" cvs-mode-diff-cvs t]
+ ["Diff against Backup Version" cvs-mode-diff-backup t]
+ "----"
+ ["Commit Changes to Repository" cvs-mode-commit t]
+ ["Revert File from Repository" cvs-mode-undo-local-changes t]
+ ["Add File to Repository" cvs-mode-add t]
+ ["Remove File from Repository" cvs-mode-remove-file t]
+ ["Ignore File" cvs-mode-ignore t]
+ ["Hide File" cvs-mode-acknowledge t]
+ ["Hide Handled Files" cvs-mode-remove-handled t]
+ "----"
+ ["Add ChangeLog Entry" cvs-mode-add-change-log-entry-other-window t]
+ ["Show CVS Log" cvs-mode-log t]
+ ["Show CVS Status" cvs-mode-status t]
+ "----"
+ ["Mark File" cvs-mode-mark t]
+ ["Unmark File" cvs-mode-unmark t]
+ ["Mark All Files" cvs-mode-mark-all-files t]
+ ["Unmark All Files" cvs-mode-unmark-all-files t]
+ "----"
+ ["Quit" bury-buffer t]
+ ))
+
+(defun cvs-menu (e)
+ (interactive "e")
+ (mouse-set-point e)
+ (beginning-of-line)
+ (or (looking-at "^[* ] ") (error "No CVS file line here"))
+ (popup-menu cvs-menu))
+
+(defun cvs-mouse-find-file (e)
+ (interactive "e")
+ (mouse-set-point e)
+ (beginning-of-line)
+ (or (looking-at "^[* ] ") (error "No CVS file line here"))
+ (cvs-mode-find-file (point)))
+
+(define-key cvs-mode-map 'button3 'cvs-menu)
+(define-key cvs-mode-map 'button2 'cvs-mouse-find-file)
+
+(make-face 'cvs-header-face)
+(make-face 'cvs-filename-face)
+(make-face 'cvs-status-face)
+
+(or (face-differs-from-default-p 'cvs-header-face)
+ (copy-face 'italic 'cvs-header-face))
+
+(or (face-differs-from-default-p 'cvs-filename-face)
+ (copy-face 'bold 'cvs-filename-face))
+
+(or (face-differs-from-default-p 'cvs-status-face)
+ (copy-face 'bold-italic 'cvs-status-face))
+
+
+(defun pcl-mode-motion-highlight-line (event)
+ (if (save-excursion
+ (let* ((window (event-window event))
+ (buffer (and window (window-buffer window)))
+ (point (and buffer (event-point event))))
+ (and point
+ (progn
+ (set-buffer buffer)
+ (goto-char point)
+ (beginning-of-line)
+ (looking-at "^[* ] ")))))
+ (mode-motion-highlight-line event)))
+
+(defconst pcl-cvs-font-lock-keywords
+ '(("^In directory \\(.+\\)$" 1 cvs-header-face)
+ ("^[* ] \\w+ +\\(ci\\)" 1 cvs-status-face)
+ ("^[* ] \\(Conflict\\|Merged\\)" 1 cvs-status-face)
+ ("^[* ] \\w+ +\\(ci +\\)?\\(.+\\)$" 2 cvs-filename-face)
+ )
+ "Patterns to highlight in the *cvs* buffer.")
+
+(defun pcl-cvs-fontify ()
+ ;;
+ ;; set up line highlighting
+ (require 'mode-motion)
+ (setq mode-motion-hook 'pcl-mode-motion-highlight-line)
+ ;;
+ ;; set up menubar
+ (if (and current-menubar (not (assoc "CVS" current-menubar)))
+ (progn
+ (set-buffer-menubar (copy-sequence current-menubar))
+ (add-menu nil "CVS" (cdr cvs-menu))))
+ ;;
+ ;; fontify mousable lines
+ (set (make-local-variable 'font-lock-keywords) pcl-cvs-font-lock-keywords)
+ (font-lock-mode 1)
+ )
+
+(add-hook 'cvs-mode-hook 'pcl-cvs-fontify)
diff --git a/gnu/usr.bin/cvs/contrib/rcs2log b/gnu/usr.bin/cvs/contrib/rcs2log
new file mode 100644
index 0000000..d790002
--- /dev/null
+++ b/gnu/usr.bin/cvs/contrib/rcs2log
@@ -0,0 +1,326 @@
+#!/bin/sh
+
+# RCS to ChangeLog generator
+
+# Generate a change log prefix from RCS/* and the existing ChangeLog (if any).
+# Output the new prefix to standard output.
+# You can edit this prefix by hand, and then prepend it to ChangeLog.
+
+# Ignore log entries that start with `#'.
+# Clump together log entries that start with `{topic} ',
+# where `topic' contains neither white space nor `}'.
+
+# Author: Paul Eggert <eggert@twinsun.com>
+
+# OrigId: rcs2log,v 1.9 1993/01/15 05:33:29 eggert Exp
+
+# Copyright 1992, 1993 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+# Parse options.
+
+# defaults
+indent=8 # indent of log line
+length=79 # suggested max width of log line
+tabwidth=8 # width of horizontal tab
+
+while :
+do
+ case $1 in
+ -i) indent=${2?};;
+ -l) length=${2?};;
+ -t) tabwidth=${2?};;
+ -*) echo >&2 "$0: usage: $0 [-i indent] [-l length] [-t tabwidth] [file ...]"
+ exit 1;;
+ *) break
+ esac
+ shift; shift
+done
+
+
+# Log into $rlogout the revisions checked in since the first ChangeLog entry.
+
+date=1970
+if test -s ChangeLog
+then
+ # Add 1 to seconds to avoid duplicating most recent log.
+ # It's a good thing `rlog' doesn't mind a time ending in `:60'.
+ e='
+ /^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{
+ printf "%s%02d %s\n", substr($0,1,17), substr($0,18,2)+1, $5
+ exit
+ }
+ '
+ d=`awk "$e" <ChangeLog` || exit
+ case $d in
+ ?*) date=$d
+ esac
+fi
+datearg="-d>$date"
+
+rlogout=/tmp/chg$$
+trap exit 1 2 13 15
+trap 'rm -f $rlogout; exit 1' 0
+
+case $# in
+0) set RCS/*
+esac
+
+rlog "$datearg" "$@" >$rlogout || exit
+
+
+# Get the full name of each author the logs mention, and set initialize_fullname
+# to awk code that initializes the `fullname' awk associative array.
+# Warning: foreign authors (i.e. not known in the passwd file) are mishandled;
+# you have to fix the resulting output by hand.
+
+initialize_fullname=
+authors=`
+ sed -n 's|^date: *[0-9]*/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]; *author: *\([^; ]*\).*|\1|p' <$rlogout |
+ sort -u
+`
+case $authors in
+?*)
+ initialize_author=
+ for author in $authors
+ do
+ initialize_author="$initialize_author
+ author[\"$author\"] = 1
+ "
+ done
+
+ awkscript='
+ BEGIN {
+ alphabet = "abcdefghijklmnopqrstuvwxyz"
+ ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ '"$initialize_author"'
+ }
+ {
+ if (author[$1]) {
+ fullname = $5
+ abbr = index(fullname, "&")
+ if (abbr) {
+ a = substr($1, 1, 1)
+ A = a
+ i = index(alphabet, a)
+ if (i) A = substr(ALPHABET, i, 1)
+ fullname = substr(fullname, 1, abbr-1) A substr($1, 2) substr(fullname, abbr+1)
+ }
+ printf "fullname[\"%s\"] = \"%s\"\n", $1, fullname
+ author[$1] = 0
+ }
+ }
+ '
+
+ initialize_fullname=`
+ (cat /etc/passwd; ypmatch $authors passwd) 2>/dev/null |
+ awk -F: "$awkscript"
+ `
+esac
+
+
+# Function to print a single log line.
+# We don't use awk functions, to stay compatible with old awk versions.
+# `Log' is the log message (with \n replaced by \r).
+# `files' contains the affected files.
+printlogline='{
+
+ # Following the GNU coding standards, rewrite
+ # * file: (function): comment
+ # to
+ # * file (function): comment
+ if (Log ~ /^\([^)]*\): /) {
+ i = index(Log, ")")
+ files = files " " substr(Log, 1, i)
+ Log = substr(Log, i+3)
+ }
+
+ # If "label: comment" is too long, break the line after the ":".
+ sep = " "
+ if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, "\r")) sep = "\n" indent_string
+
+ # Print the label.
+ printf "%s*%s:", indent_string, files
+
+ # Print each line of the log, transliterating \r to \n.
+ while ((i = index(Log, "\r")) != 0) {
+ printf "%s%s\n", sep, substr(Log, 1, i-1)
+ sep = indent_string
+ Log = substr(Log, i+1)
+ }
+}'
+
+hostname=`(
+ hostname || cat /etc/whoami || uuname -l || uname -n
+) 2>/dev/null` || {
+ echo >&2 "$0: cannot deduce hostname"
+ exit 1
+}
+
+
+# Process the rlog output, generating ChangeLog style entries.
+
+# First, reformat the rlog output so that each line contains one log entry.
+# Transliterate \n to \r so that multiline entries fit on a single line.
+# Discard irrelevant rlog output.
+awk <$rlogout '
+ /^Working file:/ { filename = $3 }
+ /^date: /, /^(-----------*|===========*)$/ {
+ if ($0 ~ /^branches: /) { next }
+ if ($0 ~ /^date: [0-9][ /0-9:]*;/) {
+ time = substr($3, 1, length($3)-1)
+ author = substr($5, 1, length($5)-1)
+ printf "%s %s %s %s \r", filename, $2, time, author
+ next
+ }
+ if ($0 ~ /^(-----------*|===========*)$/) { print ""; next }
+ printf "%s\r", $0
+ }
+' |
+
+# Now each line is of the form
+# FILENAME YYYY/MM/DD HH:MM:SS AUTHOR \rLOG
+# where \r stands for a carriage return,
+# and each line of the log is terminated by \r instead of \n.
+# Sort the log entries, first by date+time (in reverse order),
+# then by author, then by log entry, and finally by file name (just in case).
+sort +1 -3r +3 +0 |
+
+# Finally, reformat the sorted log entries.
+awk '
+ BEGIN {
+
+ # Initialize the fullname associative array.
+ '"$initialize_fullname"'
+
+ # Initialize indent string.
+ indent_string = ""
+ i = '"$indent"'
+ if (0 < '"$tabwidth"')
+ for (; '"$tabwidth"' <= i; i -= '"$tabwidth"')
+ indent_string = indent_string "\t"
+ while (1 <= i--)
+ indent_string = indent_string " "
+
+ # Set up date conversion tables.
+ # RCS uses a nice, clean, sortable format,
+ # but ChangeLog wants the traditional, ugly ctime format.
+
+ # January 1, 0 AD (Gregorian) was Saturday = 6
+ EPOCH_WEEKDAY = 6
+ # Of course, there was no 0 AD, but the algorithm works anyway.
+
+ w[0]="Sun"; w[1]="Mon"; w[2]="Tue"; w[3]="Wed"
+ w[4]="Thu"; w[5]="Fri"; w[6]="Sat"
+
+ m[0]="Jan"; m[1]="Feb"; m[2]="Mar"
+ m[3]="Apr"; m[4]="May"; m[5]="Jun"
+ m[6]="Jul"; m[7]="Aug"; m[8]="Sep"
+ m[9]="Oct"; m[10]="Nov"; m[11]="Dec"
+
+ # days in non-leap year thus far, indexed by month (0-12)
+ mo[0]=0; mo[1]=31; mo[2]=59; mo[3]=90
+ mo[4]=120; mo[5]=151; mo[6]=181; mo[7]=212
+ mo[8]=243; mo[9]=273; mo[10]=304; mo[11]=334
+ mo[12]=365
+ }
+
+ {
+ newlog = substr($0, 1 + index($0, "\r"))
+
+ # Ignore log entries prefixed by "#".
+ if (newlog ~ /^#/) { next }
+
+ if (Log != newlog || date != $2 || author != $4) {
+
+ # The previous log and this log differ.
+
+ # Print the old log.
+ if (date != "") '"$printlogline"'
+
+ # Logs that begin with "{clumpname} " should be grouped together,
+ # and the clumpname should be removed.
+ # Extract the new clumpname from the log header,
+ # and use it to decide whether to output a blank line.
+ newclumpname = ""
+ sep = "\n"
+ if (date == "") sep = ""
+ if (newlog ~ /^{[^ }]*}[ ]/) {
+ i = index(newlog, "}")
+ newclumpname = substr(newlog, 1, i)
+ while (substr(newlog, i+1) ~ /^[ ]/) i++
+ newlog = substr(newlog, i+1)
+ if (clumpname == newclumpname) sep = ""
+ }
+ printf sep
+ clumpname = newclumpname
+
+ # Get ready for the next log.
+ Log = newlog
+ if (files != "")
+ for (i in filesknown)
+ filesknown[i] = 0
+ files = ""
+ }
+ if (date != $2 || author != $4) {
+ # The previous date+author and this date+author differ.
+ # Print the new one.
+ date = $2
+ author = $4
+
+ # Convert nice RCS date like "1992/01/03 00:03:44"
+ # into ugly ctime date like "Fri Jan 3 00:03:44 1992".
+ # Calculate day of week from Gregorian calendar.
+ i = index($2, "/")
+ year = substr($2, 1, i-1) + 0
+ monthday = substr($2, i+1)
+ i = index(monthday, "/")
+ month = substr(monthday, 1, i-1) + 0
+ day = substr(monthday, i+1) + 0
+ leap = 0
+ if (2 < month && year%4 == 0 && (year%100 != 0 || year%400 == 0)) leap = 1
+ days_since_Sunday_before_epoch = EPOCH_WEEKDAY + year * 365 + int((year + 3) / 4) - int((year + 99) / 100) + int((year + 399) / 400) + mo[month-1] + leap + day - 1
+
+ # Print "date fullname (email address)" if the fullname is known;
+ # print "date author" otherwise.
+ # Get the fullname from the associative array.
+ # The email address is just author@thishostname.
+ printf "%s %s %2d %s %d ", w[days_since_Sunday_before_epoch%7], m[month-1], day, $3, year
+ if (fullname[author])
+ printf "%s (%s@%s)\n\n", fullname[author], author, "'"$hostname"'"
+ else
+ printf "%s\n\n", author
+ }
+ if (! filesknown[$1]) {
+ filesknown[$1] = 1
+ if (files == "") files = " " $1
+ else files = files ", " $1
+ }
+ }
+ END {
+ # Print the last log.
+ if (date != "") {
+ '"$printlogline"'
+ printf "\n"
+ }
+ }
+' &&
+
+
+# Exit successfully.
+
+exec rm -f $rlogout
diff --git a/gnu/usr.bin/cvs/contrib/rcs2sccs b/gnu/usr.bin/cvs/contrib/rcs2sccs
new file mode 100644
index 0000000..054ac6c
--- /dev/null
+++ b/gnu/usr.bin/cvs/contrib/rcs2sccs
@@ -0,0 +1,143 @@
+#!/bin/sh
+#
+#
+# OrigId: rcs2sccs,v 1.12 90/10/04 20:52:23 kenc Exp Locker: kenc
+# $Id: rcs2sccs,v 1.1 1993/12/06 06:37:14 berliner Exp $
+
+############################################################
+# Error checking
+#
+if [ ! -d SCCS ] ; then
+ mkdir SCCS
+fi
+
+logfile=/tmp/rcs2sccs_$$_log
+rm -f $logfile
+tmpfile=/tmp/rcs2sccs_$$_tmp
+rm -f $tmpfile
+emptyfile=/tmp/rcs2sccs_$$_empty
+echo -n "" > $emptyfile
+initialfile=/tmp/rcs2sccs_$$_init
+echo "Initial revision" > $initialfile
+sedfile=/tmp/rcs2sccs_$$_sed
+rm -f $sedfile
+revfile=/tmp/rcs2sccs_$$_rev
+rm -f $revfile
+commentfile=/tmp/rcs2sccs_$$_comment
+rm -f $commentfile
+
+# create the sed script
+cat > $sedfile << EOF
+s,;Id;,%Z%%M% %I% %E%,g
+s,;SunId;,%Z%%M% %I% %E%,g
+s,;RCSfile;,%M%,g
+s,;Revision;,%I%,g
+s,;Date;,%E%,g
+s,;Id:.*;,%Z%%M% %I% %E%,g
+s,;SunId:.*;,%Z%%M% %I% %E%,g
+s,;RCSfile:.*;,%M%,g
+s,;Revision:.*;,%I%,g
+s,;Date:.*;,%E%,g
+EOF
+sed -e 's/;/\\$/g' $sedfile > $tmpfile
+cp $tmpfile $sedfile
+############################################################
+# Loop over every RCS file in RCS dir
+#
+for vfile in *,v; do
+ # get rid of the ",v" at the end of the name
+ file=`echo $vfile | sed -e 's/,v$//'`
+
+ # work on each rev of that file in ascending order
+ firsttime=1
+ rlog $file | grep "^revision [0-9][0-9]*\." | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile
+ for rev in `cat $revfile`; do
+ if [ $? != 0 ]; then
+ echo ERROR - revision
+ exit
+ fi
+ # get file into current dir and get stats
+ date=`rlog -r$rev $file | grep "^date: " | awk '{print $2; exit}' | sed -e 's/^19//'`
+ time=`rlog -r$rev $file | grep "^date: " | awk '{print $3; exit}' | sed -e 's/;//'`
+ author=`rlog -r$rev $file | grep "^date: " | awk '{print $5; exit}' | sed -e 's/;//'`
+ date="$date $time"
+ echo ""
+ rlog -r$rev $file | sed -e '/^branches: /d' -e '1,/^date: /d' -e '/^===========/d' -e 's/$/\\/' | awk '{if ((total += length($0) + 1) < 510) print $0}' > $commentfile
+ echo "==> file $file, rev=$rev, date=$date, author=$author"
+ rm -f $file
+ co -r$rev $file >> $logfile 2>&1
+ if [ $? != 0 ]; then
+ echo ERROR - co
+ exit
+ fi
+ echo checked out of RCS
+
+ # add SCCS keywords in place of RCS keywords
+ sed -f $sedfile $file > $tmpfile
+ if [ $? != 0 ]; then
+ echo ERROR - sed
+ exit
+ fi
+ echo performed keyword substitutions
+ rm -f $file
+ cp $tmpfile $file
+
+ # check file into SCCS
+ if [ "$firsttime" = "1" ]; then
+ firsttime=0
+ echo about to do sccs admin
+ echo sccs admin -n -i$file $file < $commentfile
+ sccs admin -n -i$file $file < $commentfile >> $logfile 2>&1
+ if [ $? != 0 ]; then
+ echo ERROR - sccs admin
+ exit
+ fi
+ echo initial rev checked into SCCS
+ else
+ case $rev in
+ *.*.*.*)
+ brev=`echo $rev | sed -e 's/\.[0-9]*$//'`
+ sccs admin -fb $file 2>>$logfile
+ echo sccs get -e -p -r$brev $file
+ sccs get -e -p -r$brev $file >/dev/null 2>>$logfile
+ ;;
+ *)
+ echo sccs get -e -p $file
+ sccs get -e -p $file >/dev/null 2>> $logfile
+ ;;
+ esac
+ if [ $? != 0 ]; then
+ echo ERROR - sccs get
+ exit
+ fi
+ sccs delta $file < $commentfile >> $logfile 2>&1
+ if [ $? != 0 ]; then
+ echo ERROR - sccs delta -r$rev $file
+ exit
+ fi
+ echo checked into SCCS
+ fi
+ sed -e "s;^d D $rev ../../.. ..:..:.. [^ ][^ ]*;d D $rev $date $author;" SCCS/s.$file > $tmpfile
+ rm -f SCCS/s.$file
+ cp $tmpfile SCCS/s.$file
+ chmod 444 SCCS/s.$file
+ sccs admin -z $file
+ if [ $? != 0 ]; then
+ echo ERROR - sccs admin -z
+ exit
+ fi
+ done
+ rm -f $file
+done
+
+
+############################################################
+# Clean up
+#
+echo cleaning up...
+rm -f $tmpfile $emptyfile $initialfile $sedfile $commentfile
+echo ===================================================
+echo " Conversion Completed Successfully"
+echo ===================================================
+
+rm -f *,v
diff --git a/gnu/usr.bin/cvs/cvs/NOTES b/gnu/usr.bin/cvs/cvs/NOTES
new file mode 100644
index 0000000..646ebdf
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/NOTES
@@ -0,0 +1,60 @@
+wishlist - Tue Nov 2 15:22:58 PST 1993
+
+* bcopy -> memcpy & friends.
+ ** done 12/18/93
+
+* remove static buffers.
+* replace list & node cache with recursive obstacks, (xmalloc,
+ getnode, getlist)
+* check all io functions for error return codes. also check all
+ system calls.
+* error check mkdir.
+
+---
+Old notes...
+
+* All sizing limits are gone. The rest of these items were incidental
+ in that effort.
+
+* login name from history was duplicated. taught existing routine to
+ cache and use that instead. Also add routines to cache uid, pid,
+ etc.
+
+* ign strings were never freed. Now they are.
+
+* there was a printf("... %s ...", cp) vs *cp bug in history.c. Now
+ fixed.
+
+* The environment variables TMPDIR, HOME, and LOGNAME were not
+ honored. Now they are.
+
+* extra line inserted by do_editor() is gone. Then obviated. Editor
+ is now called exactly once per checkin.
+
+* revised editor behaviour. Never use /dev/tty. If the editor
+ session fails, we haven't yet done anything. Therefor the user can
+ safely rerun cvs and we should just fail. Also use the editor for
+ initial log messages on added files. Also omit the confirmation
+ when adding directories. Adding directories will require an
+ explicit "commit" step soon. Make it possible to prevent null login
+ messages using #define REQUIRE_LOG_MESSAGES
+
+* prototypes for all callbacks.
+
+* all callbacks get ref pointers.
+
+* do_recursion/start_recursion now use recusion_frame's rather than a
+ list of a lot of pointers and global variables.
+
+* corrected types on status_dirproc().
+
+* CONFIRM_DIRECTORY_ADDS
+
+* re_comp was innappropriate in a few places. I've eliminated it.
+
+* FORCE_MESSAGE_ON_ADD
+
+* So I built a regression test. Let's call it a sanity check to be
+ less ambitious. It exposed that cvs is difficult to call from
+ scripts.
+
diff --git a/gnu/usr.bin/cvs/cvs/convert.sh b/gnu/usr.bin/cvs/cvs/convert.sh
new file mode 100644
index 0000000..94bbdcc
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/convert.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# short script to convert cvs repositories to support file death.
+#
+
+WORKDIR=/tmp/$$-cvs-convert
+mkdir ${WORKDIR}
+cd ${WORKDIR}
+
+case $# in
+1) ;;
+*)
+ echo Usage: convert repository 2>&1
+ exit 1
+ ;;
+esac
+
+attics=`find $1 -name Attic -print`
+
+for i in ${attics} ; do
+ mkdir $i/SAVE
+ for j in $i/*,v ; do
+ echo $j
+ cp $j $i/SAVE
+ co -l $j
+ ci -K -m"recording file death" $j
+ done
+done
diff --git a/gnu/usr.bin/cvs/cvs/cvsbug.sh b/gnu/usr.bin/cvs/cvs/cvsbug.sh
new file mode 100644
index 0000000..8c6a5bb
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/cvsbug.sh
@@ -0,0 +1,533 @@
+#!/bin/sh
+# Submit a problem report to a GNATS site.
+# Copyright (C) 1993 Free Software Foundation, Inc.
+# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a
+# version written by Heinz G. Seidl (hgs@ide.com).
+#
+# This file is part of GNU GNATS.
+# Modified by Berliner for CVS.
+# $CVSid: @(#)cvsbug.sh 1.2 94/10/22 $
+#
+# GNU GNATS is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU GNATS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU GNATS; see the file COPYING. If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The version of this send-pr.
+VERSION=3.2
+
+# The submitter-id for your site.
+SUBMITTER=net
+
+## # Where the GNATS directory lives, if at all.
+## [ -z "$GNATS_ROOT" ] &&
+## GNATS_ROOT=/usr/local/lib/gnats/gnats-db
+
+# The default mail address for PR submissions.
+GNATS_ADDR=bug-cvs@prep.ai.mit.edu
+
+## # Where the gnats category tree lives.
+## DATADIR=/usr/local/lib
+
+## # If we've been moved around, try using GCC_EXEC_PREFIX.
+## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}..
+
+# The default release for this host.
+DEFAULT_RELEASE="cvs-1.4A2"
+
+# The default organization.
+DEFAULT_ORGANIZATION="net"
+
+## # The default site to look for.
+## GNATS_SITE=unknown
+
+## # Newer config information?
+## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config
+
+# What mailer to use. This must come after the config file, since it is
+# host-dependent.
+MAIL_AGENT="/usr/lib/sendmail -oi -t"
+MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'`
+if [ ! -f "$MAILER" ] ; then
+ echo "$COMMAND: Cannot file mail program \"$MAILER\"."
+ echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file."
+ exit 1
+fi
+
+if test "`echo -n foo`" = foo ; then
+ ECHON=bsd
+elif test "`echo 'foo\c'`" = foo ; then
+ ECHON=sysv
+else
+ ECHON=none
+fi
+
+if [ $ECHON = bsd ] ; then
+ ECHON1="echo -n"
+ ECHON2=
+elif [ $ECHON = sysv ] ; then
+ ECHON1=echo
+ ECHON2='\c'
+else
+ ECHON1=echo
+ ECHON2=
+fi
+
+#
+
+[ -z "$TMPDIR" ] && TMPDIR=/tmp
+
+TEMP=$TMPDIR/p$$
+BAD=$TMPDIR/pbad$$
+REF=$TMPDIR/pf$$
+
+if [ -z "$LOGNAME" -a -n "$USER" ]; then
+ LOGNAME=$USER
+fi
+
+FROM="$LOGNAME"
+REPLY_TO="$LOGNAME"
+
+# Find out the name of the originator of this PR.
+if [ -n "$NAME" ]; then
+ ORIGINATOR="$NAME"
+elif [ -f $HOME/.fullname ]; then
+ ORIGINATOR="`sed -e '1q' $HOME/.fullname`"
+elif [ -f /bin/domainname ]; then
+ if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then
+ # Must use temp file due to incompatibilities in quoting behavior
+ # and to protect shell metacharacters in the expansion of $LOGNAME
+ /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" |
+ cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
+ ORIGINATOR="`cat $TEMP`"
+ rm -f $TEMP
+ fi
+fi
+
+if [ "$ORIGINATOR" = "" ]; then
+ grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
+ ORIGINATOR="`cat $TEMP`"
+ rm -f $TEMP
+fi
+
+if [ -n "$ORGANIZATION" ]; then
+ if [ -f "$ORGANIZATION" ]; then
+ ORGANIZATION="`cat $ORGANIZATION`"
+ fi
+else
+ if [ -n "$DEFAULT_ORGANIZATION" ]; then
+ ORGANIZATION="$DEFAULT_ORGANIZATION"
+ elif [ -f $HOME/.organization ]; then
+ ORGANIZATION="`cat $HOME/.organization`"
+ elif [ -f $HOME/.signature ]; then
+ ORGANIZATION="`cat $HOME/.signature`"
+ fi
+fi
+
+# If they don't have a preferred editor set, then use
+if [ -z "$VISUAL" ]; then
+ if [ -z "$EDITOR" ]; then
+ EDIT=vi
+ else
+ EDIT="$EDITOR"
+ fi
+else
+ EDIT="$VISUAL"
+fi
+
+# Find out some information.
+SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \
+ ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""`
+ARCH=`[ -f /bin/arch ] && /bin/arch`
+MACHINE=`[ -f /bin/machine ] && /bin/machine`
+
+COMMAND=`echo $0 | sed -e 's,.*/,,'`
+## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id]
+USAGE="Usage: $COMMAND [-PVL]
+[--version]"
+REMOVE=
+BATCH=
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ -r) ;; # Ignore for backward compat.
+## -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
+## shift ; GNATS_ADDR="$1"
+## EXPLICIT_GNATS_ADDR=true
+## ;;
+## -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
+## shift ; IN_FILE="$1"
+## if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then
+## echo "$COMMAND: cannot read $IN_FILE"
+## exit 1
+## fi
+## ;;
+ -b | --batch) BATCH=true ;;
+ -p | -P | --print) PRINT=true ;;
+ -L | --list) FORMAT=norm ;;
+ -l | -CL | --lisp) FORMAT=lisp ;;
+## --request-id) REQUEST_ID=true ;;
+ -h | --help) echo "$USAGE"; exit 0 ;;
+ -V | --version) echo "$VERSION"; exit 0 ;;
+ -*) echo "$USAGE" ; exit 1 ;;
+ *) echo "$USAGE" ; exit 1
+## if [ -z "$USER_GNATS_SITE" ]; then
+## if [ ! -r "$DATADIR/gnats/$1" ]; then
+## echo "$COMMAND: the GNATS site $1 does not have a categories list."
+## exit 1
+## else
+## # The site name is the alias they'll have to have created.
+## USER_GNATS_SITE=$1
+## fi
+## else
+## echo "$USAGE" ; exit 1
+## fi
+ ;;
+ esac
+ shift
+done
+
+if [ -n "$USER_GNATS_SITE" ]; then
+ GNATS_SITE=$USER_GNATS_SITE
+ GNATS_ADDR=$USER_GNATS_SITE-gnats
+fi
+
+if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then
+ cat << '__EOF__'
+It seems that send-pr is not installed with your unique submitter-id.
+You need to run
+
+ install-sid YOUR-SID
+
+where YOUR-SID is the identification code you received with `send-pr'.
+`send-pr' will automatically insert this value into the template field
+`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net'
+for this value. If you do not know your id, run `send-pr --request-id' to
+get one from your support site.
+__EOF__
+ exit 1
+fi
+
+## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then
+## CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort`
+## else
+## echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list."
+## exit 1
+## fi
+CATEGORIES="contrib cvs doc pcl-cvs portability"
+
+if [ -z "$CATEGORIES" ]; then
+ echo "$COMMAND: the categories list for $GNATS_SITE was empty!"
+ exit 1
+fi
+
+case "$FORMAT" in
+ lisp) echo "$CATEGORIES" | \
+ awk 'BEGIN {printf "( "} {printf "(\"%s\") ",$0} END {printf ")\n"}'
+ exit 0
+ ;;
+ norm) l=`echo "$CATEGORIES" | \
+ awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } }
+ END {print max + 1;}'`
+ c=`expr 70 / $l`
+ if [ $c -eq 0 ]; then c=1; fi
+ echo "$CATEGORIES" | \
+ awk 'BEGIN {print "Known categories:"; i = 0 }
+ { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } }
+ END { print ""; }'
+ exit 0
+ ;;
+esac
+
+ORIGINATOR_C='<name of the PR author (one line)>'
+ORGANIZATION_C='<organization of PR author (multiple lines)>'
+CONFIDENTIAL_C='<[ yes | no ] (one line)>'
+SYNOPSIS_C='<synopsis of the problem (one line)>'
+SEVERITY_C='<[ non-critical | serious | critical ] (one line)>'
+PRIORITY_C='<[ low | medium | high ] (one line)>'
+CATEGORY_C='<name of the product (one line)>'
+CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>'
+RELEASE_C='<release number or tag (one line)>'
+ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>'
+DESCRIPTION_C='<precise description of the problem (multiple lines)>'
+HOW_TO_REPEAT_C='<code/input/activities to reproduce the problem (multiple lines)>'
+FIX_C='<how to correct or work around the problem, if known (multiple lines)>'
+
+# Catch some signals. ($xs kludge needed by Sun /bin/sh)
+xs=0
+trap 'rm -f $REF $TEMP; exit $xs' 0
+trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15
+
+# If they told us to use a specific file, then do so.
+if [ -n "$IN_FILE" ]; then
+ if [ "$IN_FILE" = "-" ]; then
+ # The PR is coming from the standard input.
+ if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
+ sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP
+ else
+ cat > $TEMP
+ fi
+ else
+ # Use the file they named.
+ if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
+ sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP
+ else
+ cat $IN_FILE > $TEMP
+ fi
+ fi
+else
+
+ if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
+ # If their PR_FORM points to a bogus entry, then bail.
+ if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then
+ echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM"
+ sleep 1
+ PRINT_INTERN=bad_prform
+ fi
+ fi
+
+ if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
+ cp $PR_FORM $TEMP ||
+ ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit )
+ else
+ for file in $TEMP $REF ; do
+ cat > $file << '__EOF__'
+SEND-PR: -*- send-pr -*-
+SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
+SEND-PR: will all comments (text enclosed in `<' and `>').
+SEND-PR:
+SEND-PR: Choose from the following categories:
+SEND-PR:
+__EOF__
+
+ # Format the categories so they fit onto lines.
+ l=`echo "$CATEGORIES" | \
+ awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } }
+ END {print max + 1;}'`
+ c=`expr 61 / $l`
+ if [ $c -eq 0 ]; then c=1; fi
+ echo "$CATEGORIES" | \
+ awk 'BEGIN {printf "SEND-PR: "; i = 0 }
+ { printf ("%-'$l'.'$l's", $0);
+ if ((++i % '$c') == 0) { printf "\nSEND-PR: " } }
+ END { printf "\nSEND-PR:\n"; }' >> $file
+
+ cat >> $file << __EOF__
+To: $GNATS_ADDR
+Subject:
+From: $FROM
+Reply-To: $REPLY_TO
+X-send-pr-version: $VERSION
+
+
+>Submitter-Id: $SUBMITTER
+>Originator: $ORIGINATOR
+>Organization:
+`
+ if [ -n "$ORGANIZATION" ]; then
+ echo "$ORGANIZATION"
+ else
+ echo " $ORGANIZATION_C" ;
+ fi ;
+`
+>Confidential: $CONFIDENTIAL_C
+>Synopsis: $SYNOPSIS_C
+>Severity: $SEVERITY_C
+>Priority: $PRIORITY_C
+>Category: $CATEGORY_C
+>Class: $CLASS_C
+>Release: `if [ -n "$DEFAULT_RELEASE" ]; then
+ echo "$DEFAULT_RELEASE"
+ else
+ echo " $RELEASE_C"
+ fi; `
+>Environment:
+ $ENVIRONMENT_C
+`[ -n "$SYSTEM" ] && echo System: $SYSTEM`
+`[ -n "$ARCH" ] && echo Architecture: $ARCH`
+`[ -n "$MACHINE" ] && echo Machine: $MACHINE`
+>Description:
+ $DESCRIPTION_C
+>How-To-Repeat:
+ $HOW_TO_REPEAT_C
+>Fix:
+ $FIX_C
+__EOF__
+ done
+ fi
+
+ if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then
+ cat $TEMP
+ xs=0; exit
+ fi
+
+ chmod u+w $TEMP
+ if [ -z "$REQUEST_ID" ]; then
+ eval $EDIT $TEMP
+ else
+ ed -s $TEMP << '__EOF__'
+/^Subject/s/^Subject:.*/Subject: request for a customer id/
+/^>Category/s/^>Category:.*/>Category: send-pr/
+w
+q
+__EOF__
+ fi
+
+ if cmp -s $REF $TEMP ; then
+ echo "$COMMAND: problem report not filled out, therefore not sent"
+ xs=1; exit
+ fi
+fi
+
+#
+# Check the enumeration fields
+
+# This is a "sed-subroutine" with one keyword parameter
+# (with workaround for Sun sed bug)
+#
+SED_CMD='
+/$PATTERN/{
+s|||
+s|<.*>||
+s|^[ ]*||
+s|[ ]*$||
+p
+q
+}'
+
+
+while [ -z "$REQUEST_ID" ]; do
+ CNT=0
+
+ # 1) Confidential
+ #
+ PATTERN=">Confidential:"
+ CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
+ case "$CONFIDENTIAL" in
+ ""|yes|no) CNT=`expr $CNT + 1` ;;
+ *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;;
+ esac
+ #
+ # 2) Severity
+ #
+ PATTERN=">Severity:"
+ SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
+ case "$SEVERITY" in
+ ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;;
+ *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'."
+ esac
+ #
+ # 3) Priority
+ #
+ PATTERN=">Priority:"
+ PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
+ case "$PRIORITY" in
+ ""|low|medium|high) CNT=`expr $CNT + 1` ;;
+ *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'."
+ esac
+ #
+ # 4) Category
+ #
+ PATTERN=">Category:"
+ CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
+ FOUND=
+ for C in $CATEGORIES
+ do
+ if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi
+ done
+ if [ -n "$FOUND" ]; then
+ CNT=`expr $CNT + 1`
+ else
+ if [ -z "$CATEGORY" ]; then
+ echo "$COMMAND: you must include a Category: field in your report."
+ else
+ echo "$COMMAND: \`$CATEGORY' is not a known category."
+ fi
+ fi
+ #
+ # 5) Class
+ #
+ PATTERN=">Class:"
+ CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
+ case "$CLASS" in
+ ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;;
+ *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'."
+ esac
+
+ [ $CNT -lt 5 -a -z "$BATCH" ] &&
+ echo "Errors were found with the problem report."
+
+ while true; do
+ if [ -z "$BATCH" ]; then
+ $ECHON1 "a)bort, e)dit or s)end? $ECHON2"
+ read input
+ else
+ if [ $CNT -eq 5 ]; then
+ input=s
+ else
+ input=a
+ fi
+ fi
+ case "$input" in
+ a*)
+ if [ -z "$BATCH" ]; then
+ echo "$COMMAND: the problem report remains in $BAD and is not sent."
+ mv $TEMP $BAD
+ else
+ echo "$COMMAND: the problem report is not sent."
+ fi
+ xs=1; exit
+ ;;
+ e*)
+ eval $EDIT $TEMP
+ continue 2
+ ;;
+ s*)
+ break 2
+ ;;
+ esac
+ done
+done
+#
+# Remove comments and send the problem report
+# (we have to use patterns, where the comment contains regex chars)
+#
+# /^>Originator:/s;$ORIGINATOR;;
+sed -e "
+/^SEND-PR:/d
+/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;;
+/^>Confidential:/s;<.*>;;
+/^>Synopsis:/s;$SYNOPSIS_C;;
+/^>Severity:/s;<.*>;;
+/^>Priority:/s;<.*>;;
+/^>Category:/s;$CATEGORY_C;;
+/^>Class:/s;<.*>;;
+/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;;
+/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;;
+/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;;
+/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;;
+/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;;
+" $TEMP > $REF
+
+if $MAIL_AGENT < $REF; then
+ echo "$COMMAND: problem report sent"
+ xs=0; exit
+else
+ echo "$COMMAND: mysterious mail failure."
+ if [ -z "$BATCH" ]; then
+ echo "$COMMAND: the problem report remains in $BAD and is not sent."
+ mv $REF $BAD
+ else
+ echo "$COMMAND: the problem report is not sent."
+ fi
+ xs=1; exit
+fi
diff --git a/gnu/usr.bin/cvs/cvs/cvsrc.c b/gnu/usr.bin/cvs/cvs/cvsrc.c
new file mode 100644
index 0000000..fedd020
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/cvsrc.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1993 david d zuhn
+ *
+ * written by david d `zoo' zuhn while at Cygnus Support
+ *
+ * You may distribute under the terms of the GNU General Public License
+ * as specified in the README file that comes with the CVS 1.4 kit.
+ *
+ */
+
+
+#include "cvs.h"
+
+#ifndef lint
+static char rcsid[] = "$CVSid: @(#)cvsrc.c 1.9 94/09/30 $";
+USE(rcsid)
+#endif /* lint */
+
+/* this file is to be found in the user's home directory */
+
+#ifndef CVSRC_FILENAME
+#define CVSRC_FILENAME ".cvsrc"
+#endif
+char cvsrc[] = CVSRC_FILENAME;
+
+#define GROW 10
+
+extern char *getenv ();
+extern char *strtok ();
+
+void
+read_cvsrc (argc, argv)
+ int *argc;
+ char ***argv;
+{
+ char *homedir;
+ char *homeinit;
+ FILE *cvsrcfile;
+
+ char linebuf [MAXLINELEN];
+
+ char *optstart;
+
+ int found = 0;
+
+ int i;
+
+ int new_argc;
+ int max_new_argv;
+ char **new_argv;
+
+ /* don't do anything if argc is -1, since that implies "help" mode */
+ if (*argc == -1)
+ return;
+
+ /* setup the new options list */
+
+ new_argc = 1;
+ max_new_argv = (*argc) + GROW;
+ new_argv = (char **) xmalloc (max_new_argv * sizeof (char*));
+ new_argv[0] = xstrdup ((*argv)[0]);
+
+ /* determine filename for ~/.cvsrc */
+
+ homedir = getenv ("HOME");
+ if (!homedir)
+ return;
+
+ homeinit = (char *) xmalloc (strlen (homedir) + strlen (cvsrc) + 10);
+ strcpy (homeinit, homedir);
+ strcat (homeinit, "/");
+ strcat (homeinit, cvsrc);
+
+ /* if it can't be read, there's no point to continuing */
+
+ if (access (homeinit, R_OK) != 0)
+ {
+ free (homeinit);
+ return;
+ }
+
+ /* now scan the file until we find the line for the command in question */
+
+ cvsrcfile = open_file (homeinit, "r");
+ while (fgets (linebuf, MAXLINELEN, cvsrcfile))
+ {
+ /* skip over comment lines */
+ if (linebuf[0] == '#')
+ continue;
+
+ /* stop if we match the current command */
+ if (!strncmp (linebuf, (*argv)[0], strlen ((*argv)[0])))
+ {
+ found = 1;
+ break;
+ }
+ }
+
+ fclose (cvsrcfile);
+
+ if (found)
+ {
+ /* skip over command in the options line */
+ optstart = strtok(linebuf+strlen((*argv)[0]), "\t \n");
+
+ do
+ {
+ new_argv [new_argc] = xstrdup (optstart);
+ new_argv [new_argc+1] = NULL;
+ new_argc += 1;
+
+ if (new_argc >= max_new_argv)
+ {
+ char **tmp_argv;
+ max_new_argv += GROW;
+ tmp_argv = (char **) xmalloc (max_new_argv * sizeof (char*));
+ for (i = 0; i <= new_argc; i++)
+ tmp_argv[i] = new_argv[i];
+ free(new_argv);
+ new_argv = tmp_argv;
+ }
+
+ }
+ while (optstart = strtok (NULL, "\t \n"));
+ }
+
+ /* now copy the remaining arguments */
+
+ for (i=1; i < *argc; i++)
+ {
+ new_argv [new_argc] = (*argv)[i];
+ new_argc += 1;
+ }
+
+ *argc = new_argc;
+ *argv = new_argv;
+
+ free (homeinit);
+ return;
+}
diff --git a/gnu/usr.bin/cvs/cvs/options.h b/gnu/usr.bin/cvs/cvs/options.h
new file mode 100644
index 0000000..ad07c14
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/options.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (c) 1989-1992, Brian Berliner
+ *
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with the CVS 1.4 kit.
+ *
+ * This file holds (most of) the configuration tweaks that can be made to
+ * customize CVS for your site. CVS comes configured for a typical SunOS 4.x
+ * environment. The comments for each configurable item are intended to be
+ * self-explanatory. All #defines are tested first to see if an over-riding
+ * option was specified on the "make" command line.
+ *
+ * If special libraries are needed, you will have to edit the Makefile.in file
+ * or the configure script directly. Sorry.
+ */
+
+/*
+ * CVS provides the most features when used in conjunction with the Version-5
+ * release of RCS. Thus, it is the default. This also assumes that GNU diff
+ * Version-1.15 is being used as well -- you will have to configure your RCS
+ * V5 release separately to make this the case. If you do not have RCS V5 and
+ * GNU diff V1.15, comment out this define. You should not try mixing and
+ * matching other combinations of these tools.
+ */
+#ifndef HAVE_RCS5
+#define HAVE_RCS5
+#endif
+
+/*
+ * If, before installing this version of CVS, you were running RCS V4 AND you
+ * are installing this CVS and RCS V5 and GNU diff 1.15 all at the same time,
+ * you should turn on the following define. It only exists to try to do
+ * reasonable things with your existing checked out files when you upgrade to
+ * RCS V5, since the keyword expansion formats have changed with RCS V5.
+ *
+ * If you already have been running with RCS5, or haven't been running with CVS
+ * yet at all, or are sticking with RCS V4 for now, leave the commented out.
+ */
+#ifndef HAD_RCS4
+/* #define HAD_RCS4 */
+#endif
+
+/*
+ * For portability and heterogeneity reasons, CVS is shipped by default using
+ * my own text-file version of the ndbm database library in the src/myndbm.c
+ * file. If you want better performance and are not concerned about
+ * heterogeneous hosts accessing your modules file, turn this option off.
+ */
+#ifndef MY_NDBM
+#define MY_NDBM
+#endif
+
+/*
+ * The "diff" program to execute when creating patch output. This "diff"
+ * must support the "-c" option for context diffing. Specify a full pathname
+ * if your site wants to use a particular diff. If you are using the GNU
+ * version of diff (version 1.15 or later), this should be "diff -a".
+ *
+ * NOTE: this program is only used for the ``patch'' sub-command. The other
+ * commands use rcsdiff which will use whatever version of diff was specified
+ * when rcsdiff was built on your system.
+ */
+#ifndef DIFF
+#define DIFF "diff"
+#endif
+
+/*
+ * The "grep" program to execute when checking to see if a merged file had
+ * any conflicts. This "grep" must support the "-s" option and a standard
+ * regular expression as an argument. Specify a full pathname if your site
+ * wants to use a particular grep.
+ */
+#ifndef GREP
+#define GREP "grep"
+#endif
+
+/*
+ * The "rm" program to execute when pruning directories that are not part of
+ * a release. This "rm" must support the "-fr" options. Specify a full
+ * pathname if your site wants to use a particular rm.
+ */
+#ifndef RM
+#define RM "rm"
+#endif
+
+/*
+ * The "sort" program to execute when displaying the module database. Specify
+ * a full pathname if your site wants to use a particular sort.
+ */
+#ifndef SORT
+#define SORT "sort"
+#endif
+
+/*
+ * By default, RCS programs are executed with the shell or through execlp(),
+ * so the user's PATH environment variable is searched. If you'd like to
+ * bind all RCS programs to a certain directory (perhaps one not in most
+ * people's PATH) then set the default in RCSBIN_DFLT. Note that setting
+ * this here will cause all RCS programs to be executed from this directory,
+ * unless the user overrides the default with the RCSBIN environment variable
+ * or the "-b" option to CVS.
+ *
+ * This define should be either the empty string ("") or a full pathname to the
+ * directory containing all the installed programs from the RCS distribution.
+ */
+#ifndef RCSBIN_DFLT
+#define RCSBIN_DFLT ""
+#endif
+
+/*
+ * The default editor to use, if one does not specify the "-e" option to cvs,
+ * or does not have an EDITOR environment variable. I set this to just "vi",
+ * and use the shell to find where "vi" actually is. This allows sites with
+ * /usr/bin/vi or /usr/ucb/vi to work equally well (assuming that your PATH
+ * is reasonable).
+ */
+#ifndef EDITOR_DFLT
+#define EDITOR_DFLT "vi"
+#endif
+
+/*
+ * The Repository file holds the path to the directory within the source
+ * repository that contains the RCS ,v files for each CVS working directory.
+ * This path is either a full-path or a path relative to CVSROOT.
+ *
+ * The only advantage that I can see to having a relative path is that One can
+ * change the physical location of the master source repository, change one's
+ * CVSROOT environment variable, and CVS will work without problems. I
+ * recommend using full-paths.
+ */
+#ifndef RELATIVE_REPOS
+/* #define RELATIVE_REPOS */
+#endif
+
+/*
+ * When committing or importing files, you must enter a log message.
+ * Normally, you can do this either via the -m flag on the command line or an
+ * editor will be started for you. If you like to use logging templates (the
+ * rcsinfo file within the $CVSROOT/CVSROOT directory), you might want to
+ * force people to use the editor even if they specify a message with -m.
+ * Enabling FORCE_USE_EDITOR will cause the -m message to be appended to the
+ * temp file when the editor is started.
+ */
+#ifndef FORCE_USE_EDITOR
+/* #define FORCE_USE_EDITOR */
+#endif
+
+/*
+ * When locking the repository, some sites like to remove locks and assume
+ * the program that created them went away if the lock has existed for a long
+ * time. This used to be the default for previous versions of CVS. CVS now
+ * attempts to be much more robust, so lock files should not be left around
+ * by mistake. The new behaviour will never remove old locks (they must now
+ * be removed by hand). Enabling CVS_FUDGELOCKS will cause CVS to remove
+ * locks that are older than CVSLCKAGE seconds.
+ * Use of this option is NOT recommended.
+ */
+#ifndef CVS_FUDGELOCKS
+/* #define CVS_FUDGELOCKS */
+#endif
+
+/*
+ * When committing a permanent change, CVS and RCS make 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), CVS/RCS
+ * cannot determine who is actually making the change.
+ *
+ * As such, by default, CVS disallows changes to be committed by users
+ * logged in as "root". You can disable this option by commenting
+ * out the lines below.
+ */
+#ifndef CVS_BADROOT
+#define CVS_BADROOT
+#endif
+
+/*
+ * The "cvs diff" command accepts all the single-character options that GNU
+ * diff (1.15) accepts. Except -D. GNU diff uses -D as a way to put
+ * cpp-style #define's around the output differences. CVS, by default, uses
+ * -D to specify a free-form date (like "cvs diff -D '1 week ago'"). If
+ * you would prefer that the -D option of "cvs diff" work like the GNU diff
+ * option, then comment out this define.
+ */
+#ifndef CVS_DIFFDATE
+#define CVS_DIFFDATE
+#endif
+
+/* End of CVS configuration section */
+
+/*
+ * Externs that are included in libc, but are used frequently enough to
+ * warrant defining here.
+ */
+#ifndef STDC_HEADERS
+extern void exit ();
+#endif
+
+#ifndef getwd
+extern char *getwd ();
+#endif
+
diff --git a/gnu/usr.bin/cvs/cvs/root.c b/gnu/usr.bin/cvs/cvs/root.c
new file mode 100644
index 0000000..9ff9ffa
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/root.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1992, Mark D. Baushke
+ *
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with the CVS 1.4 kit.
+ *
+ * Name of Root
+ *
+ * Determine the path to the CVSROOT and set "Root" accordingly.
+ * If this looks like of modified clone of Name_Repository() in
+ * repos.c, it is...
+ */
+
+#include "cvs.h"
+
+#ifndef lint
+static char rcsid[] = "@(#)root.c,v 1.2 1994/09/15 05:32:17 zoo Exp";
+USE(rcsid)
+#endif
+
+char *
+Name_Root(dir, update_dir)
+ char *dir;
+ char *update_dir;
+{
+ FILE *fpin;
+ char *ret, *xupdate_dir;
+ char root[PATH_MAX];
+ char tmp[PATH_MAX];
+ char cvsadm[PATH_MAX];
+ char *cp;
+
+ if (update_dir && *update_dir)
+ xupdate_dir = update_dir;
+ else
+ xupdate_dir = ".";
+
+ if (dir != NULL)
+ {
+ (void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
+ }
+ else
+ {
+ (void) strcpy (cvsadm, CVSADM);
+ }
+
+ if (dir != NULL)
+ (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
+ else
+ (void) strcpy (tmp, CVSADM_ROOT);
+
+ /*
+ * Do not bother looking for a readable file if there is no cvsadm
+ * directory present.
+ *
+ * It is possiible that not all repositories will have a CVS/Root
+ * file. This is ok, but the user will need to specify -d
+ * /path/name or have the environment variable CVSROOT set in
+ * order to continue.
+ */
+ if ((!isdir (cvsadm)) || (!isreadable (tmp)))
+ {
+ if (CVSroot == NULL)
+ {
+ error (0, 0, "in directory %s:", xupdate_dir);
+ error (0, 0, "must set the CVSROOT environment variable");
+ error (0, 0, "or specify the '-d' option to %s.", program_name);
+ }
+ return (NULL);
+ }
+
+ /*
+ * The assumption here is that the CVS Root is always contained in the
+ * first line of the "Root" file.
+ */
+ fpin = open_file (tmp, "r");
+
+ if (fgets (root, PATH_MAX, fpin) == NULL)
+ {
+ error (0, 0, "in directory %s:", xupdate_dir);
+ error (0, errno, "cannot read %s", CVSADM_ROOT);
+ error (0, 0, "please correct this problem");
+ return (NULL);
+ }
+ (void) fclose (fpin);
+ if ((cp = strrchr (root, '\n')) != NULL)
+ *cp = '\0'; /* strip the newline */
+
+ /*
+ * root now contains a candidate for CVSroot. It must be an
+ * absolute pathname
+ */
+ if (root[0] != '/')
+ {
+ error (0, 0, "in directory %s:", xupdate_dir);
+ error (0, 0,
+ "ignoring %s because it does not contain an absolute pathname.",
+ CVSADM_ROOT);
+ return (NULL);
+ }
+
+ if (!isdir (root))
+ {
+ error (0, 0, "in directory %s:", xupdate_dir);
+ error (0, 0,
+ "ignoring %s because it specifies a non-existent repository %s",
+ CVSADM_ROOT, root);
+ return (NULL);
+ }
+
+ /* allocate space to return and fill it in */
+ strip_path (root);
+ ret = xstrdup (root);
+ return (ret);
+}
+
+/*
+ * Returns non-zero if the two directories have the same stat values
+ * which indicates that they are really the same directories.
+ */
+int
+same_directories (dir1, dir2)
+ char *dir1;
+ char *dir2;
+{
+ struct stat sb1;
+ struct stat sb2;
+ int ret;
+
+ if (stat (dir1, &sb1) < 0)
+ return (0);
+ if (stat (dir2, &sb2) < 0)
+ return (0);
+
+ ret = 0;
+ if ( (memcmp( &sb1.st_dev, &sb2.st_dev, sizeof(dev_t) ) == 0) &&
+ (memcmp( &sb1.st_ino, &sb2.st_ino, sizeof(ino_t) ) == 0))
+ ret = 1;
+
+ return (ret);
+}
+
+
+/*
+ * Write the CVS/Root file so that the environment variable CVSROOT
+ * and/or the -d option to cvs will be validated or not necessary for
+ * future work.
+ */
+void
+Create_Root (dir, rootdir)
+ char *dir;
+ char *rootdir;
+{
+ FILE *fout;
+ char tmp[PATH_MAX];
+
+ /* record the current cvs root */
+
+ if (rootdir != NULL)
+ {
+ if (dir != NULL)
+ (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
+ else
+ (void) strcpy (tmp, CVSADM_ROOT);
+ fout = open_file (tmp, "w+");
+ if (fprintf (fout, "%s\n", rootdir) == EOF)
+ error (1, errno, "write to %s failed", tmp);
+ if (fclose (fout) == EOF)
+ error (1, errno, "cannot close %s", tmp);
+ }
+}
diff --git a/gnu/usr.bin/cvs/cvs/sanity.el b/gnu/usr.bin/cvs/cvs/sanity.el
new file mode 100644
index 0000000..a147057
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/sanity.el
@@ -0,0 +1,18 @@
+;;;; -*- lisp-interaction -*-
+;;;; Time-stamp: <29 Nov 93 14:25:28, by rich@sendai.cygnus.com>
+
+(defun reset-fail-counter (arg)
+ (interactive "p")
+ (setq fail-counter arg)
+ (message (concat "fail-counter = " (int-to-string arg))))
+
+
+(defun inc-next-fail-counter nil
+ (interactive)
+ (search-forward "failed test ")
+ (kill-word 1)
+ (insert-string fail-counter)
+ (setq fail-counter (+ 1 fail-counter)))
+
+(global-set-key [f15] 'reset-fail-counter)
+(global-set-key [f16] 'inc-next-fail-counter)
diff --git a/gnu/usr.bin/cvs/cvs/sanity.sh b/gnu/usr.bin/cvs/cvs/sanity.sh
new file mode 100644
index 0000000..5ffa514
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/sanity.sh
@@ -0,0 +1,1069 @@
+#!/bin/sh
+# a quick sanity test for cvs.
+#
+# Copyright (C) 1992, 1993 Cygnus Support
+#
+# Original Author: K. Richard Pixley
+# Last mod Thu Nov 4 16:37:08 PST 1993, by rich@sendai.cygnus.com
+
+#
+# These commands are not covered at all.
+# admin
+
+TESTDIR=/tmp/cvs-sanity
+
+# "debugger"
+#set -x
+
+echo This test should produce no other output than this line.
+
+# clean any old remnants
+rm -rf ${TESTDIR}
+
+# fixme: try things without -m.
+# fixme: run this in a loop over "-Q", "-q", and "".
+testcvs=$1
+CVS="${testcvs} -Q"
+OUTPUT=
+
+LOGFILE=`pwd`/check.log
+if test -f check.log; then mv check.log check.plog; fi
+
+mkdir ${TESTDIR}
+cd ${TESTDIR}
+
+# so far so good. Let's try something harder.
+
+# this should die
+if ${CVS} -d `pwd`/cvsroot co cvs-sanity 2>> ${LOGFILE} ${OUTPUT} ; then
+ echo '***' failed test 1. ; exit 1
+else
+ true
+fi
+
+# this should still die
+mkdir cvsroot
+if ${CVS} -d `pwd`/cvsroot co cvs-sanity 2>> ${LOGFILE} ${OUTPUT} ; then
+ echo '***' failed test 2. ; exit 1
+else
+ true
+fi
+
+# this should still die
+mkdir cvsroot/CVSROOT
+if ${CVS} -d `pwd`/cvsroot co cvs-sanity 2>> ${LOGFILE} ${OUTPUT} ; then
+ echo '***' failed test 3. ; exit 1
+else
+ true
+fi
+
+# This one should work, although it should spit a warning.
+mkdir tmp ; cd tmp
+${CVS} -d `pwd`/../cvsroot co CVSROOT 2>> ${LOGFILE} ${OUTPUT}
+cd .. ; rm -rf tmp
+
+# This one should succeed. No warnings.
+touch cvsroot/CVSROOT/modules
+mkdir tmp ; cd tmp
+if ${CVS} -d `pwd`/../cvsroot co CVSROOT ${OUTPUT} ; then
+ true
+else
+ echo '***' failed test 4. ; exit 1
+fi
+
+cd .. ; rm -rf tmp
+
+# Try setting CVSROOT so we don't have to worry about it anymore. (now that
+# we've tested -d cvsroot.)
+CVSROOT_FILENAME=`pwd`/cvsroot
+CVSROOT=${CVSROOT_FILENAME} ; export CVSROOT
+# This isn't exactly what we want since we would like to tell it to use ${CVS},
+# rather than some random cvs from the PATH.
+#CVSROOT=`hostname`:${CVSROOT_FILENAME} ; export CVSROOT
+
+mkdir tmp ; cd tmp
+if ${CVS} -d `pwd`/../cvsroot co CVSROOT ${OUTPUT} ; then
+ true
+else
+ echo '***' failed test 5. ; exit 1
+fi
+
+cd .. ; rm -rf tmp
+
+# start keeping history
+touch ${CVSROOT_FILENAME}/CVSROOT/history
+
+### The big loop
+for what in basic0 basic1 basic2 basic3 rtags death import new ; do
+ case $what in
+ basic0) # Now, let's build something.
+# mkdir first-dir
+ # this doesn't yet work, though I think maybe it should. xoxorich.
+# if ${CVS} add first-dir ${OUTPUT} ; then
+# true
+# else
+# echo cvs does not yet add top level directories cleanly.
+ mkdir ${CVSROOT_FILENAME}/first-dir
+# fi
+# rm -rf first-dir
+
+ # check out an empty directory
+ if ${CVS} co first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 6. ; exit 1
+ fi
+
+ # update the empty directory
+ if ${CVS} update first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 7. ; exit 1
+ fi
+
+ # diff -u the empty directory
+ if ${CVS} diff -u first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 8. ; exit 1
+ fi
+
+ # diff -c the empty directory
+ if ${CVS} diff -c first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 9. ; exit 1
+ fi
+
+ # log the empty directory
+ if ${CVS} log first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 10. ; exit 1
+ fi
+
+ # status the empty directory
+ if ${CVS} status first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 11. ; exit 1
+ fi
+
+ # tag the empty directory
+ if ${CVS} tag first first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 12. ; exit 1
+ fi
+
+ # rtag the empty directory
+ if ${CVS} rtag empty first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 13. ; exit 1
+ fi
+ ;;
+
+ basic1) # first dive - add a files, first singly, then in a group.
+ cd first-dir
+ files=first-file
+ for i in a b ; do
+ for j in ${files} ; do
+ echo $j > $j
+ done
+
+ for do in add rm ; do
+ for j in ${do} "commit -m test" ; do
+ # ${do}
+ if ${CVS} $j ${files} ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 14-${do}-$j. ; exit 1
+ fi
+
+ # update it.
+ if [ "${do}" = "rm" -a "$j" != "commit -m test" ] || ${CVS} update ${files} ; then
+ true
+ else
+ echo '***' failed test 15-${do}-$j. ; exit 1
+ fi
+
+ # update all.
+ if ${CVS} update ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 16-${do}-$j. ; exit 1
+ fi
+
+ # status all.
+ if ${CVS} status ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 17-${do}-$j. ; exit 1
+ fi
+
+ # fixme: this one doesn't work yet for added files.
+ # log all.
+ if ${CVS} log ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 18-${do}-$j. #; exit 1
+ fi
+
+ if test "x${do}-$j" = "xadd-add" || test "x${do}-$j" = "xrm-rm" ; then
+ true
+ else
+ # diff -c all
+ if ${CVS} diff -c ${OUTPUT} >> ${LOGFILE} || [ $? = 1 ] ; then
+ true
+ else
+ echo '***' failed test 19-${do}-$j. # FIXME; exit 1
+ fi
+
+ # diff -u all
+ if ${CVS} diff -u ${OUTPUT} >> ${LOGFILE} || [ $? = 1 ] ; then
+ true
+ else
+ echo '***' failed test 20-${do}-$j. # FIXME; exit 1
+ fi
+ fi
+
+ cd ..
+ # update all.
+ if ${CVS} update ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 21-${do}-$j. ; exit 1
+ fi
+
+ # log all.
+ # fixme: doesn't work right for added files.
+ if ${CVS} log first-dir ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 22-${do}-$j. #; exit 1
+ fi
+
+ # status all.
+ if ${CVS} status first-dir ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 23-${do}-$j. ; exit 1
+ fi
+
+ # update all.
+ if ${CVS} update first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 24-${do}-$j. ; exit 1
+ fi
+
+ if test "x${do}-$j" = "xadd-add" || test "x${do}-$j" = "xrm-rm" ; then
+ true
+ else
+ # diff all
+ if ${CVS} diff -u ${OUTPUT} >> ${LOGFILE} || [ $? = 1 ] ; then
+ true
+ else
+ echo '***' failed test 25-${do}-$j. # FIXME; exit 1
+ fi
+
+ # diff all
+ if ${CVS} diff -u first-dir ${OUTPUT} >> ${LOGFILE} || [ $? = 1 ] ; then
+ true
+ else
+ echo '***' failed test 26-${do}-$j. # FIXME; exit 1
+ fi
+ fi
+
+ # update all.
+ if ${CVS} co first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 27-${do}-$j. ; exit 1
+ fi
+
+ cd first-dir
+ done # j
+ rm -f ${files}
+ done # do
+
+ files="file2 file3 file4 file5"
+ done
+ if ${CVS} tag first-dive ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 28. ; exit 1
+ fi
+ cd ..
+ ;;
+
+ basic2) # second dive - add bunch o' files in bunch o' added directories
+ for i in first-dir dir1 dir2 dir3 dir4 ; do
+ if [ ! -d $i ] ; then
+ mkdir $i
+ if ${CVS} add $i ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 29-$i. ; exit 1
+ fi
+ fi
+
+ cd $i
+
+ for j in file6 file7 file8 file9 file10 file11 file12 file13; do
+ echo $j > $j
+ done
+
+ if ${CVS} add file6 file7 file8 file9 file10 file11 file12 file13 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 30-$i-$j. ; exit 1
+ fi
+ done
+ cd ../../../../..
+ if ${CVS} update first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 31. ; exit 1
+ fi
+
+ # fixme: doesn't work right for added files.
+ if ${CVS} log first-dir ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 32. # ; exit 1
+ fi
+
+ if ${CVS} status first-dir ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 33. ; exit 1
+ fi
+
+# if ${CVS} diff -u first-dir ${OUTPUT} >> ${LOGFILE} || [ $? = 1 ] ; then
+# true
+# else
+# echo '***' failed test 34. # ; exit 1
+# fi
+
+ if ${CVS} ci -m "second dive" first-dir ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 35. ; exit 1
+ fi
+
+ if ${CVS} tag second-dive first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 36. ; exit 1
+ fi
+ ;;
+
+ basic3) # third dive - in bunch o' directories, add bunch o' files, delete some, change some.
+ for i in first-dir dir1 dir2 dir3 dir4 ; do
+ cd $i
+
+ # modify some files
+ for j in file6 file8 file10 file12 ; do
+ echo $j >> $j
+ done
+
+ # delete some files
+ rm file7 file9 file11 file13
+
+ if ${CVS} rm file7 file9 file11 file13 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 37-$i. ; exit 1
+ fi
+
+ # and add some new ones
+ for j in file14 file15 file16 file17 ; do
+ echo $j > $j
+ done
+
+ if ${CVS} add file14 file15 file16 file17 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 38-$i. ; exit 1
+ fi
+ done
+ cd ../../../../..
+ if ${CVS} update first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 39. ; exit 1
+ fi
+
+ # fixme: doesn't work right for added files
+ if ${CVS} log first-dir ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 40. # ; exit 1
+ fi
+
+ if ${CVS} status first-dir ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 41. ; exit 1
+ fi
+
+# if ${CVS} diff -u first-dir ${OUTPUT} >> ${LOGFILE} || [ $? = 1 ] ; then
+# true
+# else
+# echo '***' failed test 42. # ; exit 1
+# fi
+
+ if ${CVS} ci -m "third dive" first-dir ${OUTPUT} >>${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 43. ; exit 1
+ fi
+
+ if ${CVS} tag third-dive first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 44. ; exit 1
+ fi
+
+ # Hmm... fixme.
+# if ${CVS} release first-dir ${OUTPUT} ; then
+# true
+# else
+# echo '***' failed test 45. # ; exit 1
+# fi
+
+ # end of third dive
+ rm -rf first-dir
+ ;;
+
+ rtags) # now try some rtags
+ # rtag HEADS
+ if ${CVS} rtag rtagged-by-head first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 46. ; exit 1
+ fi
+
+ # tag by tag
+ if ${CVS} rtag -r rtagged-by-head rtagged-by-tag first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 47. ; exit 1
+ fi
+
+ # tag by revision
+ if ${CVS} rtag -r1.1 rtagged-by-revision first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 48. ; exit 1
+ fi
+
+ # rdiff by revision
+ if ${CVS} rdiff -r1.1 -rrtagged-by-head first-dir ${OUTPUT} >> ${LOGFILE} || [ $? = 1 ] ; then
+ true
+ else
+ echo '***' failed test 49. ; exit 1
+ fi
+
+ # now export by rtagged-by-head and rtagged-by-tag and compare.
+ rm -rf first-dir
+ if ${CVS} export -r rtagged-by-head first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 50. ; exit 1
+ fi
+
+ mv first-dir 1dir
+ if ${CVS} export -r rtagged-by-tag first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 51. ; exit 1
+ fi
+
+ if diff -c -r 1dir first-dir ; then
+ true
+ else
+ echo '***' failed test 52. ; exit 1
+ fi
+ rm -rf 1dir first-dir
+
+ # For some reason, this command has stopped working and hence much of this sequence is currently off.
+ # export by revision vs checkout by rtagged-by-revision and compare.
+# if ${CVS} export -r1.1 first-dir ${OUTPUT} ; then
+# true
+# else
+# echo '***' failed test 53. # ; exit 1
+# fi
+ # note sidestep below
+ #mv first-dir 1dir
+
+ if ${CVS} co -rrtagged-by-revision first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 54. ; exit 1
+ fi
+ # fixme: this is here temporarily to sidestep test 53.
+ ln -s first-dir 1dir
+
+ # directory copies are done in an oblique way in order to avoid a bug in sun's tmp filesystem.
+ mkdir first-dir.cpy ; (cd first-dir ; tar cf - * | (cd ../first-dir.cpy ; tar xf -))
+
+ if diff --exclude=CVS -c -r 1dir first-dir ; then
+ true
+ else
+ echo '***' failed test 55. ; exit 1
+ fi
+
+ # interrupt, while we've got a clean 1.1 here, let's import it into another tree.
+ cd 1dir
+ if ${CVS} import -m "first-import" second-dir first-immigration immigration1 immigration1_0 ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 56. ; exit 1
+ fi
+ cd ..
+
+ if ${CVS} export -r HEAD second-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 57. ; exit 1
+ fi
+
+ if diff --exclude=CVS -c -r first-dir second-dir ; then
+ true
+ else
+ echo '***' failed test 58. ; exit 1
+ fi
+
+ rm -rf 1dir first-dir
+ mkdir first-dir
+ (cd first-dir.cpy ; tar cf - * | (cd ../first-dir ; tar xf -))
+
+ # update the top, cancelling sticky tags, retag, update other copy, compare.
+ cd first-dir
+ if ${CVS} update -A -l *file* ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 59. ; exit 1
+ fi
+
+ # If we don't delete the tag first, cvs won't retag it.
+ # This would appear to be a feature.
+ if ${CVS} tag -l -d rtagged-by-revision ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 60a. ; exit 1
+ fi
+ if ${CVS} tag -l rtagged-by-revision ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 60b. ; exit 1
+ fi
+
+ cd .. ; mv first-dir 1dir
+ mv first-dir.cpy first-dir ; cd first-dir
+ if ${CVS} diff -u ${OUTPUT} >> ${LOGFILE} || [ $? = 1 ] ; then
+ true
+ else
+ echo '***' failed test 61. ; exit 1
+ fi
+
+ if ${CVS} update ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 62. ; exit 1
+ fi
+
+ cd ..
+
+# Haven't investigated why this is failing.
+# if diff --exclude=CVS -c -r 1dir first-dir ; then
+# true
+# else
+# echo '***' failed test 63. # ; exit 1
+# fi
+ rm -rf 1dir first-dir
+
+ if ${CVS} his -e -a ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 64. ; exit 1
+ fi
+ ;;
+
+ death) # next dive. test death support.
+ rm -rf ${CVSROOT_FILENAME}/first-dir
+ mkdir ${CVSROOT_FILENAME}/first-dir
+ if ${CVS} co first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 65 ; exit 1
+ fi
+
+ cd first-dir
+
+ # add a file.
+ touch file1
+ if ${CVS} add file1 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 66 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 67 ; exit 1
+ fi
+
+ # remove
+ rm file1
+ if ${CVS} rm file1 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 68 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 69 ; exit 1
+ fi
+
+ # add again and create second file
+ touch file1 file2
+ if ${CVS} add file1 file2 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 70 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 71 ; exit 1
+ fi
+
+ # log
+ if ${CVS} log file1 ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 72 ; exit 1
+ fi
+
+
+ # branch1
+ if ${CVS} tag -b branch1 ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 73 ; exit 1
+ fi
+
+ # and move to the branch.
+ if ${CVS} update -r branch1 ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 74 ; exit 1
+ fi
+
+ # add a file in the branch
+ echo line1 from branch1 >> file3
+ if ${CVS} add file3 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 75 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 76 ; exit 1
+ fi
+
+ # remove
+ rm file3
+ if ${CVS} rm file3 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 77 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 78 ; exit 1
+ fi
+
+ # add again
+ echo line1 from branch1 >> file3
+ if ${CVS} add file3 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 79 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 80 ; exit 1
+ fi
+
+ # change the first file
+ echo line2 from branch1 >> file1
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 81 ; exit 1
+ fi
+
+ # remove the second
+ rm file2
+ if ${CVS} rm file2 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 82 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 83 ; exit 1
+ fi
+
+ # back to the trunk.
+ if ${CVS} update -A ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 84 ; exit 1
+ fi
+
+ if [ -f file3 ] ; then
+ echo '***' failed test 85 ; exit 1
+ else
+ true
+ fi
+
+ # join
+ if ${CVS} update -j branch1 ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 86 ; exit 1
+ fi
+
+ if [ -f file3 ] ; then
+ true
+ else
+ echo '***' failed test 87 ; exit 1
+ fi
+
+ # update
+ if ${CVS} update ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 88 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} >>${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 89 ; exit 1
+ fi
+
+ # remove first file.
+ rm file1
+ if ${CVS} rm file1 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 90 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m test ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 91 ; exit 1
+ fi
+
+ if [ -f file1 ] ; then
+ echo '***' failed test 92 ; exit 1
+ else
+ true
+ fi
+
+ # back to branch1
+ if ${CVS} update -r branch1 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 93 ; exit 1
+ fi
+
+ if [ -f file1 ] ; then
+ true
+ else
+ echo '***' failed test 94 ; exit 1
+ fi
+
+ # and join
+ if ${CVS} update -j HEAD ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 95 ; exit 1
+ fi
+
+ cd .. ; rm -rf first-dir ${CVSROOT_FILENAME}/first-dir
+ ;;
+
+ import) # test death after import
+ # import
+ mkdir import-dir ; cd import-dir
+
+ for i in 1 2 3 4 ; do
+ echo imported file"$i" > imported-file"$i"
+ done
+
+ if ${CVS} import -m first-import first-dir vendor-branch junk-1_0 ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 96 ; exit 1
+ fi
+ cd ..
+
+ # co
+ if ${CVS} co first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 97 ; exit 1
+ fi
+
+ cd first-dir
+ for i in 1 2 3 4 ; do
+ if [ -f imported-file"$i" ] ; then
+ true
+ else
+ echo '***' failed test 98-$i ; exit 1
+ fi
+ done
+
+ # remove
+ rm imported-file1
+ if ${CVS} rm imported-file1 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 99 ; exit 1
+ fi
+
+ # change
+ # this sleep is significant. Otherwise, on some machines, things happen so
+ # fast that the file mod times do not differ.
+ sleep 1
+ echo local-change >> imported-file2
+
+ # commit
+ if ${CVS} ci -m local-changes ${OUTPUT} >> ${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 100 ; exit 1
+ fi
+
+ # log
+ if ${CVS} log imported-file1 | grep '1.1.1.2 (dead)' ${OUTPUT} ; then
+ echo '***' failed test 101 ; exit 1
+ else
+ true
+ fi
+
+ # update into the vendor branch.
+ if ${CVS} update -rvendor-branch ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 102 ; exit 1
+ fi
+
+ # remove file4 on the vendor branch
+ rm imported-file4
+
+ if ${CVS} rm imported-file4 ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 103 ; exit 1
+ fi
+
+ # commit
+ if ${CVS} ci -m vendor-removed imported-file4 ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 104 ; exit 1
+ fi
+
+ # update to main line
+ if ${CVS} update -A ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 105 ; exit 1
+ fi
+
+ # second import - file4 deliberately unchanged
+ cd ../import-dir
+ for i in 1 2 3 ; do
+ echo rev 2 of file $i >> imported-file"$i"
+ done
+
+ if ${CVS} import -m second-import first-dir vendor-branch junk-2_0 ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 106 ; exit 1
+ fi
+ cd ..
+
+ # co
+ if ${CVS} co first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 107 ; exit 1
+ fi
+
+ cd first-dir
+
+ if [ -f imported-file1 ] ; then
+ echo '***' failed test 108 ; exit 1
+ else
+ true
+ fi
+
+ for i in 2 3 ; do
+ if [ -f imported-file"$i" ] ; then
+ true
+ else
+ echo '***' failed test 109-$i ; exit 1
+ fi
+ done
+
+ # check vendor branch for file4
+ if ${CVS} update -rvendor-branch ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 110 ; exit 1
+ fi
+
+ if [ -f imported-file4 ] ; then
+ true
+ else
+ echo '***' failed test 111 ; exit 1
+ fi
+
+ # update to main line
+ if ${CVS} update -A ${OUTPUT} 2>> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 112 ; exit 1
+ fi
+
+ cd ..
+
+ if ${CVS} co -jjunk-1_0 -jjunk-2_0 first-dir ${OUTPUT} >>${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 113 ; exit 1
+ fi
+
+ cd first-dir
+
+ if [ -f imported-file1 ] ; then
+ echo '***' failed test 114 ; exit 1
+ else
+ true
+ fi
+
+ for i in 2 3 ; do
+ if [ -f imported-file"$i" ] ; then
+ true
+ else
+ echo '***' failed test 115-$i ; exit 1
+ fi
+ done
+
+ if cat imported-file2 | grep '====' ${OUTPUT} >> ${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 116 ; exit 1
+ fi
+ cd .. ; rm -rf first-dir ${CVSROOT_FILENAME}/first-dir
+ ;;
+
+ new) # look for stray "no longer pertinent" messages.
+ rm -rf first-dir ${CVSROOT_FILENAME}/first-dir
+ mkdir ${CVSROOT_FILENAME}/first-dir
+
+ if ${CVS} co first-dir ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 117 ; exit 1
+ fi
+
+ cd first-dir
+ touch a
+
+ if ${CVS} add a ${OUTPUT} 2>>${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 118 ; exit 1
+ fi
+
+ if ${CVS} ci -m added ${OUTPUT} >>${LOGFILE} 2>&1; then
+ true
+ else
+ echo '***' failed test 119 ; exit 1
+ fi
+
+ rm a
+
+ if ${CVS} rm a ${OUTPUT} 2>>${LOGFILE}; then
+ true
+ else
+ echo '***' failed test 120 ; exit 1
+ fi
+
+ if ${CVS} ci -m removed ${OUTPUT} ; then
+ true
+ else
+ echo '***' failed test 121 ; exit 1
+ fi
+
+ if ${CVS} update -A ${OUTPUT} 2>&1 | grep longer ; then
+ echo '***' failed test 122 ; exit 1
+ else
+ true
+ fi
+
+ if ${CVS} update -rHEAD 2>&1 | grep longer ; then
+ echo '***' failed test 123 ; exit 1
+ else
+ true
+ fi
+
+ cd .. ; rm -rf first-dir ; rm -rf ${CVSROOT_FILENAME}/first-dir
+ ;;
+
+ *) echo Ooops - $what ;;
+ esac
+done
+
+echo Ok.
+
+# Local Variables:
+# fill-column: 131
+# End:
+
+# end of sanity.sh
diff --git a/gnu/usr.bin/cvs/doc/cvs-paper.ms b/gnu/usr.bin/cvs/doc/cvs-paper.ms
new file mode 100644
index 0000000..567179b
--- /dev/null
+++ b/gnu/usr.bin/cvs/doc/cvs-paper.ms
@@ -0,0 +1,1073 @@
+.\" soelim cvs.ms | pic | tbl | troff -ms
+.\" @(#)cvs.ms 1.2 92/01/30
+.\"
+.\" troff source to the cvs USENIX article, Winter 1990, Washington, D.C.
+.\" Copyright (c) 1989, Brian Berliner
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 1, or (at your option)
+.\" any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+.\"
+.\" The author can be reached at: berliner@prisma.com
+.\"
+.de SP
+.if n .sp
+.if t .sp .5
+..
+.de hl
+.br
+.in +0.5i
+\l'\\n(LLu-1i'
+.in -0.5i
+.sp
+..
+.OH ""
+.nr PS 11
+.nr PO 1.25i
+.pl -0.2i
+.TL
+.ps 14
+.ft B
+.nf
+CVS II:
+Parallelizing Software Development
+.fi
+.ft
+.ps
+.AU
+.ps 12
+.ft I
+Brian Berliner
+.ft
+.ps
+.AI
+.ps 12
+.ft I
+Prisma, Inc.
+5465 Mark Dabling Blvd.
+Colorado Springs, CO 80918
+berliner@prisma.com
+.ft
+.ps
+.AB
+The program described in this paper fills a need in the UNIX
+community for a freely available tool to manage software revision and
+release control in a multi-developer, multi-directory, multi-group
+environment.
+This tool also addresses the increasing need for tracking third-party vendor
+source distributions while trying to maintain local modifications to
+earlier releases.
+.AE
+.NH
+Background
+.PP
+In large software development projects, it is usually necessary for more
+than one software developer to be modifying (usually different) modules of the
+code at the same time.
+Some of these code modifications are done in an
+experimental sense, at least until the code functions correctly, and some
+testing of the entire program is usually necessary.
+Then, the modifications are returned to a master source repository
+so that others in the project can
+enjoy the new bug-fix or functionality.
+In order to manage such a project, some sort of revision control system is
+necessary.
+.PP
+Specifically, UNIX\**
+.FS
+UNIX is a registered trademark of AT&T.
+.FE
+kernel development is an excellent example of the
+problems that an adequate revision control system must address.
+The SunOS\**
+.FS
+SunOS is a trademark of Sun Microsystems, Inc.
+.FE
+kernel is composed of over a thousand files spread across a
+hierarchy of dozens of directories.\**
+.FS
+Yes, the SunOS 4.0 kernel is composed of over a \fIthousand\fP files!
+.FE
+Pieces of the kernel must be edited
+by many software developers within an organization.
+While undesirable in
+theory, it is not uncommon to have two or more people making
+modifications to the same file within the kernel sources in
+order to facilitate a desired change.
+Existing revision control systems like
+.SM
+RCS
+.LG
+[Tichy] or
+.SM
+SCCS
+.LG
+[Bell] serialize file modifications by
+allowing only one developer to have a writable copy of a particular file at
+any one point in time.
+That developer is said to
+have \*Qlocked\*U the file for his exclusive use, and no other developer is
+allowed to check out a writable copy of the file until the locking
+developer has finished impeding others' productivity.
+Development pressures of productivity and deadlines
+often force organizations to require that multiple developers be able to
+simultaneously edit
+copies of the same revision controlled file.
+.PP
+The necessity for multiple developers to modify the same file concurrently
+questions the value of serialization-based policies in traditional revision
+control.
+This paper discusses the approach that
+Prisma took in adapting a standard revision control system,
+.SM
+RCS\c
+.LG
+, along with an existing public-domain collection of shell scripts that sits
+atop
+.SM
+RCS
+.LG
+and provides the basic conflict-resolution algorithms.
+The resulting
+program, \fBcvs\fP, addresses not only the issue of conflict-resolution in
+a multi-developer open-editing environment, but also the issues of
+software release control and vendor source support and integration.
+.NH
+The CVS Program
+.PP
+\fBcvs\fP
+(Concurrent Versions System)
+is a front end to the
+.SM
+RCS
+.LG
+revision control system which extends
+the notion of revision control from a collection of files in a single
+directory to a hierarchical collection of directories each containing
+revision controlled files.
+Directories and files in the \fBcvs\fP system can be combined together in
+many ways to form a software release.
+\fBcvs\fP
+provides the functions necessary to manage these software releases and to
+control the concurrent editing of source files among multiple software
+developers.
+.PP
+The six major features of \fBcvs\fP are listed below, and will be
+described in more detail in the following sections:
+.RS
+.IP 1.
+Concurrent access and conflict-resolution algorithms to guarantee that
+source changes are not \*Qlost.\*U
+.IP 2.
+Support for tracking third-party vendor source distributions while
+maintaining the local modifications made to those sources.
+.IP 3.
+A flexible module database that provides a symbolic mapping of names to
+components of a larger software distribution.
+This symbolic mapping provides for location independence within the software
+release and, for example, allows one to check out a copy of the \*Qdiff\*U
+program without ever knowing that the sources to \*Qdiff\*U actually reside
+in the \*Qbin/diff\*U directory.
+.IP 4.
+Configurable logging support allows all \*Qcommitted\*U source file changes
+to be logged using an arbitrary program to save the log messages in a file,
+notesfile, or news database.
+.IP 5.
+A software release can be symbolically tagged and checked out at any time
+based on that tag.
+An exact copy of a previous software release can be checked out at
+any time, \fIregardless\fP of whether files or directories have been
+added/removed from the \*Qcurrent\*U software release.
+As well,
+a \*Qdate\*U can be used to check out the \fIexact\fP version of the software
+release as of the specified date.
+.IP 6.
+A \*Qpatch\*U format file [Wall] can be produced between two software
+releases, even if the releases span multiple directories.
+.RE
+.PP
+The sources maintained by \fBcvs\fP are kept within a single directory
+hierarchy known as the \*Qsource repository.\*U
+This \*Qsource repository\*U holds the actual
+.SM
+RCS
+.LG
+\*Q,v\*U files directly, as well as a special per-repository directory
+(\c
+.SM
+CVSROOT.adm\c
+.LG
+) which contains a small number of administrative files that describe the
+repository and how it can be accessed.
+See Figure 1 for a picture of the \fBcvs\fP tree.
+.KF
+.hl
+.DS B
+.PS
+line from 4.112,9.200 to 5.550,8.887
+line from 5.447,8.884 to 5.550,8.887 to 5.458,8.933
+line from 4.112,9.200 to 4.550,8.950
+line from 4.451,8.978 to 4.550,8.950 to 4.476,9.021
+line from 4.112,9.200 to 3.737,8.887
+line from 3.798,8.971 to 3.737,8.887 to 3.830,8.932
+line from 3.612,8.762 to 4.737,8.137
+line from 4.638,8.164 to 4.737,8.137 to 4.662,8.208
+line from 3.612,8.762 to 3.737,8.137
+line from 3.693,8.231 to 3.737,8.137 to 3.742,8.240
+line from 3.612,8.762 to 2.612,8.200
+line from 2.687,8.271 to 2.612,8.200 to 2.712,8.227
+line from 2.362,9.262 to 2.737,8.950
+line from 2.645,8.995 to 2.737,8.950 to 2.677,9.033
+line from 2.362,9.262 to 1.925,8.950
+line from 1.992,9.028 to 1.925,8.950 to 2.021,8.988
+line from 3.362,9.762 to 4.050,9.387
+line from 3.950,9.413 to 4.050,9.387 to 3.974,9.457
+line from 3.362,9.762 to 2.487,9.387
+line from 2.570,9.450 to 2.487,9.387 to 2.589,9.404
+.ps 11
+"newfs.c,v" at 4.487,8.043 ljust
+.ps 11
+"mkfs.c,v" at 3.487,8.043 ljust
+.ps 11
+"Makefile,v" at 2.237,8.043 ljust
+.ps 11
+"newfs" at 3.487,8.793 ljust
+.ps 11
+"halt.c,v" at 5.487,8.793 ljust
+.ps 11
+"Makefile,v" at 4.237,8.793 ljust
+.ps 11
+"modules,v" at 2.487,8.793 ljust
+.ps 11
+"loginfo,v" at 1.488,8.793 ljust
+.ps 11
+"etc" at 3.987,9.293 ljust
+.ps 11
+"CVSROOT.adm" at 1.988,9.293 ljust
+.ps 11
+"/src/master" at 2.987,9.793 ljust
+.PE
+.DE
+.hl
+.ce 100
+.LG
+\fBFigure 1.\fP
+.SM
+\fBcvs\fP Source Repository
+.ce 0
+.sp
+.KE
+.NH 2
+Software Conflict Resolution\**
+.FS
+The basic conflict-resolution algorithms
+used in the \fBcvs\fP program find their roots
+in the original work done by Dick Grune at Vrije Universiteit in Amsterdam
+and posted to \fBcomp.sources.unix\fP in the volume 6 release sometime in 1986.
+This original version of \fBcvs\fP was a collection of shell scripts that
+combined to form a front end to the
+.SM
+RCS
+.LG
+programs.
+.FE
+.PP
+\fBcvs\fP allows several software developers to edit personal copies of a
+revision controlled file concurrently.
+The revision number of each checked out file is maintained independently
+for each user, and \fBcvs\fP forces the checked out file to be current with
+the \*Qhead\*U revision before it can be \*Qcommitted\*U as a permanent change.
+A checked out file is brought up-to-date with the \*Qhead\*U revision using
+the \*Qupdate\*U command of \fBcvs\fP.
+This command compares the \*Qhead\*U revision number with that of the user's
+file and performs an
+.SM
+RCS
+.LG
+merge operation if they are not the same.
+The result of the merge is a file that contains the user's modifications
+and those modifications that were \*Qcommitted\*U after the user
+checked out his version of the file (as well as a backup copy of the
+user's original file).
+\fBcvs\fP points out any conflicts during the merge.
+It is the user's responsibility to resolve these conflicts
+and to \*Qcommit\*U his/her changes when ready.
+.PP
+Although the \fBcvs\fP conflict-resolution algorithm was defined in 1986,
+it is remarkably similar to the \*QCopy-Modify-Merge\*U scenario included
+with NSE\**
+.FS
+NSE is the Network Software Environment, a product of Sun Microsystems, Inc.
+.FE
+and described in [Honda] and [Courington].
+The following explanation from [Honda] also applies to \fBcvs\fP:
+.QP
+Simply stated, a developer copies an object without locking it, modifies
+the copy, and then merges the modified copy with the original.
+This paradigm allows developers to work in isolation from one another since
+changes are made to copies of objects.
+Because locks are not used, development is not serialized and can proceed
+in parallel.
+Developers, however, must merge objects after the changes have been made.
+In particular, a developer must resolve conflicts when the same object has
+been modified by someone else.
+.PP
+In practice, Prisma has found that conflicts that occur when the same
+object has been modified by someone else are quite rare.
+When they do happen, the changes made by the other developer are usually
+easily resolved.
+This practical use has shown that the \*QCopy-Modify-Merge\*U paradigm is a
+correct and useful one.
+.NH 2
+Tracking Third-Party Source Distributions
+.PP
+Currently, a large amount of software is based on source
+distributions from a third-party distributor.
+It is often the case that local modifications are to be made to this
+distribution, \fIand\fP that the vendor's future releases should be
+tracked.
+Rolling your local modifications forward into the new vendor release is a
+time-consuming task, but \fBcvs\fP can ease this burden somewhat.
+The \fBcheckin\fP program of \fBcvs\fP initially sets up a source
+repository by integrating the source modules directly from the vendor's
+release, preserving the directory hierarchy of the vendor's distribution.
+The branch support of
+.SM
+RCS
+.LG
+is used to build this vendor release as a branch of the main
+.SM
+RCS
+.LG
+trunk.
+Figure 2 shows how the \*Qhead\*U tracks a sample vendor
+branch when no local modifications have been made to the file.
+.KF
+.hl
+.DS B
+.PS
+ellipse at 3.237,6.763 wid 1.000 ht 0.500
+dashwid = 0.050i
+line dashed from 3.237,7.513 to 3.737,7.513 to 3.737,9.762 to 4.237,9.762
+line from 4.138,9.737 to 4.237,9.762 to 4.138,9.787
+line dashed from 2.237,8.262 to 3.237,8.262 to 3.237,7.013
+line from 3.212,7.112 to 3.237,7.013 to 3.262,7.112
+line from 3.737,6.763 to 4.237,6.763
+line from 4.138,6.737 to 4.237,6.763 to 4.138,6.788
+line from 2.237,6.763 to 2.737,6.763
+line from 2.637,6.737 to 2.737,6.763 to 2.637,6.788
+line from 1.738,6.013 to 1.738,6.513
+line from 1.762,6.413 to 1.738,6.513 to 1.713,6.413
+line from 1.238,7.013 to 2.237,7.013 to 2.237,6.513 to 1.238,6.513 to 1.238,7.013
+line from 4.237,9.012 to 5.237,9.012 to 5.237,8.512 to 4.237,8.512 to 4.237,9.012
+line from 4.237,8.012 to 5.237,8.012 to 5.237,7.513 to 4.237,7.513 to 4.237,8.012
+line from 4.237,7.013 to 5.237,7.013 to 5.237,6.513 to 4.237,6.513 to 4.237,7.013
+line from 4.737,7.013 to 4.737,7.513
+line from 4.763,7.413 to 4.737,7.513 to 4.712,7.413
+line from 4.737,8.012 to 4.737,8.512
+line from 4.763,8.412 to 4.737,8.512 to 4.712,8.412
+line from 4.237,10.012 to 5.237,10.012 to 5.237,9.512 to 4.237,9.512 to 4.237,10.012
+line from 4.737,9.012 to 4.737,9.512
+line from 4.763,9.412 to 4.737,9.512 to 4.712,9.412
+line from 5.987,5.013 to 5.987,6.013 to 0.988,6.013 to 0.988,5.013 to 5.987,5.013
+.ps 11
+"\"HEAD\"" at 1.550,8.231 ljust
+.ps 11
+"'SunOS'" at 2.987,6.293 ljust
+.ps 11
+"1.1.1" at 3.050,6.793 ljust
+.ps 11
+"1.1" at 1.613,6.793 ljust
+.ps 11
+"1.1.1.1" at 4.487,6.793 ljust
+.ps 11
+"1.1.1.2" at 4.487,7.793 ljust
+.ps 11
+"1.1.1.3" at 4.487,8.793 ljust
+.ps 11
+"1.1.1.4" at 4.487,9.793 ljust
+.ps 11
+"'SunOS_4_0'" at 5.487,6.793 ljust
+.ps 11
+"'SunOS_4_0_1'" at 5.487,7.793 ljust
+.ps 11
+"'YAPT_5_5C'" at 5.487,8.793 ljust
+.ps 11
+"'SunOS_4_0_3'" at 5.487,9.793 ljust
+.ps 11
+"rcsfile.c,v" at 2.987,5.543 ljust
+.PE
+.DE
+.hl
+.ce 100
+.LG
+\fBFigure 2.\fP
+.SM
+\fBcvs\fP Vendor Branch Example
+.ce 0
+.sp .3
+.KE
+Once this is done, developers can check out files and make local changes to
+the vendor's source distribution.
+These local changes form a new branch to the tree which is then used as the
+source for future check outs.
+Figure 3 shows how the \*Qhead\*U moves to the main
+.SM
+RCS
+.LG
+trunk when a local modification is made.
+.KF
+.hl
+.DS B
+.PS
+ellipse at 3.237,6.763 wid 1.000 ht 0.500
+dashwid = 0.050i
+line dashed from 2.800,9.075 to 1.738,9.075 to 1.738,8.012
+line from 1.713,8.112 to 1.738,8.012 to 1.762,8.112
+line from 1.738,7.013 to 1.738,7.513
+line from 1.762,7.413 to 1.738,7.513 to 1.713,7.413
+line from 1.238,8.012 to 2.237,8.012 to 2.237,7.513 to 1.238,7.513 to 1.238,8.012
+line from 3.737,6.763 to 4.237,6.763
+line from 4.138,6.737 to 4.237,6.763 to 4.138,6.788
+line from 2.237,6.763 to 2.737,6.763
+line from 2.637,6.737 to 2.737,6.763 to 2.637,6.788
+line from 1.738,6.013 to 1.738,6.513
+line from 1.762,6.413 to 1.738,6.513 to 1.713,6.413
+line from 1.238,7.013 to 2.237,7.013 to 2.237,6.513 to 1.238,6.513 to 1.238,7.013
+line from 4.237,9.012 to 5.237,9.012 to 5.237,8.512 to 4.237,8.512 to 4.237,9.012
+line from 4.237,8.012 to 5.237,8.012 to 5.237,7.513 to 4.237,7.513 to 4.237,8.012
+line from 4.237,7.013 to 5.237,7.013 to 5.237,6.513 to 4.237,6.513 to 4.237,7.013
+line from 4.737,7.013 to 4.737,7.513
+line from 4.763,7.413 to 4.737,7.513 to 4.712,7.413
+line from 4.737,8.012 to 4.737,8.512
+line from 4.763,8.412 to 4.737,8.512 to 4.712,8.412
+line from 4.237,10.012 to 5.237,10.012 to 5.237,9.512 to 4.237,9.512 to 4.237,10.012
+line from 4.737,9.012 to 4.737,9.512
+line from 4.763,9.412 to 4.737,9.512 to 4.712,9.412
+line from 5.987,5.013 to 5.987,6.013 to 0.988,6.013 to 0.988,5.013 to 5.987,5.013
+.ps 11
+"1.2" at 1.613,7.793 ljust
+.ps 11
+"\"HEAD\"" at 2.862,9.043 ljust
+.ps 11
+"'SunOS'" at 2.987,6.293 ljust
+.ps 11
+"1.1.1" at 3.050,6.793 ljust
+.ps 11
+"1.1" at 1.613,6.793 ljust
+.ps 11
+"1.1.1.1" at 4.487,6.793 ljust
+.ps 11
+"1.1.1.2" at 4.487,7.793 ljust
+.ps 11
+"1.1.1.3" at 4.487,8.793 ljust
+.ps 11
+"1.1.1.4" at 4.487,9.793 ljust
+.ps 11
+"'SunOS_4_0'" at 5.487,6.793 ljust
+.ps 11
+"'SunOS_4_0_1'" at 5.487,7.793 ljust
+.ps 11
+"'YAPT_5_5C'" at 5.487,8.793 ljust
+.ps 11
+"'SunOS_4_0_3'" at 5.487,9.793 ljust
+.ps 11
+"rcsfile.c,v" at 2.987,5.543 ljust
+.PE
+.DE
+.hl
+.ce 100
+.LG
+\fBFigure 3.\fP
+.SM
+\fBcvs\fP Local Modification to Vendor Branch
+.ce 0
+.sp
+.KE
+.PP
+When a new version of the vendor's source distribution arrives, the
+\fBcheckin\fP program adds the new and changed vendor's files to the
+already existing source repository.
+For files that have not been changed locally, the new file from the
+vendor becomes the current \*Qhead\*U revision.
+For files that have been modified locally, \fBcheckin\fP warns that the
+file must be merged with the new vendor release.
+The \fBcvs\fP \*Qjoin\*U command is a useful tool that aids this process by
+performing the necessary
+.SM
+RCS
+.LG
+merge, as is done above when performing an \*Qupdate.\*U
+.PP
+There is also limited support for \*Qdual\*U derivations for source files.
+See Figure 4 for a sample dual-derived file.
+.KF
+.hl
+.DS B
+.PS
+ellipse at 2.337,8.575 wid 0.700 ht 0.375
+ellipse at 2.312,9.137 wid 0.700 ht 0.375
+line from 1.225,9.012 to 1.225,9.363
+line from 1.250,9.263 to 1.225,9.363 to 1.200,9.263
+line from 0.875,9.725 to 1.600,9.725 to 1.600,9.363 to 0.875,9.363 to 0.875,9.725
+line from 0.875,9.012 to 1.600,9.012 to 1.600,8.650 to 0.875,8.650 to 0.875,9.012
+line from 4.050,10.200 to 4.775,10.200 to 4.775,9.850 to 4.050,9.850 to 4.050,10.200
+line from 4.050,9.475 to 4.775,9.475 to 4.775,9.113 to 4.050,9.113 to 4.050,9.475
+line from 4.050,8.762 to 4.775,8.762 to 4.775,8.400 to 4.050,8.400 to 4.050,8.762
+line from 4.425,8.762 to 4.425,9.113
+line from 4.450,9.013 to 4.425,9.113 to 4.400,9.013
+line from 4.425,9.475 to 4.425,9.850
+line from 4.450,9.750 to 4.425,9.850 to 4.400,9.750
+line from 3.050,10.000 to 3.775,10.000 to 3.775,9.637 to 3.050,9.637 to 3.050,10.000
+line from 3.050,9.312 to 3.775,9.312 to 3.775,8.950 to 3.050,8.950 to 3.050,9.312
+line from 0.713,7.325 to 0.713,8.075 to 4.925,8.075 to 4.925,7.325 to 0.713,7.325
+line from 1.238,8.075 to 1.238,8.637
+line from 1.262,8.537 to 1.238,8.637 to 1.213,8.537
+line from 1.613,8.825 to 1.975,8.575
+line from 1.878,8.611 to 1.975,8.575 to 1.907,8.652
+line from 2.675,8.575 to 4.050,8.575
+line from 3.950,8.550 to 4.050,8.575 to 3.950,8.600
+line from 2.675,9.137 to 3.050,9.137
+line from 2.950,9.112 to 3.050,9.137 to 2.950,9.162
+line from 3.425,9.325 to 3.425,9.637
+line from 3.450,9.537 to 3.425,9.637 to 3.400,9.537
+line from 1.613,8.825 to 1.925,9.137
+line from 1.872,9.049 to 1.925,9.137 to 1.837,9.084
+.ps 11
+"'BSD'" at 2.138,9.481 ljust
+.ps 11
+"1.2" at 1.113,9.543 ljust
+.ps 11
+"1.1" at 1.125,8.831 ljust
+.ps 11
+"1.1.1.1" at 4.175,8.543 ljust
+.ps 11
+"1.1.1.2" at 4.175,9.281 ljust
+.ps 11
+"1.1.1.3" at 4.175,9.993 ljust
+.ps 11
+"1.1.2.2" at 3.175,9.793 ljust
+.ps 11
+"1.1.2.1" at 3.175,9.106 ljust
+.ps 11
+"rcsfile.c,v" at 2.425,7.706 ljust
+.ps 11
+"1.1.1" at 2.175,8.568 ljust
+.ps 11
+"'SunOS'" at 2.125,8.243 ljust
+.ps 11
+"1.1.2" at 2.163,9.131 ljust
+.PE
+.DE
+.hl
+.ce 100
+.LG
+\fBFigure 4.\fP
+.SM
+\fBcvs\fP Support For \*QDual\*U Derivations
+.ce 0
+.sp
+.KE
+This example tracks the SunOS distribution but includes major changes from
+Berkeley.
+These BSD files are saved directly in the
+.SM
+RCS
+.LG
+file off a new branch.
+.NH 2
+Location Independent Module Database
+.PP
+\fBcvs\fP contains support for a simple, yet powerful, \*Qmodule\*U database.
+For reasons of efficiency, this database is stored in \fBndbm\fP\|(3) format.
+The module database is used to apply names to collections of directories
+and files as a matter of convenience for checking out pieces of a large
+software distribution.
+The database records the physical location of the sources as a form of
+information hiding, allowing one to check out whole directory hierarchies
+or individual files without regard for their actual location within the
+global source distribution.
+.PP
+Consider the following small sample of a module database, which must be
+tailored manually to each specific source repository environment:
+.DS
+\f(CW #key [-option argument] directory [files...]
+ diff bin/diff
+ libc lib/libc
+ sys -o sys/tools/make_links sys
+ modules -i mkmodules CVSROOT.adm modules
+ kernel -a sys lang/adb
+ ps bin Makefile ps.c\fP
+.DE
+.PP
+The \*Qdiff\*U and \*Qlibc\*U modules refer to whole directory hierarchies that
+are extracted on check out.
+The \*Qsys\*U module extracts the \*Qsys\*U hierarchy, and runs the
+\*Qmake_links\*U program at the end of the check out process (the \fI-o\fP
+option specifies a program to run on check\fIo\fPut).
+The \*Qmodules\*U module allows one to edit the module database file and
+runs the \*Qmkmodules\*U program on check\fIi\fPn to regenerate the
+\fBndbm\fP database that \fBcvs\fP uses.
+The \*Qkernel\*U module is an alias (as the \fI-a\fP option specifies)
+which causes the remaining arguments after the \fI-a\fP to be interpreted
+exactly as if they had been specified on the command line.
+This is useful for objects that require shared pieces of code from far away
+places to be compiled (as is the case with the kernel debugger, \fBkadb\fP,
+which shares code with the standard \fBadb\fP debugger).
+The \*Qps\*U module shows that the source for \*Qps\*U lives in the \*Qbin\*U
+directory, but only \fIMakefile\fP and \fIps.c\fP are required to build the
+object.
+.PP
+The module database at Prisma is now populated for the entire UNIX
+distribution and thereby allows us to issue the
+following convenient commands to check out components of the UNIX
+distribution without regard for their actual location within the master source
+repository:
+.DS
+\f(CW example% cvs checkout diff
+ example% cvs checkout libc ps
+ example% cd diff; make\fP
+.DE
+.PP
+In building the module database file, it is quite possible to have name
+conflicts within a global software distribution.
+For example, SunOS provides two \fBcat\fP programs:
+one for the standard environment, \fI/bin/cat\fP, and one for the System V
+environment, \fI/usr/5bin/cat\fP.
+We resolved this conflict by naming the standard \fBcat\fP module
+\*Qcat\*U, and the System V \fBcat\fP module \*Q5cat\*U.
+Similar name modifications must be applied to other conflicting names, as
+might be found between a utility program and a library function, though
+Prisma chose not to include individual library functions within the module
+database at this time.
+.NH 2
+Configurable Logging Support
+.PP
+The \fBcvs\fP \*Qcommit\*U command is used to make a permanent change to the
+master source repository (where the
+.SM
+RCS
+.LG
+\*Q,v\*U files live).
+Whenever a \*Qcommit\*U is done, the log message for the change is carefully
+logged by an arbitrary program (in a file, notesfile, news database, or
+mail).
+For example, a collection of these updates can be used to produce release
+notices.
+\fBcvs\fP can be configured to send log updates through one or more filter
+programs, based on a regular expression match on the directory that is
+being changed.
+This allows multiple related or unrelated projects to exist within a single
+\fBcvs\fP source repository tree, with each different project sending its
+\*Qcommit\*U reports to a unique log device.
+.PP
+A sample logging configuration file might look as follows:
+.DS
+\f(CW #regex filter-program
+ DEFAULT /usr/local/bin/nfpipe -t %s utils.updates
+ ^diag /usr/local/bin/nfpipe -t %s diag.updates
+ ^local /usr/local/bin/nfpipe -t %s local.updates
+ ^perf /usr/local/bin/nfpipe -t %s perf.updates
+ ^sys /usr/local/bin/nfpipe -t %s kernel.updates\fP
+.DE
+.PP
+This sample allows the diagnostics and performance groups to
+share the same source repository with the kernel and utilities groups.
+Changes that they make are sent directly to their own notesfile [Essick]
+through the \*Qnfpipe\*U program.
+A sufficiently simple title is substituted for the \*Q%s\*U argument before
+the filter program is executed.
+This logging configuration file is tailored manually to each specific
+source repository environment.
+.NH 2
+Tagged Releases and Dates
+.PP
+Any release can be given a symbolic tag name that is stored directly in the
+.SM
+RCS
+.LG
+files.
+This tag can be used at any time to get an exact copy of any previous
+release.
+With equal ease, one can also extract an exact copy of the source files as
+of any arbitrary date in the past as well.
+Thus, all that's required to tag the current kernel, and to tag the kernel
+as of the Fourth of July is:
+.DS
+\f(CW example% cvs tag TEST_KERNEL kernel
+ example% cvs tag -D 'July 4' PATRIOTIC_KERNEL kernel\fP
+.DE
+The following command would retrieve an exact copy of the test kernel at
+some later date:
+.DS
+\f(CW example% cvs checkout -fp -rTEST_KERNEL kernel\fP
+.DE
+The \fI-f\fP option causes only files that match the specified tag to be
+extracted, while the \fI-p\fP option automatically prunes empty directories.
+Consequently, directories added to the kernel after the test kernel was
+tagged are not included in the newly extracted copy of the test kernel.
+.PP
+The \fBcvs\fP date support has exactly the same interface as that provided
+with
+.SM
+RCS\c
+.LG
+, however \fBcvs\fP must process the \*Q,v\*U files directly due to the
+special handling required by the vendor branch support.
+The standard
+.SM
+RCS
+.LG
+date handling only processes one branch (or the main trunk) when checking
+out based on a date specification.
+\fBcvs\fP must instead process the current \*Qhead\*U branch and, if a
+match is not found, proceed to look for a match on the vendor branch.
+This, combined with reasons of performance, is why \fBcvs\fP processes
+revision (symbolic and numeric) and date specifications directly from the
+\*Q,v\*U files.
+.NH 2
+Building \*Qpatch\*U Source Distributions
+.PP
+\fBcvs\fP can produce a \*Qpatch\*U format [Wall] output file which can be
+used to bring a previously released software distribution current with the
+newest release.
+This patch file supports an entire directory hierarchy within a single
+patch, as well as being able to add whole new files to the previous
+release.
+One can combine symbolic revisions and dates together to display changes in
+a very generic way:
+.DS
+\f(CW example% cvs patch -D 'December 1, 1988' \e
+ -D 'January 1, 1989' sys\fP
+.DE
+This example displays the kernel changes made in the month of December,
+1988.
+To release a patch file, for example, to take the \fBcvs\fP distribution
+from version 1.0 to version 1.4 might be done as follows:
+.DS
+\f(CW example% cvs patch -rCVS_1_0 -rCVS_1_4 cvs\fP
+.DE
+.NH
+CVS Experience
+.NH 2
+Statistics
+.PP
+A quick summary of the scale that \fBcvs\fP is addressing today
+can be found in Table 1.
+.KF
+.TS
+box center tab(:);
+c s
+c s
+c | c
+l | n .
+\fB\s+2Revision Control Statistics at Prisma
+as of 11/11/89\fP\s-2
+_
+How Many...:Total
+=
+Files:17243
+Directories:1005
+Lines of code:3927255
+Removed files:131
+Software developers:14
+Software groups:6
+Megabytes of source:128
+.TE
+.ce 100
+.LG
+\fBTable 1.\fP
+.SM
+\fBcvs\fP Statistics
+.ce 0
+.sp .3
+.KE
+Table 2 shows the history of files changed or added and the number
+of source lines affected by the change at Prisma.
+Only changes made to the kernel sources are included.
+.KF
+.TS
+box center tab(:);
+c s s s s
+c s s s s
+c || c | c || c | c
+c || c | c || c | c
+l || n | n || n | n.
+\fB\s+2Prisma Kernel Source File Changes
+By Month, 1988-1989\fP\s-2
+_
+Month:# Changed:# Lines:# Added:# Lines
+\^:Files:Changed:Files:Added
+=
+Dec:87:3619:68:9266
+Jan:39:4324:0:0
+Feb:73:1578:5:3550
+Mar:99:5301:18:11461
+Apr:112:7333:11:5759
+May:138:5371:17:13986
+Jun:65:2261:27:12875
+Jul:34:2000:1:58
+Aug:65:6378:8:4724
+Sep:266:23410:113:39965
+Oct:22:621:1:155
+Total:1000:62196:269:101799
+.TE
+.ce 100
+.LG
+\fBTable 2.\fP
+.SM
+\fBcvs\fP Usage History for the Kernel
+.ce 0
+.sp
+.KE
+The large number of source file changes made in September are the result of
+merging the SunOS 4.0.3 sources into the kernel.
+This merge process is described in section 3.3.
+.NH 2
+Performance
+.PP
+The performance of \fBcvs\fP is currently quite reasonable.
+Little effort has been expended on tuning \fBcvs\fP, although performance
+related decisions were made during the \fBcvs\fP design.
+For example, \fBcvs\fP parses the
+.SM
+RCS
+.LG
+\*Q,v\*U files directly instead of running an
+.SM
+RCS
+.LG
+process.
+This includes following branches as well as integrating with the vendor
+source branches and the main trunk when checking out files based on a date.
+.PP
+Checking out the entire kernel source tree (1223 files/59 directories)
+currently takes 16 wall clock minutes on a Sun-4/280.
+However, bringing the tree up-to-date with the current kernel sources, once
+it has been checked out, takes only 1.5 wall clock minutes.
+Updating the \fIcomplete\fP 128 MByte source tree under \fBcvs\fP control
+(17243 files/1005 directories) takes roughly 28 wall clock minutes and
+utilizes one-third of the machine.
+For now this is entirely acceptable; improvements on these numbers will
+possibly be made in the future.
+.NH 2
+The SunOS 4.0.3 Merge
+.PP
+The true test of the \fBcvs\fP vendor branch support came with the arrival
+of the SunOS 4.0.3 source upgrade tape.
+As described above, the \fBcheckin\fP program was used to install the new
+sources and the resulting output file listed the files that had been
+locally modified, needing to be merged manually.
+For the kernel, there were 94 files in conflict.
+The \fBcvs\fP \*Qjoin\*U command was used on each of the 94 conflicting
+files, and the remaining conflicts were resolved.
+.PP
+The \*Qjoin\*U command performs an \fBrcsmerge\fP operation.
+This in turn uses \fI/usr/lib/diff3\fP to produce a three-way diff file.
+As it happens, the \fBdiff3\fP program has a hard-coded limit of 200
+source-file changes maximum.
+This proved to be too small for a few of the kernel files that needed
+merging by hand, due to the large number of local changes that Prisma had
+made.
+The \fBdiff3\fP problem was solved by increasing the hard-coded limit by an
+order of magnitude.
+.PP
+The SunOS 4.0.3 kernel source upgrade distribution contained
+346 files, 233 of which were modifications to previously released files,
+and 113 of which were newly added files.
+\fBcheckin\fP added the 113 new files to the source repository
+without intervention.
+Of the 233 modified files, 139 dropped in cleanly by \fBcheckin\fP, since
+Prisma had not made any local changes to them, and 94 required manual
+merging due to local modifications.
+The 233 modified files consisted of 20,766 lines of differences.
+It took one developer two days to manually merge the 94 files using the
+\*Qjoin\*U command and resolving conflicts manually.
+An additional day was required for kernel debugging.
+The entire process of merging over 20,000 lines of differences was
+completed in less than a week.
+This one time-savings alone was justification enough for the \fBcvs\fP
+development effort; we expect to gain even more when tracking future SunOS
+releases.
+.NH
+Future Enhancements and Current Bugs
+.PP
+Since \fBcvs\fP was designed to be incomplete, for reasons of design
+simplicity, there are naturally a good
+number of enhancements that can be made to make it more useful.
+As well, some nuisances exist in the current implementation.
+.RS
+.IP \(bu 3
+\fBcvs\fP does not currently \*Qremember\*U who has a checked out a copy of a
+module.
+As a result, it is impossible to know who might be working on the same
+module that you are.
+A simple-minded database that is updated nightly would likely suffice.
+.IP \(bu 3
+Signal processing, keyboard interrupt handling in particular, is currently
+somewhat weak.
+This is due to the heavy use of the \fBsystem\fP\|(3) library
+function to execute
+.SM
+RCS
+.LG
+programs like \fBco\fP and \fBci\fP.
+It sometimes takes multiple interrupts to make \fBcvs\fP quit.
+This can be fixed by using a home-grown \fBsystem\fP\|() replacement.
+.IP \(bu 3
+Security of the source repository is currently not dealt with directly.
+The usual UNIX approach of user-group-other security permissions through
+the file system is utilized, but nothing else.
+\fBcvs\fP could likely be a set-group-id executable that checks a
+protected database to verify user access permissions for particular objects
+before allowing any operations to affect those objects.
+.IP \(bu 3
+With every checked-out directory, \fBcvs\fP maintains some administrative
+files that record the current revision numbers of the checked-out files as
+well as the location of the respective source repository.
+\fBcvs\fP does not recover nicely at all if these administrative files are
+removed.
+.IP \(bu 3
+The source code for \fBcvs\fP has been tested extensively on Sun-3 and
+Sun-4 systems, all running SunOS 4.0 or later versions of the operating
+system.
+Since the code has not yet been compiled under other platforms, the overall
+portability of the code is still questionable.
+.IP \(bu 3
+As witnessed in the previous section, the \fBcvs\fP method for tracking
+third party vendor source distributions can work quite nicely.
+However, if the vendor changes the directory structure or the file names
+within the source distribution, \fBcvs\fP has no way of matching the old
+release with the new one.
+It is currently unclear as to how to solve this, though it is certain to
+happen in practice.
+.RE
+.NH
+Availability
+.PP
+The \fBcvs\fP program sources can be found in a recent posting to the
+\fBcomp.sources.unix\fP newsgroup.
+It is also currently available via anonymous ftp from \*Qprisma.com\*U.
+Copying rights for \fBcvs\fP will be covered by the GNU General Public
+License.
+.NH
+Summary
+.PP
+Prisma has used \fBcvs\fP since December, 1988.
+It has evolved to meet our specific needs of revision and release control.
+We will make our code freely available so that others can
+benefit from our work, and can enhance \fBcvs\fP to meet broader needs yet.
+.PP
+Many of the other software release and revision control systems, like the
+one described in [Glew], appear to use a collection of tools that are
+geared toward specific environments \(em one set of tools for the kernel,
+one set for \*Qgeneric\*U software, one set for utilities, and one set for
+kernel and utilities.
+Each of these tool sets apparently handle some specific aspect of the
+problem uniquely.
+\fBcvs\fP took a somewhat different approach.
+File sharing through symbolic or hard links is not addressed; instead, the
+disk space is simply burned since it is \*Qcheap.\*U
+Support for producing objects for multiple architectures is not addressed;
+instead, a parallel checked-out source tree must be used for each
+architecture, again wasting disk space to simplify complexity and ease of
+use \(em punting on this issue allowed \fIMakefile\fPs to remain
+unchanged, unlike the approach taken in [Mahler], thereby maintaining closer
+compatibility with the third-party vendor sources.
+\fBcvs\fP is essentially a source-file server, making no assumptions or
+special handling of the sources that it controls.
+To \fBcvs\fP:
+.QP
+A source is a source, of course, of course, unless of course the source is
+Mr. Ed.\**
+.FS
+\fBcvs\fP, of course, does not really discriminate against Mr. Ed.\**
+.FE
+.FS
+Yet.
+.FE
+.LP
+Sources are maintained, saved, and retrievable at any time based on
+symbolic or numeric revision or date in the past.
+It is entirely up to \fBcvs\fP wrapper programs to provide for release
+environments and such.
+.PP
+The major advantage of \fBcvs\fP over the
+many other similar systems that have already been designed is the
+simplicity of \fBcvs\fP.
+\fBcvs\fP contains only three programs that do all the work of release
+and revision control, and two manually-maintained administrative
+files for each source repository.
+Of course, the deciding factor of any tool is whether people use it, and if
+they even \fIlike\fP to use it.
+At Prisma, \fBcvs\fP prevented members of the kernel
+group from killing each other.
+.NH
+Acknowledgements
+.PP
+Many thanks to Dick Grune at Vrije Universiteit in Amsterdam for his work
+on the original version of \fBcvs\fP and for making it available to the
+world.
+Thanks to Jeff Polk of Prisma for helping with the design of the module
+database, vendor branch support, and for writing the \fBcheckin\fP shell
+script.
+Thanks also to the entire software group at Prisma for taking the
+time to review the paper and correct my grammar.
+.NH
+References
+.IP [Bell] 12
+Bell Telephone Laboratories.
+\*QSource Code Control System User's Guide.\*U
+\fIUNIX System III Programmer's Manual\fP, October 1981.
+.IP [Courington] 12
+Courington, W.
+\fIThe Network Software Environment\fP,
+Sun Technical Report FE197-0, Sun Microsystems Inc, February 1989.
+.IP [Essick] 12
+Essick, Raymond B. and Robert Bruce Kolstad.
+\fINotesfile Reference Manual\fP,
+Department of Computer Science Technical Report #1081,
+University of Illinois at Urbana-Champaign, Urbana, Illinois,
+1982, p. 26.
+.IP [Glew] 12
+Glew, Andy.
+\*QBoxes, Links, and Parallel Trees:
+Elements of a Configuration Management System.\*U
+\fIWorkshop Proceedings of the Software Management Conference\fP, USENIX,
+New Orleans, April 1989.
+.IP [Grune] 12
+Grune, Dick.
+Distributed the original shell script version of \fBcvs\fP in the
+\fBcomp.sources.unix\fP volume 6 release in 1986.
+.IP [Honda] 12
+Honda, Masahiro and Terrence Miller.
+\*QSoftware Management Using a CASE Environment.\*U
+\fIWorkshop Proceedings of the Software Management Conference\fP, USENIX,
+New Orleans, April 1989.
+.IP [Mahler] 12
+Mahler, Alex and Andreas Lampen.
+\*QAn Integrated Toolset for Engineering Software Configurations.\*U
+\fIProceedings of the ACM SIGSOFT/SIGPLAN Software Engineering Symposium on
+Practical Software Development Environments\fP, ACM, Boston, November 1988.
+Described is the \fBshape\fP toolkit posted to the
+\fBcomp.sources.unix\fP newsgroup in the volume 19 release.
+.IP [Tichy] 12
+Tichy, Walter F.
+\*QDesign, Implementation, and Evaluation of a Revision Control System.\*U
+\fIProceedings of the 6th International Conference on Software
+Engineering\fP, IEEE, Tokyo, September 1982.
+.IP [Wall] 12
+Wall, Larry.
+The \fBpatch\fP program is an indispensable tool for applying a diff file
+to an original.
+Can be found on uunet.uu.net in ~ftp/pub/patch.tar.
diff --git a/gnu/usr.bin/cvs/doc/cvs.texinfo b/gnu/usr.bin/cvs/doc/cvs.texinfo
new file mode 100644
index 0000000..c38166f
--- /dev/null
+++ b/gnu/usr.bin/cvs/doc/cvs.texinfo
@@ -0,0 +1,6644 @@
+\input texinfo @c -*-texinfo-*-
+@comment cvs.texinfo,v 1.3 1994/09/15 23:39:26 zoo Exp
+@comment Documentation for CVS.
+@comment Copyright (C) 1992, 1993 Signum Support AB
+@comment Copyright (C) 1993 Free Software Foundation, Inc.
+
+@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 1, 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.
+
+@comment You should have received a copy of the GNU General Public License
+@comment along with CVS; see the file COPYING. If not, write to
+@comment the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+@afourpaper
+@setfilename cvs.info
+@settitle CVS---Concurrent Versions System
+@setchapternewpage odd
+
+@c -- TODO list:
+@c -- Fix all lines that match "^@c -- "
+@c -- Document how CVS finds the binaries it executes.
+@c Things to include in the index:
+@c Finding RCS binaries
+@c Path to RCS binaries
+@c RCS, how CVS finds them
+@c s/RCS/diff/
+@c -- More on binary files
+
+@ifinfo
+Copyright @copyright{} 1992, 1993 Signum Support AB
+Copyright @copyright{} 1993, 1994 Free Software Foundation, Inc.
+
+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.
+
+@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 copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+section entitled ``GNU General Public License'' is included exactly as
+in the original, and provided 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 the section entitled ``GNU General Public License'' and
+this permission notice may be included in translations approved by the
+Free Software Foundation instead of in the original English.
+@end ifinfo
+
+@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 release 0.9, for @sc{cvs} 1.3+
+@comment -release-
+@sp 3
+@center Per Cederqvist
+@sp 3
+@center last updated 2 Nov 1993
+@comment -date-
+
+@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
+Copyright @copyright{} 1992, 1993 Signum Support AB
+
+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
+section entitled ``GNU General Public License'' is included exactly as
+in the original, and provided 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 the section entitled ``GNU General Public License'' and
+this permission notice may be included in translations approved by the
+Free Software Foundation instead of in the original English.
+@end titlepage
+
+@comment ================================================================
+@comment The real text starts here
+@comment ================================================================
+
+@ifinfo
+@c ---------------------------------------------------------------------
+@node Top
+@top
+
+This info manual describes @sc{cvs} and is updated to
+release 1.4 or something similar.
+@end ifinfo
+
+@menu
+* Preface:: About this manual
+* What is CVS?:: What is CVS?
+* Basic concepts:: Basic concepts of revision management
+* A sample session:: A tour of basic CVS usage
+* Repository:: Where all your sources are stored
+* Starting a new project:: Starting a project with CVS
+* Multiple developers:: How CVS helps a group of developers
+* Branches:: Parallel development explained
+* Merging:: How to move changes between branches
+* Recursive behavior:: CVS descends directories
+* Adding files:: Adding files to a module
+* Removing files:: Removing files from a module
+* Tracking sources:: Tracking third-party sources
+* Moving files:: Moving and renaming files
+* Moving directories:: Moving and renaming directories
+* Keyword substitution:: CVS can include the revision inside the file
+* Revision management:: Policy questions for revision management
+* Invoking CVS:: Reference manual for CVS commands
+* Administrative files:: Reference manual for the Administrative files
+* Environment variables:: All environment variables which affect CVS
+* Troubleshooting:: Some tips when nothing works
+* Copying:: GNU GENERAL PUBLIC LICENSE
+* Index:: Index
+@end menu
+
+@c ---------------------------------------------------------------------
+@node Preface
+@unnumbered About this manual
+@cindex Preface
+@cindex About this manual
+
+Up to this point, one of the weakest parts of @sc{cvs}
+has been the documentation. @sc{cvs} is a complex
+program. Previous versions of the manual were written
+in the manual page format, which is not really well
+suited for such a complex program.
+
+When writing this manual, I had several goals in mind:
+
+@itemize @bullet
+@item
+No knowledge of @sc{rcs} should be necessary.
+
+@item
+No previous knowledge of revision control software
+should be necessary. All terms, such as @dfn{revision
+numbers}, @dfn{revision trees} and @dfn{merging} are
+explained as they are introduced.
+
+@item
+The manual should concentrate on the things @sc{cvs} users
+want to do, instead of what the @sc{cvs} commands can do.
+The first part of this manual leads you through things
+you might want to do while doing development, and
+introduces the relevant @sc{cvs} commands as they are
+needed.
+
+@item
+Information should be easy to find. In the reference
+manual in the appendices almost all information about
+every @sc{cvs} command is gathered together. There is also
+an extensive index, and a lot of cross references.
+@end itemize
+
+@cindex Signum Support
+@cindex Support, getting CVS support
+This manual was contributed by Signum Support AB in
+Sweden. Signum is yet another in the growing list of
+companies that support free software. You are free to
+copy both this manual and the @sc{cvs} program.
+@xref{Copying}, for the details. Signum Support offers
+@c -- Check this reference! It has been bogus in the past.
+support contracts and binary distribution for many
+programs, such as @sc{cvs}, @sc{gnu} Emacs, the
+@sc{gnu} C compiler and others. You can also buy
+hardcopies of this manual from us. Write to us for
+more information.
+
+@example
+Signum Support AB
+Box 2044
+S-580 02 Linkoping
+Sweden
+
+Email: info@@signum.se
+Phone: +46 (0)13 - 21 46 00
+Fax: +46 (0)13 - 21 47 00
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@menu
+* Checklist::
+* Credits::
+* BUGS::
+@end menu
+
+@node Checklist
+@unnumberedsec Checklist for the impatient reader
+
+@sc{cvs} is a complex system. You will need to read
+the manual to be able to use all of its capabilities.
+There are dangers that can easily be avoided if you
+know about them, and this manual tries to warn you
+about them. This checklist is intended to help you
+avoid the dangers without reading the entire manual.
+If you intend to read the entire manual you can skip
+this table.
+
+@table @asis
+@item Binary files
+@sc{cvs} can handle binary files, but
+you must have @sc{rcs} release 5.5 or later and
+a release of @sc{gnu} diff that supports the @samp{-a}
+flag (release 1.15 and later are OK). You must also
+configure both @sc{rcs} and @sc{cvs} to handle binary
+files when you install them.
+
+Keword substitution can be a source of trouble with
+binary files. @xref{Keyword substitution}, for
+solutions.
+
+@item The @code{admin} command
+Uncareful use of the @code{admin} command can cause
+@sc{cvs} to cease working. @xref{admin}, before trying
+to use it.
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Credits
+@unnumberedsec Credits
+
+@cindex Contributors (manual)
+@cindex Credits (manual)
+Roland Pesch, Cygnus Support <@t{pesch@@cygnus.com}>
+wrote the manual pages which were distributed with
+@sc{cvs} 1.3. Appendix A and B contain much text that
+was extracted from them. 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} (@pxref{What is CVS?}) by David
+G. Grubbs has been used as a check-list to make sure
+that this manual is as complete as possible. (This
+manual does however not include all of the material in
+the @sc{faq}). The @sc{faq} contains a lot of useful
+information.
+
+In addition, the following persons have helped by
+telling me about mistakes I've made:
+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}>.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node BUGS
+@unnumberedsec BUGS
+
+@cindex Bugs, known in this manual
+@cindex Known bugs in this manual
+This manual is still very new. Here is a
+list of known deficiencies in it:
+
+@itemize @bullet
+@item
+In the examples, the output from @sc{cvs} is sometimes
+displayed, sometimes not.
+
+@item
+The input that you are supposed to type in the examples
+should have a different font than the output from the
+computer.
+
+@item
+This manual should be clearer about what file
+permissions you should set up in the repository, and
+about setuid/setgid.
+
+@item
+Some of the chapters are not yet complete. They are
+noted by comments in the @file{cvs.texinfo} file.
+
+@item
+@cindex Reporting bugs (manual)
+@cindex Bugs, reporting (manual)
+@cindex Errors, reporting (manual)
+This list is not complete. If you notice any error,
+omission, or something that is unclear, please send
+mail to @t{ceder@@signum.se}.
+@end itemize
+
+I hope that you will find this manual useful, despite
+the above-mentioned shortcomings.
+
+@flushright
+
+Linkoping, October 1993
+Per Cederqvist
+@end flushright
+
+@c ---------------------------------------------------------------------
+@node What is CVS?
+@chapter 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
+the same file is never modified by two people 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 @code{comp.sources.unix} in the volume 6
+release of December, 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} via anonymous ftp from a number of
+sites, for instance @t{prep.ai.mit.edu} in
+@file{pub/gnu}.
+
+@cindex Mailing list
+@cindex List, mailing list
+There is a mailing list for @sc{cvs} where bug reports
+can be sent, questions can be asked, an FAQ is posted,
+and discussion about future enhancements to @sc{cvs}
+take place. To submit a message to the list, write to
+<@t{info-cvs@@prep.ai.mit.edu}>. To subscribe or
+unsubscribe, write to
+<@t{info-cvs-request@@prep.ai.mit.edu}>. Please be
+specific about your email address.
+
+Work is in progress on creating a newsgroup for
+@sc{cvs}-related topics. It will appear somewhere
+under the @samp{gnu.} hierarchy. Gateways to and from
+the mailing list will be set up.
+@c -- Newsgroup? gnu.cvs.info?
+
+@cindex FTP site
+@cindex Patches to CVS
+@cindex CVS FTP site
+@cindex Fixes to CVS
+@cindex FAQ
+@cindex CVS FAQ
+The @sc{ftp} site @t{think.com} has some @sc{cvs}
+material in the @file{/pub/cvs} subdirectory.
+Currently (late summer 1993) it contains an excellent
+@sc{faq} (Frequently Asked Questions, with answers),
+and an improved (but unofficial) version of @sc{cvs}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@unnumberedsec CVS is not@dots{}
+
+@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. That's simply bad planning.
+
+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. You must use your
+brain and a collection of other tools to provide a
+build scheme to match your plans.
+
+Of course, you should place the tools created to
+support such a build system (scripts, @file{Makefile}s,
+etc) under @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} is not a configuration management system.
+
+@sc{cvs} is a source control system. The phrase
+``configuration management'' is a marketing term, not
+an industry-recognized set of functions.
+
+A true ``configuration management system'' would contain
+elements of the following:
+
+@itemize @bullet
+@item Source control.
+@item Dependency tracking.
+@item Build systems (i.e. What to build and how to find
+things during a build. What is shared? What is local?)
+@item Bug tracking.
+@item Automated Testing procedures.
+@item Release Engineering documentation and procedures.
+@item Tape Construction.
+@item Customer Installation.
+@item A way for users to run different versions of the same
+software on the same host at the same time.
+@end itemize
+
+@sc{cvs} provides only the first.
+@end table
+
+This section is taken from release 2.3 of the @sc{cvs}
+@sc{faq}.
+
+@c ---------------------------------------------------------------------
+@node Basic concepts
+@chapter Basic concepts
+@cindex Modules (intro)
+@cindex Repository (intro)
+
+@sc{cvs} stores all files in a centralized @dfn{repository}: a
+directory (such as @file{/usr/local/cvsroot}) which is populated with a
+hierarchy of files and directories.
+
+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, and then work on that copy.
+
+The files in the repository are organized in
+@dfn{modules}. Each module is made up of one or more
+files, and can include files from several directories.
+A typical usage is to define one module per project.
+
+@menu
+* Revision numbers:: The meaning of a revision number
+* Versions revisions releases:: Terminology used in this manual
+@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 Main trunk (intro)
+@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
+
+@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
+@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.2.2.4 !
+ / +---------+ +---------+ +---------+ +---------+
+ /
+ /
++-----+ +-----+ +-----+ +-----+ +-----+
+! 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 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.
+
+@c ---------------------------------------------------------------------
+@node A sample session
+@chapter A sample session
+@cindex 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)
+
+This section describes a typical work-session using
+@sc{cvs}. It assumes that a repository is set up
+(@pxref{Repository}).
+
+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
+@section 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 tc
+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
+@section Committing your changes
+@cindex Committing changes
+@cindex Log message entry
+@cindex CVSEDITOR, environment variable
+@cindex EDITOR, environment variable
+
+When you have checked that the compiler is still compilable you decide
+to make a new version of @file{backend.c}.
+
+@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.
+
+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 the editor defaults to
+@code{vi}. If you want to avoid the overhead of
+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
+@section 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) module `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
+@section 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.
+
+@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) module `tc': y
+@end example
+
+@c ---------------------------------------------------------------------
+@node Repository
+@chapter The Repository
+@cindex Repository, example
+@cindex Layout of repository
+@cindex Typical repository
+@cindex CVSROOT, environment variable
+@cindex .profile
+@cindex .cshrc
+@cindex .tcshrc
+@cindex .bashrc
+@cindex /usr/local/cvsroot
+@cindex cvsroot
+
+Figure 3 below shows a typical setup of a repository.
+Only directories are shown below.
+
+@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
+
+The @code{$CVSROOT} environment variable should always
+be set to an absolute path to the root of the
+repository, @file{/usr/local/cvsroot} in this example.
+With this setup all @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
+
+There is nothing magical about the name
+@file{/usr/local/cvsroot}. You can choose to place the
+repository anywhere you like, but @code{$CVSROOT} must
+always point to it.
+
+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
+* User modules:: The structure of the repository
+* Intro administrative files:: Defining modules
+* Multiple repositories:: Multiple repositories
+* Creating a repository:: Creating a repository
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node User modules
+@section User modules
+@cindex User modules
+@cindex Repository, user parts
+
+@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
+@cindex RCS, CVS uses RCS
+The figure above shows the contents of the @samp{tc}
+module inside the repository. As you can see all file
+names end in @samp{,v}. The files are @dfn{history
+files}. They 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. @sc{cvs} uses the
+facilities of @sc{rcs}, a simpler version control
+system, to maintain these files. For a full
+description of the file format, see the @code{man} page
+@cite{rcsfile(5)}.
+@c -- Use this format for all references to man pages,
+@c -- or use something better!
+
+@menu
+* File permissions:: File permissions
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node File permissions
+@subsection File permissions
+@c -- Move this to @node Setting up
+@cindex Security
+@cindex File permissions
+@cindex Group
+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.
+
+This means that you can only control access to files on
+a per-directory basis.
+
+@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.
+
+@cindex setuid
+@cindex setgid
+Since @sc{cvs} was not written to be run setuid, it is
+unsafe to try to run it setuid. You cannot use the
+setuid features of @sc{rcs} together with @sc{cvs}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Intro administrative files
+@section The administrative files
+@cindex Administrative files (intro)
+@cindex Modules file
+@cindex CVSROOT, module name
+@cindex Defining modules (intro)
+
+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.
+
+@example
+CVSROOT -i mkmodules CVSROOT
+modules -i mkmodules 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 for lines in the example
+above are examples of such lines.
+
+@cindex mkmodules
+Each module definition can contain options. The @samp{-i mkmodules} is
+an example of an option. It arranges for @sc{cvs} to run the
+@code{mkmodules} program whenever any file in the module CVSROOT is
+committed. That program is responsible for checking out read-only
+copies from the @sc{rcs} @dfn{history files} of all the administrative files.
+These read-only copies are used internally by @sc{cvs}. You
+should never edit them directly.
+
+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.
+
+@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 set @code{$CVSROOT} to the
+repository you want to use at the moment.
+
+There are disadvantages to having more than one
+repository. In @sc{cvs} 1.3 you @emph{must} make sure
+that @code{$CVSROOT} always points to the correct
+repository. If the same filename is used in two
+repositories, and you mix up the setting of
+@code{$CVSROOT}, you might lose data. @sc{cvs} 1.4
+solves this problem by saving the repository
+information in the local @file{CVS} administration
+files. If you try to use the wrong repository,
+@sc{cvs} will warn you of the attempt and then exit.
+
+Notwithstanding, it can be confusing to have two or
+more repositories.
+
+All examples in this manual assume that you have a
+single repository.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Creating a repository
+@section Creating a repository
+@c -- Well, how do you do?
+
+See the instructions in the @file{INSTALL} file in the
+@sc{cvs} distribution.
+
+@c ---------------------------------------------------------------------
+@node Starting a new project
+@chapter Starting a project with CVS
+@cindex Starting a project with CVS
+@cindex Creating a project
+
+@comment --moduledb--
+Since @sc{cvs} 1.x is bad at renaming files and moving
+them between directories, the first thing you do when
+you start a new project should be to think through your
+file organization. It is not impossible---just
+awkward---to rename or move files in @sc{cvs} 1.x.
+@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 scratch:: Creating a module from scratch.
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node From files
+@subsection Creating a module 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{dir}}, and you want them to appear in the
+repository as @file{$CVSROOT/yoyodyne/@var{dir}}, you can do this:
+
+@example
+$ cd @var{dir}
+$ cvs import -m "Imported sources" yoyodyne/@var{dir} 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.
+
+@example
+$ cd ..
+$ mv @var{dir} @var{dir}.orig
+$ cvs checkout yoyodyne/@var{dir} # @r{Explanation below}
+$ ls -R yoyodyne
+$ rm -r @var{dir}.orig
+@end example
+
+@noindent
+Erasing the original sources is a good idea, to make sure that you do
+not accidentally edit them in @var{dir}, 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 @samp{$CVSROOT}
+are reasonable, and that they belong to the proper
+groups. @xref{File permissions}.
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node From scratch
+@subsection Creating a module from scratch
+
+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
+
+Then, use @code{add} to add files (and new directories)
+as they appear.
+
+Check that the permissions @sc{cvs} sets on the
+directories inside @samp{$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. Some
+@sc{cvs} commands work without this step, but others (most notably
+@code{release}) require that all modules are properly defined in the
+@file{modules} file.
+
+In simple cases these steps are sufficient to define a module.
+
+@enumerate
+@item
+Get a working copy of the modules file.
+
+@example
+$ cvs checkout modules
+$ cd modules
+@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 modules
+@end example
+@end enumerate
+
+@c ---------------------------------------------------------------------
+@node Multiple developers
+@chapter Multiple developers
+@cindex Multiple developers
+@cindex Team of developers
+@cindex File locking
+@cindex Locking files
+@cindex Working copy
+
+When more than one person works on a software project
+things often get complicated. Often, two people try to
+edit the same file simultaneously. Some other version
+control systems (including @sc{rcs} and @sc{sccs})
+try to solve that particular problem by introducing
+@dfn{file locking}, so that only one person can edit
+each file at a time. Unfortunately, file locking 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.
+
+@sc{cvs} does not use file locking. Instead, it allows many
+people to 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, and explained in this chapter.
+
+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. It is often useful to inform the group of
+commits you have done. @sc{cvs} has several ways of
+automating that process. @xref{Informing others}.
+@xref{Revision management}, for more tips on how to use
+@sc{cvs}.
+
+@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
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node File status
+@section File status
+@cindex File status
+@cindex Status of a file
+@cindex Four states of a file
+
+After you have checked out a file out from @sc{cvs}, it is in
+one of these four states:
+
+@table @asis
+@cindex Up-to-date
+@item Up-to-date
+The file is identical with the latest revision in the
+repository.
+@c -- The above is not always true if branching is used.
+
+@item Locally modified
+@cindex Locally modified
+You have edited the file, and not yet committed your changes.
+
+@item Needing update
+@cindex Needing update
+Someone else has committed a newer revision to the repository.
+
+@item Needing merge
+@cindex Needing merge
+Someone else have committed a newer revision to the repository, and you
+have also made modifications to the file.
+@c -- What about "added" "removed" and so on?
+@end table
+
+You can use the @code{status} command to find out the status of a given
+file. @xref{status}.
+
+@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{update}
+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 copy of the
+module.
+
+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");
+<<<<<<< driver.c
+ exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+=======
+ exit(!!nerr);
+>>>>>>> 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
+
+@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.
+
+@c ---------------------------------------------------------------------
+@node Branches
+@chapter Branches
+@cindex Branches
+@cindex Main trunk and branches
+@cindex Revision tree, making branches
+
+So far, all revisions shown in this manual have been on
+the @dfn{main trunk}
+of the revision tree, i.e., all revision numbers
+have been of the form @var{x}.@var{y}. One useful
+feature, especially when maintaining several releases
+of a software product at once, is the ability to make
+branches on the revision tree. @dfn{Tags}, symbolic
+names for revisions, will also be
+introduced in this chapter.
+
+@menu
+* Tags:: Tags--Symbolic revisions
+* Branches motivation:: What branches are good for
+* Creating a branch:: Creating a branch
+* Sticky tags:: Sticky tags
+@end menu
+
+@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, command, introduction
+@cindex Tag, symbolic name
+@cindex Symbolic name (tag)
+@cindex Name, symbolic (tag)
+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. (The output of @code{status}
+unfortunately uses the word ``version'' instead of ``revision''.)
+@c -- Is this fixed in CVS 1.3.1?
+
+@cindex Adding a tag
+@cindex tag, example
+The following example shows how you can add a tag to a
+file. The commands must be issued inside your working
+copy of the module. That is, you should issue the
+command in the directory where @file{backend.c}
+resides.
+
+@example
+$ cvs tag release-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 /usr/local/cvsroot/yoyodyne/tc/backend.c,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ release-0-4 (revision: 1.4)
+
+@end example
+
+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 release-1-0 .
+cvs tag: Tagging .
+T Makefile
+T backend.c
+T driver.c
+T frontend.c
+T parser.c
+@end example
+
+(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 Tag, 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 release-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 at any given date.
+@xref{checkout options}.
+
+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
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Branches motivation
+@section What branches are good for
+@cindex Branches motivation
+@cindex What branches are good for
+@cindex Motivation for branches
+
+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
+bugfix 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 select 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 rtag, creating a branch using
+
+The @code{rtag} command can be used to create a branch.
+The @code{rtag} command is much like @code{tag}, but it
+does not require that you have a working copy of the
+module. @xref{rtag}. (You can also use the @code{tag}
+command; @pxref{tag}).
+
+@example
+$ cvs rtag -b -r release-1-0 release-1-0-patches tc
+@end example
+
+The @samp{-b} flag makes @code{rtag} create a branch
+(rather than just a symbolic revision name). @samp{-r
+release-1-0} says that this branch should be rooted at the node (in
+the revision tree) that corresponds to the tag
+@samp{release-1-0}. Note that the numeric revision number that matches
+@samp{release-1-0} will probably be different from file to file. The
+name of the new branch is @samp{release-1-0-patches}, and the
+module affected is @samp{tc}.
+
+To fix the problem in release 1.0, you need a working
+copy of the branch you just created.
+
+@example
+$ cvs checkout -r release-1-0-patches tc
+$ 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 /usr/local/cvsroot/yoyodyne/tc/driver.c,v
+ Sticky Tag: release-1-0-patches (branch: 1.7.2)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ release-1-0-patches (branch: 1.7.2)
+ release-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 /usr/local/cvsroot/yoyodyne/tc/backend.c,v
+ Sticky Tag: release-1-0-patches (branch: 1.4.2)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ release-1-0-patches (branch: 1.4.2)
+ release-1-0 (revision: 1.4)
+ release-0-4 (revision: 1.4)
+
+@end example
+
+@cindex Branch numbers
+As the output from the @code{status} command shows the branch
+number is created by adding a digit at the tail of the revision number
+it is based on. (If @samp{release-1-0} corresponds to revision 1.4, the
+branch's revision number will be 1.4.2. For obscure reasons @sc{cvs} always
+gives branches even numbers, starting at 2.
+@xref{Revision numbers}).
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Sticky tags
+@section Sticky tags
+@cindex Sticky tags
+@cindex Tags, sticky
+@cindex Branches, sticky
+
+The @samp{-r release-1-0-patches} flag that was given to @code{checkout}
+is @dfn{sticky}, that is, it will apply to subsequent commands
+in this directory. If you commit any modifications, they are
+committed on the branch. You can later merge the modifications into
+the main trunk. @xref{Merging}.
+
+@example
+$ vi driver.c # @r{Fix the bugs}
+$ cvs commit -m "Fixed initialization bug" driver.c
+Checking in driver.c;
+/usr/local/cvsroot/yoyodyne/tc/driver.c,v <-- driver.c
+new revision: 1.7.2.1; previous revision: 1.7
+done
+$ cvs status -v 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 /usr/local/cvsroot/yoyodyne/tc/driver.c,v
+ Sticky Tag: release-1-0-patches (branch: 1.7.2)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ release-1-0-patches (branch: 1.7.2)
+ release-1-0 (revision: 1.7)
+
+@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}. @xref{update}.
+
+Sticky tags are not just for branches. If you check
+out a certain revision (such as 1.4) it will also
+become sticky. Subsequent @samp{cvs update} will not
+retrieve the latest revision until you reset the tag
+with @samp{cvs update -A}.
+
+See the descriptions in Appendix A for more information
+about sticky tags. Dates and some other options can
+also be sticky. Again, see Appendix A for details.
+@c -- xref to relevant part of App A.
+@c -- Re-evaluate this node.
+
+@c ---------------------------------------------------------------------
+@node Merging
+@chapter Merging
+@cindex Merging
+@cindex Copying changes
+@cindex Branches, copying changes between
+@cindex Changes, copying between branches
+@cindex Modifications, copying between branches
+
+You can include the changes made between any two
+revisions into your working copy, by @dfn{merging}.
+You can then commit that revision, and thus effectively
+copy the changes onto another branch.
+
+@menu
+* Merging a branch:: Merging an entire branch
+* Merging two revisions:: Merging differences between two revisions
+@end menu
+
+@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{branch}} flag to the @code{update} command. With one
+@samp{-j @var{branch}} option it merges the changes made between the
+point where the branch forked and newest revision on that branch (into
+your working copy).
+
+@cindex Join
+The @samp{-j} stands for ``join''. In previous
+versions of @sc{cvs} there was a special command,
+@samp{cvs join}, that was used to merge changes between
+branches.
+
+@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 !----! 1.5 ! <- The main trunk
++-----+ +-----+ +-----+ +-----+ +-----+
+ !
+ !
+ ! +---------+ +---------+ +---------+
+Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
+ +---------+ +---------+ +---------+
+@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.5}
+
+$ 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.3, into your working copy}
+ # @r{of the file.}
+
+$ cvs commit -m "Included R1fix" # @r{Create revision 1.6.}
+@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}.
+
+The @code{checkout} command also supports the @samp{-j @var{branch}} flag. The
+same effect as above could be achieved with this:
+
+@example
+$ cvs checkout -j R1fix mod
+$ cvs commit -m "Included R1fix"
+@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 @emph{remove} all changes made between revision
+1.3 and 1.5. Note the order of the revisions!
+
+If you try to use this option with the @code{checkout}
+command, remember that the numeric revisions will
+probably be very different between the various files
+that make up a module. You almost always use symbolic
+tags rather than revision numbers with the
+@code{checkout} command.
+
+@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 @samp{cvs
+update testing/testpgm.t testing/test2.t}
+
+@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} module
+@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.
+
+@example
+$ cvs update -l # @r{Don't update files in subdirectories}
+@end example
+
+@c ---------------------------------------------------------------------
+@node Adding files
+@chapter Adding files to a module
+@cindex Adding files
+
+To add a new file to a module, follow these steps.
+
+@itemize @bullet
+@item
+You must have a working copy of the module.
+@xref{Getting the source}.
+
+@item
+Create the new file inside your working copy of the module.
+
+@item
+Use @samp{cvs add @var{filename}} to tell @sc{cvs} that you
+want to version control the file.
+
+@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.
+
+@item
+If the file contains binary data it might be necessary
+to change the default keyword substitution.
+@xref{Keyword substitution}. @xref{admin examples}.
+@end itemize
+
+You can also use the @code{add} command to add a new
+directory inside a module.
+
+Unlike most other commands, the @code{add} command is
+not recursive. You cannot even type @samp{cvs add
+foo/bar}! Instead, you have to
+
+@example
+$ cd foo
+$ cvs add bar
+@end example
+
+@xref{add}, for a more complete description of the @code{add}
+command.
+
+@c ---------------------------------------------------------------------
+@node Removing files
+@chapter Removing files from a module
+@cindex Removing files
+@cindex Deleting files
+
+Modules change. New files are added, and old files
+disappear. Still, you want to be able to retrieve an
+exact copy of old releases of the module.
+
+Here is what you can do to remove a file from a module,
+but remain able to retrieve old revisions:
+
+@itemize @bullet
+@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 module.
+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
+
+What happens when you commit the removal of the file is
+that inside the source repository, it is moved into a
+subdirectory called @file{Attic}. @sc{cvs} normally doesn't
+look in that directory when you run e.g.
+@code{checkout}. However, if you are retrieving a
+certain revision via e.g. @samp{cvs checkout -r
+@var{some-tag}}, it will look at the files inside the
+@file{Attic} and include any files that contain the
+specified tag.
+
+This method is simple and works quite well, but it has
+some known deficiencies:
+
+@itemize @bullet
+@item
+If you remove the file @file{foo.c}, you cannot later
+create a new file called @file{foo.c} unless you
+manually remove the file @file{Attic/foo.c,v} inside
+the repository. On the other hand, if you remove
+@file{Attic/foo.c,v} you will of course not be able to
+retrieve any revision of the old file @file{foo.c}.
+
+@item
+If the file @file{bar.c} is present in release 1.0 of a
+product, and was accidentally removed in release 1.1,
+you cannot easily resurrect it to release 1.2. You
+have to move the file out of the @file{Attic} manually
+inside the repository. (Do a @samp{mv Attic/@var{file}
+@var{file}}).
+@end itemize
+
+There is a design for a @dfn{rename database} that will
+solve these problems and many others, but it is not yet
+implemented.
+
+@c ---------------------------------------------------------------------
+@node Tracking sources
+@chapter Tracking third-party sources
+@cindex Third-party sources
+@cindex Tracking sources
+
+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. After a successful @code{import}
+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 a module for the first time
+* Update imports:: Updating a module with the import command
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node First import
+@section Importing a module for the first time
+@cindex Importing modules
+
+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---@xref{import options}). The
+@dfn{release tags} are symbolic names for a particular
+release, such as @samp{FSF_0_04}.
+
+@cindex Wdiff (import example)
+Suppose you use @code{wdiff} (a variant of @code{diff}
+that ignores changes that only involve whitespace), 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
+$ tar xfz wdiff-0.04.tar.gz
+$ cd wdiff-0.04
+$ cvs import -m "Import of FSF v. 0.04" fsf/wdiff FSF WDIFF_0_04
+@end example
+
+The vendor tag is named @samp{FSF} in the above
+example, and the only release tag assigned is
+@samp{WDIFF_0_04}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Update imports
+@section Updating a module 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 WDIFF_0_05
+@end example
+
+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.
+
+@example
+$ cvs checkout -jFSF:yesterday -jFSF 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}
+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.
+
+@sc{cvs} assumes that you do not import more than one
+release of a product per day. If you do, you can always
+use something like this instead:
+
+@example
+$ cvs checkout -jWDIFF_0_04 -jWDIFF_0_05 wdiff
+@end example
+
+@noindent
+In this case, the two above commands are equivalent.
+
+@c ---------------------------------------------------------------------
+@node Moving files
+@chapter Moving and renaming files
+@cindex Moving files
+@cindex Renaming files
+@cindex Files, moving
+
+One of the biggest design flaws with the current release of @sc{cvs} is that
+it is very difficult to move a file to a different directory or
+rename it. There are workarounds, and they all have their strong and weak
+points. (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}. Both files reside in the same module,
+@var{module}, but not necessarily in the same directory.
+The relative path to the module inside the repository is assumed
+to be @var{module}.
+
+@menu
+* Outside:: Moving outside the repository
+* Inside:: Moving the history file
+* Rename by copying::
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Outside
+@section Moving outside the repository
+
+One way to move the 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. (Both @var{old} and @var{new} could contain
+relative paths inside the module).
+
+@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
+
+@noindent
+Advantages:
+
+@itemize @bullet
+@item
+Checking out old revisions works correctly.
+@end itemize
+
+@noindent
+Disadvantages:
+
+@itemize @bullet
+@item
+You cannot easily see the history of the file across the rename.
+@item
+Unless you use the @samp{-r rev} (@pxref{commit
+options}) flag when @var{new} is committed its revision
+numbers will start at 1.0 again.
+@end itemize
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Inside
+@section 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/module
+$ 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 of the module 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
+@section Copying the history file
+
+This is probably the best way to do the renaming. It is
+safe, but not without drawbacks.
+
+@example
+# @r{Copy the @sc{rcs} file inside the repository}
+$ cd $CVSROOT/module
+$ cp @var{old},v @var{new},v
+# @r{Remove the old file}
+$ cd ~/module
+$ 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 tag names}
+$ cvs tag -d @var{tag1}
+$ cvs tag -d @var{tag2}
+@dots{}
+@end example
+
+By removing the tags you will be able to check out old
+revisions of the module.
+
+@noindent
+Advantages:
+
+@itemize @bullet
+@item
+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.
+
+@item
+Unless you use the @samp{-r rev} (@pxref{commit
+options}) flag when @var{new} is committed its revision
+numbers will start at 1.0 again.
+@end itemize
+
+@c ---------------------------------------------------------------------
+@node Moving directories
+@chapter Moving and renaming directories
+@cindex Moving directories
+@cindex Renaming directories
+@cindex Directories, moving
+
+If you want to be able to retrieve old versions of the
+module, you must move each file in the directory
+with the @sc{cvs} commands. @xref{Outside}. The old, empty
+directory will remain inside the repository, but it
+will not appear in your workspace when you check out
+the module in the future.
+@c -- rephrase
+
+If you really want to rename or delete a directory, you
+can do it like this:
+
+@enumerate
+@item
+Inform everyone who has a copy of the module that the
+directory will be renamed. They should commit all
+their changes, and remove their working copies of the
+module, before you take the steps below.
+
+@item
+Rename the directory inside the repository.
+
+@example
+$ cd $CVSROOT/@var{module}
+$ 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 the module and continue
+working.
+
+@end enumerate
+
+If someone had a working copy of the module 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.
+
+@ignore
+@c ---------------------------------------------------------------------
+@c @node History browsing
+@chapter History browsing
+@cindex History browsing
+@cindex Traceability
+@cindex Isolation
+
+@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.
+
+@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
+
+Whenever you commit a file you specify a log message. ///
+@c --
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node history database
+@section The history database
+
+///
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node user-defined logging
+@section User-defined logging
+
+///
+
+@end ignore
+
+@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 your working
+copy of a module 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{Rcs} uses 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:: RCS Keywords
+* Using keywords:: Using keywords
+* Avoiding substitution:: Avoiding substitution
+* Substitution modes:: Substitution modes
+* Log keyword:: Problems with the $@asis{}Log$ keyword.
+@end menu
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Keyword list
+@section RCS Keywords
+@cindex RCS keywords
+
+This is a list of the keywords that @sc{rcs} currently
+(in release 5.6.0.1) supports:
+
+@table @code
+@cindex Author keyword
+@item $@asis{Author}$
+The login name of the user who checked in the revision.
+
+@cindex Date keyword
+@item $@asis{Date}$
+The date and time (UTC) the revision was checked in.
+
+@cindex Header keyword
+@item $@asis{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 $@asis{Id}$
+Same as @code{$@asis{Header}$}, except that the @sc{rcs}
+filename is without a path.
+
+@cindex Locker keyword
+@item $@asis{Locker}$
+The login name of the user who locked the revision
+(empty if not locked, and thus almost always useless
+when you are using @sc{cvs}).
+
+@cindex Log keyword
+@item $@asis{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{$@asis{Log:@dots{}}$}.
+Each new line is prefixed with a @dfn{comment leader}
+which @sc{rcs} guesses from the file name extension.
+It can be changed with @code{cvs admin -c}.
+@xref{admin options}. This keyword is useful for
+accumulating a complete change log in a source file,
+but for several reasons it can be problematic.
+@xref{Log keyword}.
+
+@cindex RCSfile keyword
+@item $@asis{RCSfile}$
+The name of the RCS file without a path.
+
+@cindex Revision keyword
+@item $@asis{Revision}$
+The revision number assigned to the revision.
+
+@cindex Source keyword
+@item $@asis{Source}$
+The full pathname of the RCS file.
+
+@cindex State keyword
+@item $@asis{State}$
+The state assigned to the revision. States can be
+assigned with @code{cvs admin -s}---@xref{admin options}.
+
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Using keywords
+@section Using keywords
+
+To include a keyword string you simply include the
+relevant text string, such as @code{$@asis{Id}$}, inside the
+file, and commit the file. @sc{cvs} will automatically
+expand the string as part of the commit operation.
+
+@need 800
+It is common to embed @code{$@asis{}Id$} string in the
+C source code. This example shows the first few lines
+of a typical file, after keyword substitution has been
+performed:
+
+@example
+static char *rcsid="$@asis{}Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $";
+/* @r{The following lines will prevent @code{gcc} version 2.@var{x}}
+ @r{from issuing an "unused variable" warning}. */
+#if __GNUC__ == 2
+#define USE(var) static void * use_##var = (&use_##var, (void *) &var)
+USE (rcsid);
+#endif
+@end example
+
+Even though a clever optimizing compiler could remove
+the unused variable @code{rcsid}, most compilers tend
+to include the string in the binary. Some compilers
+have a @code{#pragma} directive to include literal text
+in the binary.
+
+@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:
+ $@asis{}Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
+$ gcc samp.c
+$ ident a.out
+a.out:
+ $@asis{}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 @sc{rcs} keyword with the
+magic @sc{sccs} phrase, like this:
+
+@example
+static char *id="@@(#) $@asis{}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{$@asis{}Author$} to appear inside a file without
+@sc{rcs} interpreting it as a keyword and expanding it
+into something like @samp{$@asis{}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. (If you put binaries under
+version control you are strongly encouraged to use that
+option, for obvious reasons).
+
+In many cases you can avoid using @sc{rcs} 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{$@asis{}Author$} should appear. In @code{nroff}
+and @code{troff} you can embed the null-character
+@code{\&} inside the keyword for a similar effect.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Substitution modes
+@section Substitution modes
+@cindex -k (RCS kflags)
+@cindex Kflag
+
+You can control how @sc{rcs} expands keywords
+through the use of the @samp{-k} option (@pxref{Common
+options}). The @samp{-k} option is available with the
+@code{add}, @code{checkout}, @code{diff} and
+@code{update} commands.
+
+Five different modes are available. They are:
+
+@table @samp
+@item -kkv
+Generate keyword strings using the default form, e.g.
+@code{$@asis{}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.
+This option is normally not useful when @sc{cvs} is used.
+
+@item -kk
+Generate only keyword names in keyword strings; omit
+their values. For example, for the @code{Revision}
+keyword, generate the string @code{$@asis{}Revision$}
+instead of @code{$@asis{}Revision: 5.7 $}. This option
+is useful to ignore differences due to keyword
+substitution when comparing different revisions of a
+file.
+
+@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{$@asis{}Revision: 1.1 $} instead of
+@code{$@asis{}Revision: 5.7 $} if that is how the
+string appeared when the file was checked in. This can
+be useful for binary file formats that cannot tolerate
+any changes to substrings that happen to take the form
+of keyword strings.
+
+@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{$@asis{}Revision: 5.7 $}.
+This can help generate files in programming languages
+where it is hard to strip keyword delimiters like
+@code{$@asis{}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.
+
+This option is always use by @code{cvs
+export}---@pxref{export}.
+
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Log keyword
+@section Problems with the $@asis{}Log$ keyword.
+
+The @code{$@asis{}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{$@asis{}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{rcs} is not good at
+handling @code{$@asis{}Log$} entries when a branch is
+merged onto the main trunk. Conflicts often result
+from the merging operation.
+
+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{$@asis{}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 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 Commit, 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 Invoking CVS
+@appendix Reference manual for CVS commands
+@cindex Command reference
+@cindex Reference, commands
+@cindex Invoking CVS
+
+This appendix describes every subcommand of @sc{cvs} in
+detail. It also describes how to invoke CVS.
+
+@menu
+* Structure:: Overall structure of CVS commands
+* ~/.cvsrc:: Default options with the ~/.csvrc file
+* Global options:: Options you give to the left of cvs_command
+* Common options:: Options you give to the right of cvs_command
+* add:: Add a new file/directory to the repository
+* admin:: Administration front end for rcs
+* checkout:: Checkout sources for editing
+* commit:: Check files into the repository
+* diff:: Run diffs 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:: Print out 'rlog' information for files
+* rdiff:: 'patch' format diffs between releases
+* release:: Indicate that a Module is no longer in use
+* remove:: Remove an entry from the repository
+* rtag:: Add a tag to a module
+* status:: Status info on the revisions
+* tag:: Add a tag to checked out version
+* 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 first release of @sc{cvs} consisted of a number of shell-scripts.
+Today @sc{cvs} is implemented as a single program that is a front-end
+to @sc{rcs} and @code{diff}. 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 program that is a front-end to @sc{rcs}.
+
+@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}. For
+example, @samp{-q} can often (but not always) be given
+as both a @code{cvs_option} and a
+@code{command_option}. @samp{-l}, when given as a
+@code{cvs_option}, only affects some of the commands.
+When it is given as a @code{command_option} is has a
+different meaning, and is accepted by more commands.
+In other words, do not take the above categorization
+too seriously. Look at the documentation instead.
+
+@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 @footnote{being the one that drove the
+implementation of the .cvsrc support} 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}), only the name 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 -u
+update -P
+co -P
+@end example
+
+@noindent
+the command @samp{cvs checkout foo} would not have the
+@samp{-P} option added to the arguments, while
+@samp{cvs co foo} would.
+
+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. Since
+@code{diff} doesn't have an option to specify use of
+the "old" format, you would need to use the @samp{-f}
+option to @samp{cvs} to turn off use of the
+@file{~/.cvsrc} options.
+
+
+
+@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
+@cindex RCSBIN, overriding
+@cindex Overriding RCSBIN
+@item -b @var{bindir}
+Use @var{bindir} as the directory where @sc{rcs} programs are
+located. Overrides the setting of the @code{$RCSBIN} environment
+variable and any precompiled directory. This parameter should be
+specified as an absolute pathname.
+
+@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. This parameter
+should be specified as an absolute pathname.
+
+@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.
+
+@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{diff},
+you may need to use @samp{-f} to show the tag names.
+@footnote{Yes, this really should be fixed, and it's
+being worked on}
+
+@item -H
+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 a summary of all the
+commands available.
+
+@item -l
+Do not log the cvs_command in the command history (but execute it
+anyway). @xref{history}, for information on command history.
+
+@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.
+
+@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
+@item -r
+Make new working files 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.
+
+@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
+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.
+
+@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{Warning:} 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
+(unless you explicitly override it; @pxref{update}).
+
+A wide variety of date formats are supported by the underlying
+@sc{rcs} facilities, similar to those described in co(1), but not
+exactly the same. The @var{date_spec} is interpreted as being
+in the local timezone, unless a specific timezone is specified.
+Examples of valid date specifications include:
+
+@example
+ 1 month ago
+ 2 hours ago
+ 400000 seconds ago
+ last year
+ last Monday
+ yesterday
+ a fortnight ago
+ 3/31/92 10:00:07 PST
+ January 23, 1987 10:05pm
+ 22:00 GMT
+@end example
+
+@samp{-D} is available with the @code{checkout},
+@code{diff}, @code{export}, @code{history},
+@code{rdiff}, @code{rtag}, and @code{update} commands.
+(The @code{history} command uses this option in a
+slightly different way; @pxref{history options}).
+
+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).
+
+@need 800
+@samp{-f} is available with these commands: @code{checkout},
+@code{export}, @code{rdiff}, @code{rtag}, and @code{update}.
+
+@strong{Warning:} The @code{commit} command also has a
+@samp{-f} option, but it has a different behavior for
+that command. @xref{commit options}.
+
+@item -H
+Help; describe the options available for this command. This is
+the only option supported for all @sc{cvs} commands.
+
+@item -k @var{kflag}
+Alter the default @sc{rcs} processing of keywords.
+@xref{Keyword substitution}, for the meaning of
+@var{kflag}. Your @var{kflag} specification is
+@dfn{sticky} when you use it to create a private copy
+of a source file; that is, when you use this option
+with the @code{checkout} or @code{update} commands,
+@sc{cvs} associates your selected @var{kflag} with the
+file, and continues to use it with future update
+commands on the same file until you specify otherwise.
+
+The @samp{-k} option is available with the @code{add},
+@code{checkout}, @code{diff} and
+@code{update} commands.
+
+@item -l
+Local; run only in current working directory, rather than
+recursing through subdirectories.
+
+@strong{Warning:} this is not the same
+as the overall @samp{cvs -l} option, which you can specify to the
+left of a cvs command!
+
+Available with the following commands: @code{checkout},
+@code{commit}, @code{diff}, @code{export}, @code{log},
+@code{remove}, @code{rdiff}, @code{rtag},
+@code{status}, @code{tag}, and @code{update}.
+
+@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 checkout/commit/tag program. (A program can be
+specified to run on each of these activities, in the modules
+database (@pxref{modules}); this option bypasses it).
+
+@strong{Warning:} this is not the same as the overall @samp{cvs -n}
+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 (remove) directories that are empty after being updated, on
+@code{checkout}, or @code{update}. Normally, an empty directory
+(one that is void of revision-controlled files) is left alone.
+Specifying @samp{-P} will cause these directories to be silently
+removed from your checked-out sources. This does not remove the
+directory from the repository, only from your checked out copy.
+Note that this option is implied by the @samp{-r} or @samp{-D}
+options of @code{checkout} and @code{export}.
+@c -- implied--
+
+@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 -Q
+Cause the command to be really quiet; the command will only
+generate output for serious problems. Available with the following
+commands: @code{checkout}, @code{import}, @code{export},
+@code{rdiff}, @code{rtag}, @code{tag}, and @code{update}.
+
+@item -q
+Cause the command to be somewhat quiet; informational messages,
+such as reports of recursion through subdirectories, are
+suppressed. Available with the following commands:
+@code{checkout}, @code{import}, @code{export}, @code{rtag},
+@code{tag}, and @code{update}.
+
+@item -r @var{tag}
+Use the revision specified by the @var{tag} argument 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.
+
+The tag specification is sticky when you use this option
+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. The
+tag can be either a symbolic or numeric tag.
+@xref{Tags}.
+
+Specifying the @samp{-q} option along with the @samp{-r} option is often
+useful, to suppress the warning messages when the @sc{rcs} history file does
+not contain the specified tag.
+
+@strong{Warning:} this is not the same as the overall `cvs -r' option,
+which you can specify to the left of a cvs command!
+
+@samp{-r} is available with the @code{checkout}, @code{commit},
+@code{diff}, @code{history}, @code{export}, @code{rdiff},
+@code{rtag}, and @code{update} commands.
+
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node add
+@appendixsec add---Add a new file/directory to the repository
+@cindex Add (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: add [-k kflag] [-m 'message'] files@dots{}
+@item
+Requires: repository, working directory.
+@item
+Changes: working directory.
+@item
+Synonym: new
+@end itemize
+
+Use the @code{add} command to create a new file or directory in the
+source repository. The files or directories specified with @code{add}
+must already exist in the current directory (which must have been
+created with the @code{checkout} command). 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}.
+
+If the argument to @code{add} refers to an immediate
+sub-directory, the directory is created at the correct place in
+the source repository, and the necessary @sc{cvs} administration
+files are created in your working directory. If the directory
+already exists in the source repository, @code{add} still creates
+the administration files in your version of the directory.
+This allows you to use @code{add} to add a particular directory
+to your private sources even if someone else created that
+directory after your checkout of the sources. You can do the
+following:
+
+@example
+$ mkdir new_directory
+$ cvs add new_directory
+$ cvs update new_directory
+@end example
+
+An alternate approach using @code{update} might be:
+
+@example
+$ cvs update -d new_directory
+@end example
+
+(To add any available new directories to your working directory,
+it's probably simpler to use @code{checkout} (@pxref{checkout})
+or @samp{update -d} (@pxref{update})).
+
+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 resurrect the file, unless a @code{commit} command
+intervened.
+@xref{remove examples} for an example.
+
+
+Unlike most other commands @code{add} never recurses down
+directories. It cannot yet handle relative paths. Instead of
+
+@example
+$ cvs add foo/bar.c
+@end example
+
+you have to do
+
+@example
+$ cd foo
+$ cvs add bar.c
+@end example
+
+@menu
+* add options:: add options
+* add examples:: add examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node add options
+@appendixsubsec add options
+@cindex Add options
+
+There are only two options you can give to @samp{add}:
+
+@table @code
+@item -k @var{kflag}
+This option specifies the default way that this file
+will be checked out. See rcs(1) and co(1). The
+@var{kflag} argument (@pxref{Substitution modes}) is
+stored in the @sc{rcs} file and can be changed with
+@code{admin -k} (@pxref{admin options}). Specifying
+@samp{-ko} is useful for checking in binaries that
+should not have the @sc{rcs} id strings expanded.
+
+@strong{Warning:} this option is reported to be broken in
+version 1.3 and 1.3-s2 of @sc{cvs}. Use @samp{admin -k}
+after the commit instead. @xref{admin examples}.
+@c -- broken--
+
+@item -m @var{description}
+Using this option, you can give 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 @sc{rcs} history
+file 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 table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node add examples
+@appendixsubsec add examples
+
+To add the file @file{backend.c} to the repository, with a
+description, the following can be used.
+
+@example
+$ cvs add -m "Optimizer and code generation passes." backend.c
+$ cvs commit -m "Early version. Not yet compilable." backend.c
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node admin
+@appendixsec admin---Administration front end for rcs
+@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 @sc{rcs}
+facilities, documented in rcs(1). @code{admin} simply passes
+all its options and arguments to the @code{rcs} command; it does
+no filtering or other processing. This command @emph{does} work
+recursively, however, so extreme care should be used.
+
+@menu
+* admin options:: admin options
+* admin examples:: admin examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node admin options
+@appendixsubsec admin options
+
+Not all valid @code{rcs} options are useful together
+with @sc{cvs}. Some even makes it impossible to use
+@sc{cvs} until you undo the effect!
+
+This description of the available options is based on
+the @samp{rcs(1)} man page, but modified to suit
+readers that are more interrested in @sc{cvs} than
+@sc{rcs}.
+
+@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}]
+Breaks @sc{cvs}. When used with bare @sc{rcs}, this
+option sets the default branch to @var{rev}.
+If @var{rev} is omitted, the default branch is reset to
+the (dynamically) highest branch on the trunk. Use
+sticky tags instead, as in @code{cvs co -r}.
+@xref{Sticky tags}.
+
+@item -c@var{string}
+Useful with @sc{cvs}. Sets the comment leader to
+@var{string}. The comment leader is printed before
+every log message line generated by the keyword
+@code{$@asis{}Log$} (@pxref{Keyword substitution}).
+This is useful for programming languages without
+multi-line comments. @sc{Rcs} initially guesses the
+value of the comment leader from the file name
+extension when the file is first committed.
+
+@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.
+
+@item -I
+Run interactively, even if the standard input is not a
+terminal.
+
+@item -i
+Useless with @sc{cvs}. When using bare @sc{rcs}, this
+is used to create and initialize a new @sc{rcs} file,
+without depositing a revision.
+
+@item -k@var{subst}
+Useful with @sc{cvs}. Set the default keyword
+substitution to @var{subst}. @xref{Keyword
+substitution}. Giving an explicit @samp{-k} option to
+@code{cvs update} or @code{cvs checkout} overrides this
+default. @code{cvs export} always uses @code{-kv},
+regardless of which keyword substitution is set with
+@code{cvs admin}.
+
+@item -l[@var{rev}]
+Probably useless with @sc{cvs}. With bare @sc{rcs},
+this option can be used to 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.
+
+@item -L
+Probably useless with @sc{cvs}. Used with bare
+@sc{rcs} to set locking to strict. Strict
+locking means that the owner of an RCS file is not
+exempt from locking for checkin.
+
+@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}.
+
+@item -N@var{name}[:[@var{rev}]]
+Act like @samp{-n}, except override any previous
+assignment of @var{name}.
+
+@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{rcs -n@var{name}: RCS/*} associates @var{name} with the
+current latest revision of all the named RCS files;
+this contrasts with @samp{rcs -n@var{name}:$ RCS/*} 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}
+Useful, but dangerous, with @sc{cvs} (see below).
+Deletes (@dfn{outdates}) the revisions given by
+@var{range}. A range consisting of a single revision
+number means that revision. A range consisting of a
+branch number means the latest revision on that branch.
+A range of the form @samp{@var{rev1}:@var{rev2}} means
+revisions @var{rev1} to @var{rev2} on the same branch,
+@samp{:@var{rev}} means from the beginning of the
+branch containing @var{rev} up to and including
+@var{rev}, and @samp{@var{rev}:} means from revision
+@var{rev} to the end of the branch containing
+@var{rev}. None of the outdated revisions may have
+branches or locks.
+
+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.
+
+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, you should never use this option to take
+back a bogus commit unless you work alone. Instead,
+you should fix the file and commit a new revision.
+
+@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{$@asis{}Log$} and @samp{$@asis{}State$} keywords
+(@pxref{Keyword substitution}).
+
+@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{-}. 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}. The descriptive text can be seen in the
+output from @samp{cvs log} (@pxref{log}).
+
+@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.
+
+@item -U
+Probably useless with @sc{cvs}. Used with bare
+@sc{rcs} to set locking to non-strict. Non-strict
+locking means that the owner of a file need not lock a
+revision for checkin.
+
+@item -u[@var{rev}]
+Probably useless with @sc{cvs}. With bare @sc{rcs},
+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 a mail message to be sent
+to the original locker. The message contains a
+commentary solicited from the breaker. The commentary
+is terminated by end-of-file or by a line containing
+@code{.} by itself.
+
+@item -V@var{n}
+Emulate @sc{rcs} version @var{n}. Use -V@var{n} to make
+an @sc{rcs} file acceptable to @sc{rcs} version @var{n}
+by discarding information that would confuse version
+@var{n}.
+
+@item -x@var{suffixes}
+Useless with @sc{cvs}. Use @var{suffixes} to
+characterize RCS files.
+@end table
+
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node admin examples
+@appendixsubsec admin examples
+
+@appendixsubsubsec Outdating is dangerous
+
+First, an example of how @emph{not} to use the
+@code{admin} command. It is included to stress the
+fact that this command can be quite dangerous unless
+you know @emph{exactly} what you are doing.
+
+The @samp{-o} option can be used to @dfn{outdate} old revisions
+from the history file. 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!
+
+The next line is an example of a command that you would
+@emph{not} like to execute.
+
+@example
+$ cvs admin -o:R_1_02 .
+@end example
+
+The above command will delete all revisions up to, and
+including, the revision that corresponds to 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!
+
+@need 1200
+@appendixsubsubsec Handling binary files
+@cindex Binary files (inhibit keyword expansion)
+@cindex Inhibiting keyword expansion
+@cindex Keyword expansion, inhibiting
+
+If you use @sc{cvs} to store binary files, where
+keyword strings (@pxref{Keyword substitution}) might
+accidentally appear inside the file, you should use
+@code{cvs admin -ko} to make sure that they are not
+modified automatically. Here is an example of how you
+can create a new file using the @samp{-ko} flag:
+
+@example
+$ echo '$@asis{}Id$' > kotest
+$ cvs add -m"A test file" kotest
+$ cvs ci -m"First checkin; contains a keyword" kotest
+$ cvs admin -ko kotest
+$ rm kotest
+$ cvs update kotest
+@end example
+
+When you check in the file @file{kotest} the keywords
+are expanded. (Try the above example, and do a
+@code{cat kotest} after every command!) The @code{cvs
+admin -ko} command sets the default keyword
+substitution method for this file, but it does not
+alter the working copy of the file that you have. The
+easiest way to get the unexpanded version of
+@file{kotest} is to remove it and check it out again.
+
+@appendixsubsubsec Comment leaders
+@cindex Comment leader
+@cindex Log keyword, selecting comment leader
+@cindex Nroff (selecting comment leader)
+
+If you use the @code{$@asis{}Log$} keyword and you do
+not agree with the guess for comment leader that
+@sc{cvs} has done, you can enforce your will with
+@code{cvs admin -c}. This might be suitable for
+@code{nroff} source:
+
+@example
+$ cvs admin -c'.\" ' *.man
+$ rm *.man
+$ cvs update
+@end example
+
+The two last steps are to make sure that you get the
+versions with correct comment leaders in your working
+files.
+
+@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
+
+Make 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} part of the command 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}.
+
+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} option).
+
+Running @code{checkout} on a directory that was already
+built by a prior @code{checkout} is also permitted, and
+has the same effect as specifying the @samp{-d} option
+to the @code{update} command, that is, any new
+directories that have been created in the repository
+will appear in your work area. @xref{update}.
+
+@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}.
+
+@item -f
+Only useful with the @samp{-D @var{date}} or @samp{-r
+@var{tag}} flags. If no matching revision is found,
+retrieve the most recent revision (instead of ignoring
+the file).
+
+@item -k @var{kflag}
+Process @sc{rcs} keywords according to @var{kflag}. See
+co(1). 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. @xref{status}.
+
+@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.
+
+@item -p
+Pipe files to the standard output.
+
+@item -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+
+@item -r @var{tag}
+Use revision @var{tag}. This option is sticky, and implies @samp{-P}.
+@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.
+(If you get a working file using one of the @samp{-r},
+@samp{-D}, or @samp{-k} options, @sc{cvs} remembers the
+corresponding tag, date, or @var{kflag} and continues using
+it for future updates; use the @samp{-A} option to make
+@sc{cvs} forget these specifications, and retrieve the
+`head' revision of the file).
+
+@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. Unless you
+also use @samp{-N}, the paths created under @var{dir}
+will be as short as possible.
+
+@item -j @var{tag}
+Merge the changes made between the resulting revision
+and the revision that it is based on (e.g., if
+@var{tag} refers to a branch, @sc{cvs} will merge all
+changes made on that branch into your working file).
+
+With two @samp{-j @var{tag}} options, @sc{cvs} will merge in the
+changes between the two respective revisions. This can
+be used to undo changes made between two revisions
+(@pxref{Merging two revisions}) in your working copy,
+or to move changes between different branches.
+
+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. An example might be what @code{import}
+tells you to do when you have just imported sources
+that have conflicts with local changes:
+
+@example
+$ cvs checkout -jTAG:yesterday -jTAG module
+@end example
+
+@item -N
+Only useful together with @samp{-d @var{dir}}. With this
+option, @sc{cvs} will not shorten module paths in your
+working directory. (Normally, @sc{cvs} shortens paths as
+much as possible when you specify an explicit target
+directory).
+
+@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
+Version 1.3 Synopsis: commit [-lnR] [-m 'log_message' |
+-f file] [-r revision] [files@dots{}]
+@item
+Version 1.3.1 Synopsis: commit [-lnRf] [-m 'log_message' |
+-F file] [-r revision] [files@dots{}]
+@c -- rename-f-F--
+@item
+Requires: working directory, repository.
+@item
+Changes: repository.
+@item
+Synonym: ci
+@end itemize
+
+@strong{Warning:} The @samp{-f @var{file}} option will
+probably be renamed to @samp{-F @var{file}}, and @samp{-f}
+will be given a new behavior in future releases of @sc{cvs}.
+@c -- rename-f-F--
+
+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} history file inside the
+repository. This log message can be retrieved with the
+@code{log} command; @xref{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
+@c -- rename-f-F--
+that the argument file contains the log message.
+
+@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 -n
+Do not run any module program.
+
+@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. You
+cannot commit to a specific revision on a branch.
+@end table
+
+@code{commit} also supports these options:
+
+@table @code
+@item -F @var{file}
+This option is present in @sc{cvs} releases 1.3-s3 and
+later. Read the log message from @var{file}, instead
+of invoking an editor.
+
+@item -f
+@c -- rename-f-F--
+This option is present in @sc{cvs} 1.3-s3 and later releases
+of @sc{cvs}. Note that this is not the standard behavior of
+the @samp{-f} option as defined in @xref{Common options}.
+
+Force @sc{cvs} to commit a new revision even if you haven't
+made any changes to the file. 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
+
+@item -f @var{file}
+@c -- rename-f-F--
+This option is present in @sc{cvs} releases 1.3, 1.3-s1 and
+1.3-s2. Note that this is not the standard behavior of
+the @samp{-f} option as defined in @xref{Common options}.
+
+Read the log message from @var{file}, instead
+of invoking an editor.
+
+@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
+
+@appendixsubsubsec New major release number
+
+When you make a major release of your product, you
+might want the revision numbers to track your major
+release number. You should normally not care about
+the revision numbers, but this is a thing that many
+people want to do, and it can be done without doing any
+harm.
+
+To bring all your files up to the @sc{rcs} revision 3.0
+(including those that haven't changed), you might do:
+
+@example
+$ cvs commit -r 3.0
+@end example
+
+Note that it is generally a bad idea to try to make the
+@sc{rcs} revision number equal to the current release number
+of your product. You should think of the revision
+number as an internal number that the @sc{cvs} package
+maintains, and that you generally never need to care
+much about. Using the @code{tag} and @code{rtag}
+commands you can give symbolic names to the releases
+instead. @xref{tag} and @xref{rtag}.
+
+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}.
+
+@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{tag}
+or @pxref{rtag}). 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:
+
+@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:
+
+@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---Run diffs between revisions
+@cindex Diff (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: diff [-l] [rcsdiff_options] [[-r rev1 | -D date1] [-r rev2 | -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 will be 0 if no differences were found,
+1 if some differences were found, and 2 if any error
+occurred.
+
+@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.
+
+@sc{cvs} can be configured to pass the @samp{-D} option
+through to @code{rcsdiff} (which in turn passes it on
+to @code{diff}. @sc{Gnu} diff uses @samp{-D} as a way to
+put @code{cpp}-style @samp{#define} statements around the output
+differences. There is no way short of testing to
+figure out how @sc{cvs} was configured. In the default
+configuration @sc{cvs} will use the @samp{-D @var{date}} option.
+
+@item -k @var{kflag}
+Process @sc{rcs} keywords according to @var{kflag}. See
+co(1).
+
+@item -l
+Local; run only in current working directory.
+
+@item -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+
+@item -R
+Examine directories recursively. This option is on by
+default.
+
+@item -r @var{tag}
+Compare with revision @var{tag}. 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).
+
+One or both @samp{-r} options can be replaced by a
+@samp{-D @var{date}} option, described above.
+@end table
+
+Any other options that are found are passed through to
+@code{rcsdiff}, which in turn passes them to
+@code{diff}. The exact meaning of the options depends
+on which @code{diff} you are using. The long options
+introduced in @sc{gnu} diff 2.0 are not yet supported in
+@sc{cvs}. See the documentation for your @code{diff} to see
+which options are supported.
+
+@c -- Document some common useful diff options, such as
+@c -u and -c.
+@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 [-flNnQq] -r rev|-D date [-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.
+
+The keyword substitution option @samp{-kv} is always set when
+export is used. This causes any @sc{rcs} keywords to be
+expanded such that an import done at some other site
+will not lose the keyword revision information. There
+is no way to override this. Note that this breaks the
+@code{ident} command (which is part of the @sc{rcs}
+suite---see ident(1)) which looks for @sc{rcs} keyword
+strings. If you want to be able to use @code{ident}
+you must use @code{checkout} instead.
+
+@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 -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+
+@item -R
+Export directories recursively. This is on by default.
+
+@item -r @var{tag}
+Use revision @var{tag}.
+@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. Unless you
+also use @samp{-N}, the paths created under @var{dir}
+will be as short as possible.
+
+@item -N
+Only useful together with @samp{-d @var{dir}}. With this
+option, @sc{cvs} will not shorten module paths in your
+working directory. (Normally, @sc{cvs} shortens paths as
+much as possible when you specify an explicit target
+directory.)
+@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 file that tracks each use of the
+@code{checkout}, @code{commit}, @code{rtag},
+@code{update}, and @code{release} commands. You can
+use @code{history} to display this information in
+various formats.
+
+Logging must be enabled by creating the file
+@file{$CVSROOT/CVSROOT/history}.
+
+@strong{Warning:} @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{-xMACFROGWUT}.
+
+@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.
+
+@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 T
+rtag
+@end table
+
+@noindent
+One of four 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 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 -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 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}.
+@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)
+
+@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.
+
+By default, certain file names are ignored during
+@code{import}: 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 files includes
+files matching these names:
+
+@example
+ RCSLOG RCS SCCS
+ CVS* cvslog.*
+ tags TAGS
+ .make.state .nse_depinfo
+ *~ #* .#* ,*
+ *.old *.bak *.BAK *.orig *.rej .del-*
+ *.a *.o *.so *.Z *.elc *.ln
+ core
+@end example
+
+If the file @file{$CVSROOT/CVSROOT/cvsignore} exists,
+any files whose names match the specifications in that
+file will also be ignored.
+
+The outside source is saved in a first-level @sc{rcs}
+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 identify the files at
+the leaves created each time you execute @code{import}.
+
+@menu
+* import options:: import options
+* import examples:: import examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node import options
+@appendixsubsec import options
+
+These standard options are supported by @code{import}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -m @var{message}
+Use @var{message} as log information, instead of
+invoking an editor.
+
+@item -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+@end table
+
+There are three additional special options.
+
+@table @code
+@item -b @var{branch}
+Specify a first-level branch other than 1.1.1. Unless
+the @samp{-b @var{branch}} flag is given, revisions will
+@emph{always} be made to the branch 1.1.1---even if a
+@var{vendortag} that matches another branch is given!
+What happens in that case, is that the tag will be
+reset to 1.1.1. Warning: This behavior might change
+in the future.
+
+@item -k @var{subst}
+Indicate the RCS 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 co(1) for a complete list of
+valid @samp{-k} settings.
+
+If you are checking in sources that contain @sc{rcs} keywords, and you
+wish those keywords to remain intact, use the @samp{-ko} flag when
+importing the files. This setting indicates that no keyword expansion
+is to be performed by @sc{rcs} when checking files out. It is also
+useful for checking in binaries.
+
+@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?
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node import examples
+@appendixsubsec import examples
+
+@xref{Tracking sources}, and @xref{From files}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node log
+@appendixsec log---Print out 'rlog' information for files
+@cindex Log (subcommand)
+
+@itemize @bullet
+@item
+Synopsis: log [-l] rlog-options [files@dots{}]
+@item
+Requires: repository, working directory.
+@item
+Changes: nothing.
+@item
+Synonym: rlog
+@end itemize
+
+Display log information for files. @code{log} calls
+the @sc{rcs} utility @code{rlog}, which prints all available
+information about the @sc{rcs} history file. This 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 author, the number of lines added/deleted and
+the log message are printed. All times are displayed in
+Coordinated Universal Time (UTC). (Other parts of @sc{cvs}
+print times in the local timezone).
+@c -- timezone--
+
+@menu
+* log options:: log options
+* log examples:: log examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node log options
+@appendixsubsec log options
+
+Only one option is interpreted by @sc{cvs} and not passed on to @code{rlog}:
+
+@table @code
+@item -l
+Local; run only in current working directory. (Default
+is to run recursively).
+@end table
+
+By default, @code{rlog} prints all information that is
+available. All other options (including those that
+normally behave differently) are passed through to
+@code{rlog} and restrict the output. See rlog(1) for a
+complete description of options. This incomplete list
+(which is a slightly edited extract from rlog(1)) lists
+all options that are useful in conjunction with @sc{cvs}.
+
+@strong{Please note:} There can be no space between the option
+and its argument, since @code{rlog} parses its options
+in a different way than @sc{cvs}.
+
+@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 following table
+explains the available range formats:
+
+@table @code
+@item @var{d1}<@var{d2}
+@itemx @var{d2}>@var{d1}
+Select the revisions that were deposited between
+@var{d1} and @var{d2} inclusive.
+
+@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 date/time strings @var{d}, @var{d1}, and @var{d2}
+are in the free format explained in co(1). Quoting is
+normally necessary, especially for < and >. Note that
+the separator is a semicolon (;).
+
+@item -h
+Print only the @sc{rcs} pathname, working pathname, head,
+default branch, access list, locks, symbolic names, and
+suffix.
+
+@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} history file.
+
+@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{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{branch}
+An argument that is a branch means all revisions on
+that branch. You can unfortunately not specify a
+symbolic branch here. You must specify the numeric
+branch number. @xref{Magic branch numbers}, for an
+explanation.
+
+@item @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.
+
+@item -s@var{states}
+Print information about revisions whose state
+attributes match one of the states given in the
+comma-separated list @var{states}.
+
+@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.
+@end table
+
+@code{rlog} prints the intersection of the revisions
+selected with the options @samp{-d}, @samp{-l},
+@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
+
+Contributed examples are gratefully accepted.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node rdiff
+@appendixsec rdiff---'patch' format diffs between releases
+@cindex Rdiff (subcommand)
+
+@itemize @bullet
+@item
+rdiff [-flags] [-V vn] [-r t|-D d [-r t2|-D d2]] 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 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 patch command when
+patching the old sources, so that 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 -l
+Local; don't descend subdirectories.
+
+@item -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+
+@item -r @var{tag}
+Use revision @var{tag}.
+@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.
+This option is not available if your diff does not
+support the unidiff format. 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 @sc{rcs} keywords according to the rules current in
+@sc{rcs} version @var{vn} (the expansion format changed with
+@sc{rcs} version 5).
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node rdiff examples
+@appendixsubsec rdiff examples
+
+Suppose you receive mail from @t{foo@@bar.com} 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@@bar.com
+@end example
+
+Suppose you have made release 1.3, and forked a branch
+called @samp{R_1_3fix} for bugfixes. @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 [-dQq] modules@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 options
+* release examples:: release examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node release options
+@appendixsubsec release options
+
+Only these standard options are supported by @code{release}.
+
+@table @code
+@item -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+@end table
+
+In addition to the above, it supports one additional
+flag.
+
+@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 uses
+@samp{rm -r @file{module}} to delete your file. 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{add}) 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.
+
+@strong{Warning:} Any new directories that you have
+created, but not added to the @sc{cvs} directory hierarchy
+with the @code{add} command (@pxref{add}) will be
+silently ignored (and deleted, if @samp{-d} is
+specified), even if they contain files.
+
+@table @code
+@item U @var{file}
+There exists a newer revision of this file in the
+repository, and you have not modified your local copy
+of the file.
+
+@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.
+
+Note that no warning message like this is printed for
+spurious directories that @sc{cvs} encounters. The
+directory, and all its contents, are silently ignored.
+
+@c FIXME -- this should be fixed for CVS 1.4
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node release examples
+@appendixsubsec release examples
+
+Release the module, 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) module `tc': y
+$
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node remove
+@appendixsec remove---Remove an entry from the repository
+@cindex Remove (subcommand)
+
+@itemize @bullet
+@item
+remove [-lR] [files@dots{}]
+@item
+Requires: Working directory.
+@item
+Changes: Working directory.
+@item
+Synonyms: rm, delete
+@end itemize
+
+Use this command to declare that you wish to remove
+files from the source repository. Like most @sc{cvs}
+commands, @samp{cvs remove} works on files in your working
+directory, not directly on the repository. As a
+safeguard, it also requires that you first erase the
+specified files from your working directory.
+
+The files are not actually removed until you apply your
+changes to the repository with @code{commit}; at that
+point, the corresponding @sc{rcs} files in the source
+repository are moved into the @file{Attic} directory
+(also within the source repository).
+
+This command is recursive by default, scheduling all
+physically removed files that it finds for removal by
+the next commit. Use the @samp{-l} option to avoid
+this recursion, or just specify the actual files that
+you wish removed.
+
+
+@menu
+* remove options:: remove options
+* remove examples:: remove examples
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node remove options
+@appendixsubsec remove options
+
+Two of the standard options are the only options
+supported by @code{remove}.
+
+@table @code
+@item -l
+Local; run only in current working directory.
+
+@item -R
+Commit directories recursively. This is on by default.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node remove examples
+@appendixsubsec remove examples
+
+@appendixsubsubsec Remove a couple of 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
+
+@appendixsubsubsec Resurrecting removed files
+
+If you change your mind you can easily resurrect the
+file before you commit it, using the @code{add}
+command.
+
+@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
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node rtag
+@appendixsec rtag---Add a tag to the RCS file
+@cindex Rtag (subcommand)
+
+@itemize @bullet
+@item
+rtag [-falnRQq] [-b] [-d] [-r tag | -Ddate] symbolic_tag modules@dots{}
+@item
+Requires: repository.
+@item
+Changes: repository.
+@item
+Synonym: rfreeze
+@end itemize
+
+You can use this command to assign symbolic tags to
+particular, explicitly specified source revisions in
+the repository. @code{rtag} works directly on the
+repository contents (and requires no prior checkout).
+Use @code{tag} instead (@pxref{tag}), to base the
+selection of revisions on the contents of your
+working directory.
+
+If you attempt to use a tag name that already exists,
+@sc{cvs} will complain and not overwrite that tag. Use
+the @samp{-F} option to force the new tag value.
+
+@menu
+* rtag options:: rtag options
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node rtag options
+@appendixsubsec rtag options
+
+These standard options are supported by @code{rtag}
+(@pxref{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 @var{date}} or @samp{-r @var{tag}}
+flags. If no matching revision is found, use the most
+recent revision (instead of ignoring the file).
+
+@item -F
+Overwrite an existing tag of the same name on a
+different revision. This option is new in @sc{cvs}
+1.4. The old behavior is matched by @samp{cvs tag -F}.
+
+@item -l
+Local; run only in current working directory.
+
+@item -n
+Do not run any tag program that was specified with the
+@samp{-t} flag inside the @file{modules} file.
+(@pxref{modules}).
+
+@item -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+
+@item -R
+Commit directories recursively. This is on by default.
+
+@item -r @var{tag}
+Only tag those files that contain @var{tag}. This can
+be used to rename a tag: tag only the files identified
+by the old tag, then delete the old tag, leaving the
+new tag on exactly the same files as the old tag.
+@end table
+
+In addition to the above common options, these options
+are available:
+
+@table @code
+@item -a
+Use the @samp{-a} option to have @code{rtag} look in the
+@file{Attic} (@pxref{Removing files}) for removed files
+that contain the specified tag. The tag is removed from
+these files, which makes it convenient to re-use a
+symbolic tag as development continues (and files get
+removed from the up-coming distribution).
+
+@item -b
+Make the tag a branch tag. @xref{Branches}.
+
+@item -d
+Delete the tag instead of creating it.
+
+In general, tags (often the symbolic names of software
+distributions) should not be removed, but the @samp{-d}
+option is available as a means to remove completely
+obsolete symbolic names if necessary (as might be the
+case for an Alpha release, or if you mistagged a
+module).
+@end table
+
+@ignore
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@c @node rtag examples
+@appendixsubsec rtag examples
+
+@c -- Examples here!
+@end ignore
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node status
+@appendixsec status---Status info on the revisions
+@cindex Status (subcommand)
+
+@itemize @bullet
+@item
+status [-lR] [-v] [-Q] [files@dots{}]
+@item
+Requires: working directory, repository.
+@item
+Changes: nothing.
+@end itemize
+
+Display a brief report on the current status of files
+with respect to the source repository, including any
+sticky tags, dates, or @samp{-k} options.
+
+You can also use this command to determine the
+potential impact of a @samp{cvs update} on your working
+source directory---but remember that things might
+change in the repository before you run @code{update}.
+
+@menu
+* status options:: status options
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node status options
+@appendixsubsec status options
+
+These standard options are supported by @code{status}
+(@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 -Q
+Really quiet. Do not print empty sticky parts. This
+option is not available in @sc{cvs} 1.3.
+@end table
+
+There is one additional option:
+
+@table @code
+@item -v
+Verbose. In addition to the information normally
+displayed, print all symbolic tags, together with the
+numerical value of the revision or branch they refer
+to.
+@end table
+
+@ignore
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@c @node status examples
+@appendixsubsec status examples
+
+@c -- FIXME
+@end ignore
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node tag
+@appendixsec tag---Add a symbolic tag to checked out version of RCS file
+@c -- //////// - unnecessary. Also
+@c -- in a lot of other
+@c -- places.
+@cindex Tag (subcommand)
+
+@itemize @bullet
+@item
+tag [-lQqR] [-b] [-d] symbolic_tag [files@dots{}]
+@item
+Requires: working directory, repository.
+@item
+Changes: repository.
+@item
+Synonym: freeze
+@end itemize
+
+Use this command to assign symbolic tags to the nearest
+repository versions to your working sources. The tags
+are applied immediately to the repository, as with
+@code{rtag}, but the versions are supplied implicitly by the
+@sc{cvs} records of your working files' history rather than
+applied explicitly.
+
+One use for tags is to record a snapshot of the
+current sources when the software freeze date of a
+project arrives. As bugs are fixed after the freeze
+date, only those changed sources that are to be part of
+the release need be re-tagged.
+
+The symbolic tags are meant to permanently record which
+revisions of which files were used in creating a
+software distribution. The @code{checkout} and
+@code{update} commands allow you to extract an exact
+copy of a tagged release at any time in the future,
+regardless of whether files have been changed, added,
+or removed since the release was tagged.
+
+This command can also be used to delete a symbolic tag,
+or to create a branch. See the options section below.
+
+If you attempt to use a tag name that already exists,
+@sc{cvs} will complain and not overwrite that tag. Use
+the @samp{-F} option to force the new tag value.
+
+
+@menu
+* tag options:: tag options
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node tag options
+@appendixsubsec tag options
+
+These standard options are supported by @code{tag}
+(@pxref{Common options}, for a complete description of
+them):
+
+@table @code
+@item -F
+Overwrite an existing tag of the same name on a
+different revision. This option is new in @sc{cvs}
+1.4. The old behavior is matched by @samp{cvs tag -F}.
+
+@item -l
+Local; run only in current working directory.
+
+@item -R
+Commit directories recursively. This is on by default.
+
+@item -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+@end table
+
+Two special options are available:
+
+@table @code
+@item -b
+The -b option makes the tag a branch tag
+(@pxref{Branches}), allowing concurrent, isolated
+development. This is most useful for creating a patch
+to a previously released software distribution.
+
+@item -d
+Delete a tag.
+
+If you use @samp{cvs tag -d symbolic_tag}, the symbolic
+tag you specify is deleted instead of being added.
+Warning: Be very certain of your ground before you
+delete a tag; doing this permanently discards some
+historical information, which may later turn out to
+be valuable.
+@end table
+
+@ignore
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@c @node tag examples
+@appendixsubsec tag examples
+
+@c -- FIXME
+@end ignore
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node update
+@appendixsec update---Bring work tree in sync with repository
+@cindex Update (subcommand)
+
+@itemize @bullet
+@item
+update [-AdflPpQqR] [-d] [-r tag|-D date] 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.
+
+@menu
+* update options:: update options
+* update output:: update output
+* update examples:: update examples
+@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}.
+
+@item -f
+Only useful with the @samp{-D @var{date}} or @samp{-r
+@var{tag}} flags. If no matching revision is found,
+retrieve the most recent revision (instead of ignoring
+the file).
+
+@item -k @var{kflag}
+Process @sc{rcs} keywords according to @var{kflag}. See
+co(1). 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. @xref{status}.
+
+@item -l
+Local; run only in current working directory.
+
+@item -P
+Prune empty directories.
+
+@item -p
+Pipe files to the standard output.
+
+@item -Q
+Really quiet.
+
+@item -q
+Somewhat quiet.
+
+@item -R
+Commit directories recursively. This is on by default.
+
+@item -r tag
+Retrieve revision @var{tag}. This option is sticky,
+and implies @samp{-P}.
+@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.
+(If you get a working copy of a file by using one of
+the @samp{-r}, @samp{-D}, or @samp{-k} options, @sc{cvs}
+remembers the corresponding tag, date, or @var{kflag} and
+continues using it on future updates; use the @samp{-A}
+option to make @sc{cvs} forget these specifications, and
+retrieve the head revision of the file).
+
+@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. By default, @code{update}
+ignores files whose names match any of the following:
+
+@example
+ RCSLOG RCS SCCS
+ CVS* cvslog.*
+ tags TAGS
+ .make.state .nse_depinfo
+ *~ #* .#* ,*
+ *.old *.bak *.BAK *.orig *.rej .del-*
+ *.a *.o *.so *.Z *.elc *.ln
+ core
+@end example
+
+Use @samp{-I !} to avoid ignoring any files at all.
+@xref{cvsignore}, for other ways to make @sc{cvs} ignore
+some files.
+
+@item -j@var{branch}
+Merge the changes made between the resulting revision
+and the revision that it is based on (e.g., if the tag
+refers to a branch, @sc{cvs} will merge all changes made in
+that branch into your working file).
+
+With two @samp{-j} options, @sc{cvs} will merge in the
+changes between the two respective revisions. This can
+be used to remove a certain delta from your working
+file; if the file @file{foo.c} is based on
+revision 1.6 and you want to remove the changes made
+between 1.3 and 1.5, you might do:
+
+@example
+$ cvs update -j1.5 -j1.3 foo.c # @r{note the order@dots{}}
+@end example
+
+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}}.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node update output
+@appendixsubsec update output
+
+@code{update} 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 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 source, and for files
+that you haven't changed but are not the most recent
+versions available in the repository.
+
+@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}
+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 output of the rcsmerge(1) command
+on 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 @sc{rcs} revision that your modified file started
+from. (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.)
+
+@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}).
+
+Note that no warning message like this is printed for
+spurious directories that @sc{cvs} encounters. The
+directory, and all its contents, are silently ignored.
+@end table
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node update examples
+@appendixsubsec update examples
+
+The following line will display all files which are not
+up-to-date without actually change anything in your
+working directory. It can be used to check what has
+been going on with the project.
+
+@example
+$ cvs -n -q update
+@end example
+
+@c ---------------------------------------------------------------------
+@node Administrative files
+@appendix Reference manual for the 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.
+
+The most important of these files is the @file{modules}
+file, which defines the modules inside the repository.
+
+@menu
+* modules:: Defining modules
+* commit files:: The commit support files
+* commitinfo:: Pre-commit checking
+* editinfo:: Specifying how log messages are created
+* loginfo:: Where should log messages be sent?
+* rcsinfo:: Templates for the log messages
+* cvsignore:: Ignoring files via cvsignore
+* history file:: History information
+* Setting up:: Setting up the repository
+@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 create a file with the right
+format in @file{$CVSROOT/CVSROOT/modules,v}. The
+mkmodules(1) command should be run whenever the modules
+file changes, so that the appropriate files can be
+generated (depending on how you have configured @sc{cvs}
+operation).
+
+To allow convenient editing of the @file{modules} file
+itself, the file should include an entry like the
+following (where @var{localbin} represents the
+directory where your site installs programs like
+mkmodules(1)):
+
+@example
+modules -i /@var{localbin}/mkmodules CVSROOT modules
+@end example
+
+@noindent
+This defines the name @samp{modules} as the module name
+for the file itself, so that you can use
+
+@example
+$ cvs checkout modules
+@end example
+
+@noindent
+to get a copy of the file that you can edit. You should define
+similar module entries for the other configuration
+files described in this appendix, except
+@file{history}).
+
+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.
+
+A module definition is a single line of the
+@file{modules} file, in either of two formats. In both
+cases, @var{mname} represents the symbolic module name,
+and the remainder of the line is its definition.
+
+@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.
+
+@item @var{mname} [ options ] @var{dir} [ @var{files}@dots{} ] [ &@var{module}@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.
+
+By explicitly specifying files in the module definition
+after @var{dir}, you can select particular files from
+directory @var{dir}. The sample definition for
+@samp{modules} is an example of a module defined with a
+single file from a particular directory. Here is
+another example:
+
+@example
+m4test unsupported/gnu/m4 foreach.m4 forloop.m4
+@end example
+
+@noindent
+With this definition, executing @samp{cvs checkout
+m4test} will create a single working directory
+@file{m4test} containing the two files listed, which
+both come from a common directory several levels deep
+in the @sc{cvs} source repository.
+
+A module definition can refer to other modules by
+including @samp{&@var{module}} in its definition.
+@code{checkout} creates a subdirectory for each such
+module, in your working directory.
+@c -- Nope. "in your working directory" is wrong. What
+@c -- is right?
+
+@table @code
+@item -d @var{name}
+Name the working directory something other than the
+module name.
+
+@cindex Checkin program
+@item -i @var{prog}
+Specify a program @var{prog} to run whenever files in a
+module are committed. @var{prog} runs with a single
+argument, the full pathname of the affected directory
+in a source repository. The @file{commitinfo},
+@file{loginfo}, and @file{editinfo} files provide other
+ways to call a program on commit.
+
+@cindex Checkout program
+@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.
+
+@cindex Status of a module
+@cindex Module status
+@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
+@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}. There is no way to
+specify a program to run when @code{tag} is executed.
+
+@cindex Update program
+@item -u @var{prog}
+Specify a program @var{prog} to run whenever @samp{cvs
+update} is executed from the top-level directory of the
+checked-out module. @var{prog} runs with a single
+argument, the full path to the source repository for
+this module.
+@end table
+@end table
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node commit files
+@appendixsec The commit support files
+@cindex Commit 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 kind 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.
+
+@item editinfo
+The specified program is used to edit 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}).
+
+@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!
+@end table
+
+@menu
+* syntax:: The common syntax
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node syntax
+@appendixsubsec The common syntax
+@cindex Info files (syntax)
+@cindex Syntax of info files
+@cindex Common syntax of info files
+
+The four files @file{commitinfo}, @file{loginfo},
+@file{rcsinfo} and @file{editinfo} all have a common
+format. The purpose of the files are described later
+on. The common syntax is described here.
+
+Each line contains the following:
+@itemize @bullet
+@item
+A regular expression
+
+@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.
+
+Whenever one of the regular expressions matches a
+directory name in the repository, the rest of the line
+is used.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node commitinfo
+@appendixsec Commitinfo
+@cindex Commitinfo
+@cindex Checking commits
+@cindex Precommit checking
+
+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.
+
+As mentioned earlier, each line in the
+@file{commitinfo} file consists of a regular expression
+and a command-line template. The template can include
+a program name and any number of arguments you wish to
+supply to it. The full path to the current source
+repository is appended to the template, followed by the
+file names of any files involved in the commit (added,
+removed, and modified files).
+
+All lines with a regular expression matching the
+relative path to the module will be used. If any of
+the commands return a non-zero exit status the commit
+will be aborted.
+
+@cindex DEFAULT in commitinfo
+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.
+
+@cindex ALL in commitinfo
+If the name @samp{ALL} appears as a regular expression
+it is always used in addition to any matching regular
+expression or @samp{DEFAULT}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node editinfo
+@appendixsec Editinfo
+@cindex Editinfo
+@cindex Editor, specifying per module
+@cindex Per-module editor
+@cindex Log messages, editing
+
+If you want to make sure that all log messages look the
+same way, you can use the @file{editinfo} file to
+specify a program that is used to edit the log message.
+This program could be a custom-made editor that always
+enforces a certain style of the log message, or maybe a
+simple shell script that calls an editor, and checks
+that the entered message contains the required fields.
+
+If no matching line is found in the @file{editinfo}
+file, the editor specified in the environment variable
+@code{$CVSEDITOR} is used instead. If that variable is
+not set, then the environment variable @code{$EDITOR}
+is used instead. If that variable is not
+set a precompiled default, normally @code{vi}, will be
+used.
+
+The @file{editinfo} file is often most useful together
+with the @file{rcsinfo} file, which can be used to
+specify a log message template.
+
+Each line in the @file{editinfo} file consists of a
+regular expression and a command-line template. The template must
+include a program name, and can include any number of
+arguments. The full path to the current log message
+template file is appended to the template.
+
+One thing that should be noted is that the ALL keyword
+is not supported. If more than one matching line is
+found, the last one is used. This can be useful for
+specifying a default edit script in a module, and then
+overriding it in a subdirectory.
+
+If the edit script exits with a non-zero exit status,
+the commit is aborted.
+
+@menu
+* editinfo example:: Editinfo example
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node editinfo example
+@appendixsubsec Editinfo example
+
+The following is a little silly example of a
+@file{editinfo} file, together with the corresponding
+@file{rcsinfo} file, the log message template and an
+editor 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.edit} is used to
+edit the log message.
+
+@example
+#!/bin/sh
+#
+# bugid.edit filename
+#
+# Call $EDITOR on FILENAME, and verify that the
+# resulting file contains a valid bugid on the first
+# line.
+if [ "x$EDITOR" = "x" ]; then EDITOR=vi; fi
+if [ "x$CVSEDITOR" = "x" ]; then CVSEDITOR=$EDITOR; fi
+$CVSEDITOR $1
+until head -1|grep '^BugId:[ ]*[0-9][0-9]*$' < $1
+do echo -n "No BugId found. Edit again? ([y]/n)"
+ read ans
+ case $@{ans@} in
+ n*) exit 1;;
+ esac
+ $CVSEDITOR $1
+done
+@end example
+
+The @file{editinfo} file contains this line:
+
+@example
+^tc /usr/cvssupport/bugid.edit
+@end example
+
+The @file{rcsinfo} file contains this line:
+
+@example
+^tc /usr/cvssupport/tc.template
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node loginfo
+@appendixsec Loginfo
+@cindex Loginfo
+@cindex Storing log messages
+@cindex Mailing log messages
+@cindex Distributing log messages
+@cindex Log messages
+
+The @file{loginfo} file is used to control where
+@samp{cvs commit} log information is sent. The first
+entry on a line is a regular expression which is tested
+against the directory that the change is being made to,
+relative to the @code{$CVSROOT}. If a match is found, then
+the remainder of the line is a filter program that
+should expect log information on its standard input.
+
+The filter program may use one and only one % modifier
+(a la printf). If @samp{%s} is specified in the filter
+program, a brief title is included (enclosed in single
+quotes) showing the modified file names.
+
+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.
+
+If the name @samp{ALL} appears as a regular expression
+it is always used in addition to any matching regular expression or
+@samp{DEFAULT}.
+
+All matching regular expressions are used.
+
+@xref{commit files}, for a description of the syntax of
+the @file{loginfo} file.
+
+@menu
+* loginfo example:: Loginfo example
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node loginfo example
+@appendixsubsec 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} and mailed to @t{ceder}.
+
+@example
+ALL /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog
+^CVSROOT Mail -s %s ceder
+^CVSROOT /usr/local/bin/cvs-log /usr/adm/cvsroot-log
+@end example
+
+The shell-script @file{/usr/local/bin/cvs-log} looks
+like this:
+
+@example
+#!/bin/sh
+(echo "-----------------------------------------------------------------";
+ echo -n $USER" ";
+ date;
+ echo;
+ sed '1s+'$@{CVSROOT@}'++') >> $1
+@end example
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node rcsinfo
+@appendixsec Rcsinfo
+@cindex Rcsinfo
+@cindex Form for log message
+@cindex Log message template
+@cindex Template for log message
+
+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{editinfo}, @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.
+
+If the name @samp{ALL} appears as a regular expression
+it is always used in addition to the first matching
+regular expression or @samp{DEFAULT}.
+
+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{editinfo example}, for an example @file{rcsinfo}
+file.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node cvsignore
+@appendixsec Ignoring files via cvsignore
+@cindex Cvsignore, 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 the following file name
+patterns:
+
+@cindex Ignored files
+@cindex Automatically ignored files
+@example
+ RCSLOG RCS SCCS
+ CVS* cvslog.*
+ tags TAGS
+ .make.state .nse_depinfo
+ *~ #* .#* ,*
+ *.old *.bak *.BAK *.orig *.rej .del-*
+ *.a *.o *.so *.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}.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node history file
+@appendixsec The history file
+@cindex History file
+@cindex Log information, saving
+
+The file @file{$CVSROOT/CVSROOT/history} is used
+to log information for the @code{history} command
+(@pxref{history}). This file must be created to turn
+on logging. This is done automatically if the
+@code{cvsinit} script is used to set up the repository.
+
+The file format of the @file{history} file is
+unfortunately not yet documented anywhere, but it is
+fairly easy to understand most of it.
+@c -- document it here?
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Setting up
+@appendixsec Setting up the repository
+@cindex Repository, setting up
+@cindex Creating a repository
+@cindex Setting up a repository
+
+When you install @sc{cvs} for the first time, you should
+follow the instructions in the @file{INSTALL} file to
+set up the repository.
+
+If you want to set up another repository, the easiest
+way to get a reasonable set of working administrative
+files is to get the source to @sc{cvs}, and run the
+@code{cvsinit} shell script. It will set up an empty
+repository in the directory defined by the environment
+variable @code{$CVSROOT}. (@code{cvsinit} is careful to
+never overwrite any existing files in the repository,
+so no harm is done if you run @code{cvsinit} on
+an already set-up repository.)
+
+@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}.
+
+@table @code
+@cindex CVSIGNORE
+@item $CVSIGNORE
+A whitespace-separated list of file name patterns that
+@sc{cvs} should ignore. @xref{cvsignore}.
+
+@cindex 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 CVSROOT
+@item $CVSROOT
+Should contain the full pathname to the root of the @sc{cvs}
+source repository (where the @sc{rcs} history 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{}} You may not need to set
+@code{$CVSROOT} if your @sc{cvs} binary has the right path
+compiled in.
+
+If your site has several repositories, you must be
+careful to set @code{$CVSROOT} to the appropriate one
+when you use @sc{cvs}, even if you just run @samp{cvs
+update} inside an already checked-out module. Future
+releases of @sc{cvs} will probably store information about
+which repository the module came from inside the
+@file{CVS} directory, but version 1.3 relies totally on
+@code{$CVSROOT}.
+
+@cindex EDITOR
+@cindex CVSEDITOR
+@item $EDITOR
+@itemx $CVSEDITOR
+Specifies the program to use for recording log messages
+during commit. If not set, the default is
+@samp{/usr/ucb/vi}. @code{$CVSEDITOR} overrides
+@code{$EDITOR}. @code{$CVSEDITOR} does not exist in
+@sc{cvs} 1.3, but the next release will probably
+include it.
+
+@cindex PATH
+@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 RCSBIN
+@item $RCSBIN
+Specifies the full pathname of the location of @sc{rcs} programs,
+such as co(1) and ci(1). If not set, a compiled-in
+value is used, or your @code{$PATH} is searched.
+@end table
+
+@sc{cvs} is a front-end to @sc{rcs}. The following environment
+variables affect @sc{rcs}:
+
+@table @code
+@cindex LOGNAME
+@item $LOGNAME
+@cindex USER
+@itemx $USER
+If set, they affect who @sc{rcs} thinks you are. If you
+have trouble checking in files it might be because your
+login name differs from the setting of e.g.
+@code{$LOGNAME}.
+
+@cindex RCSINIT
+@item $RCSINIT
+Options prepended to the argument list, separated by
+spaces. A backslash escapes spaces within an option.
+The @code{$RCSINIT} options are prepended to the
+argument lists of most @sc{rcs} commands.
+
+@cindex TMPDIR
+@item $TMPDIR
+@cindex TMP
+@itemx $TMP
+@cindex TEMP
+@itemx $TEMP
+Name of the temporary directory. The environment
+variables are inspected in the order they appear above
+and the first value found is taken; if none of them are
+set, a host-dependent default is used, typically
+@file{/tmp}.
+@end table
+
+@c ---------------------------------------------------------------------
+@node Troubleshooting
+@appendix Troubleshooting
+
+@menu
+* Magic branch numbers:: Magic branch numbers
+@end menu
+
+@ignore
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@c @node Bad administrative files
+@appendixsec Bad administrative files
+
+@c -- Give hints on how to fix them
+@end ignore
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Magic branch numbers
+@appendixsec Magic branch numbers
+
+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.3 becomes
+1.2.0.3, 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 at least four places the
+hiding is incomplete.
+
+@itemize @bullet
+@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.
+
+@item
+The magic branch number appears in the output from
+@code{cvs log}. This is much harder to fix, since
+@code{cvs log} runs @code{rlog} (which is part of the
+@sc{rcs} distribution), and modifying @code{rlog} to
+know about magic branches would probably break someone's
+habits (if they use branch 0 for their own purposes).
+
+@item
+You cannot specify a symbolic branch name to @code{cvs log}.
+
+@item
+You cannot specify a symbolic branch name to @code{cvs
+admin}.
+
+@end itemize
+
+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 Copying
+@appendix GNU GENERAL PUBLIC LICENSE
+@c @include gpl.texinfo
+
+@c ---------------------------------------------------------------------
+@node Index
+@unnumbered Index
+@cindex Index
+
+If you cannot find what you are looking for here write
+to <@t{ceder@@signum.se}> so that an entry can be added
+to the next release of this manual.
+
+@printindex cp
+
+@summarycontents
+
+@contents
+
+@bye
+
+Local Variables:
+fill-column: 55
+End:
diff --git a/gnu/usr.bin/cvs/lib/config.h b/gnu/usr.bin/cvs/lib/config.h
new file mode 100644
index 0000000..cd1b857
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/config.h
@@ -0,0 +1,133 @@
+/* config.h. Generated automatically by configure. */
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define if type char is unsigned and you are not using gcc. */
+/* #undef __CHAR_UNSIGNED__ */
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you support file names longer than 14 characters. */
+#define HAVE_LONG_FILE_NAMES 1
+
+/* Define if utime(file, NULL) sets file's timestamp to the present. */
+#define HAVE_UTIME_NULL 1
+
+/* Define if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef mode_t */
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if your <sys/time.h> declares struct tm. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+/* Define if you have the fchmod function. */
+#define HAVE_FCHMOD 1
+
+/* Define if you have the fsync function. */
+#define HAVE_FSYNC 1
+
+/* Define if you have the ftime function. */
+/* #undef HAVE_FTIME */
+
+/* Define if you have the ftruncate function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define if you have the mkfifo function. */
+#define HAVE_MKFIFO 1
+
+/* Define if you have the putenv function. */
+#define HAVE_PUTENV 1
+
+/* Define if you have the setvbuf function. */
+#define HAVE_SETVBUF 1
+
+/* Define if you have the vfork function. */
+#define HAVE_VFORK 1
+
+/* Define if you have the vprintf function. */
+#define HAVE_VPRINTF 1
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <ndbm.h> header file. */
+#define HAVE_NDBM_H 1
+
+/* Define if you have the <ndir.h> header file. */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file. */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file. */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the <sys/timeb.h> header file. */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
diff --git a/gnu/usr.bin/cvs/lib/hostname.c b/gnu/usr.bin/cvs/lib/hostname.c
new file mode 100644
index 0000000..34be15e
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/hostname.c
@@ -0,0 +1,49 @@
+/* hostname.c -- use uname() to get the name of the host
+ Copyright (C) 1992 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(STDC_HEADERS) || defined(USG)
+#include <string.h>
+#ifndef index
+#define index strchr
+#endif
+#else
+#include <strings.h>
+#endif
+
+#include <sys/utsname.h>
+
+/* Put this host's name into NAME, using at most NAMELEN characters */
+
+int
+gethostname(name, namelen)
+ char *name;
+ int namelen;
+{
+ struct utsname ugnm;
+
+ if (uname(&ugnm) < 0)
+ return (-1);
+
+ (void) strncpy(name, ugnm.nodename, namelen-1);
+ name[namelen-1] = '\0';
+
+ return (0);
+}
diff --git a/gnu/usr.bin/cvs/lib/memmove.c b/gnu/usr.bin/cvs/lib/memmove.c
new file mode 100644
index 0000000..8818d46
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/memmove.c
@@ -0,0 +1,57 @@
+/* memmove -- copy memory regions of arbitary length
+ Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+
+/*
+
+NAME
+
+ memmove -- copy memory regions of arbitary length
+
+SYNOPSIS
+
+ void memmove (void *out, const void *in, size_t n);
+
+DESCRIPTION
+
+ Copy LENGTH bytes from memory region pointed to by IN to memory
+ region pointed to by OUT.
+
+ Regions can be overlapping.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+void *
+memmove (out, in, length)
+ void *out;
+ const void* in;
+ size_t length;
+{
+ bcopy(in, out, length);
+ return out;
+}
diff --git a/gnu/usr.bin/cvs/lib/strerror.c b/gnu/usr.bin/cvs/lib/strerror.c
new file mode 100644
index 0000000..b0bec13
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/strerror.c
@@ -0,0 +1,813 @@
+/* Extended support for using errno values.
+ Copyright (C) 1992 Free Software Foundation, Inc.
+ Written by Fred Fish. fnf@cygnus.com
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#ifndef NEED_sys_errlist
+/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
+ might declare sys_errlist in a way that the compiler might consider
+ incompatible with our later declaration, perhaps by using const
+ attributes. So we hide the declaration in errno.h (if any) using a
+ macro. */
+#define sys_errlist sys_errlist__
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+
+#ifndef NEED_sys_errlist
+#undef sys_errlist
+#endif
+
+/* Routines imported from standard C runtime libraries. */
+
+#ifdef __STDC__
+#include <stddef.h>
+extern void *malloc (size_t size); /* 4.10.3.3 */
+extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */
+#else /* !__STDC__ */
+extern char *malloc (); /* Standard memory allocater */
+extern char *memset ();
+#endif /* __STDC__ */
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+/* Translation table for errno values. See intro(2) in most UNIX systems
+ Programmers Reference Manuals.
+
+ Note that this table is generally only accessed when it is used at runtime
+ to initialize errno name and message tables that are indexed by errno
+ value.
+
+ Not all of these errnos will exist on all systems. This table is the only
+ thing that should have to be updated as new error numbers are introduced.
+ It's sort of ugly, but at least its portable. */
+
+struct error_info
+{
+ int value; /* The numeric value from <errno.h> */
+ char *name; /* The equivalent symbolic value */
+#ifdef NEED_sys_errlist
+ char *msg; /* Short message about this value */
+#endif
+};
+
+#ifdef NEED_sys_errlist
+# define ENTRY(value, name, msg) {value, name, msg}
+#else
+# define ENTRY(value, name, msg) {value, name}
+#endif
+
+static const struct error_info error_table[] =
+{
+#if defined (EPERM)
+ ENTRY(EPERM, "EPERM", "Not owner"),
+#endif
+#if defined (ENOENT)
+ ENTRY(ENOENT, "ENOENT", "No such file or directory"),
+#endif
+#if defined (ESRCH)
+ ENTRY(ESRCH, "ESRCH", "No such process"),
+#endif
+#if defined (EINTR)
+ ENTRY(EINTR, "EINTR", "Interrupted system call"),
+#endif
+#if defined (EIO)
+ ENTRY(EIO, "EIO", "I/O error"),
+#endif
+#if defined (ENXIO)
+ ENTRY(ENXIO, "ENXIO", "No such device or address"),
+#endif
+#if defined (E2BIG)
+ ENTRY(E2BIG, "E2BIG", "Arg list too long"),
+#endif
+#if defined (ENOEXEC)
+ ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
+#endif
+#if defined (EBADF)
+ ENTRY(EBADF, "EBADF", "Bad file number"),
+#endif
+#if defined (ECHILD)
+ ENTRY(ECHILD, "ECHILD", "No child processes"),
+#endif
+#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
+ ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
+#endif
+#if defined (EAGAIN)
+ ENTRY(EAGAIN, "EAGAIN", "No more processes"),
+#endif
+#if defined (ENOMEM)
+ ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
+#endif
+#if defined (EACCES)
+ ENTRY(EACCES, "EACCES", "Permission denied"),
+#endif
+#if defined (EFAULT)
+ ENTRY(EFAULT, "EFAULT", "Bad address"),
+#endif
+#if defined (ENOTBLK)
+ ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
+#endif
+#if defined (EBUSY)
+ ENTRY(EBUSY, "EBUSY", "Device busy"),
+#endif
+#if defined (EEXIST)
+ ENTRY(EEXIST, "EEXIST", "File exists"),
+#endif
+#if defined (EXDEV)
+ ENTRY(EXDEV, "EXDEV", "Cross-device link"),
+#endif
+#if defined (ENODEV)
+ ENTRY(ENODEV, "ENODEV", "No such device"),
+#endif
+#if defined (ENOTDIR)
+ ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
+#endif
+#if defined (EISDIR)
+ ENTRY(EISDIR, "EISDIR", "Is a directory"),
+#endif
+#if defined (EINVAL)
+ ENTRY(EINVAL, "EINVAL", "Invalid argument"),
+#endif
+#if defined (ENFILE)
+ ENTRY(ENFILE, "ENFILE", "File table overflow"),
+#endif
+#if defined (EMFILE)
+ ENTRY(EMFILE, "EMFILE", "Too many open files"),
+#endif
+#if defined (ENOTTY)
+ ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
+#endif
+#if defined (ETXTBSY)
+ ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
+#endif
+#if defined (EFBIG)
+ ENTRY(EFBIG, "EFBIG", "File too large"),
+#endif
+#if defined (ENOSPC)
+ ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
+#endif
+#if defined (ESPIPE)
+ ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
+#endif
+#if defined (EROFS)
+ ENTRY(EROFS, "EROFS", "Read-only file system"),
+#endif
+#if defined (EMLINK)
+ ENTRY(EMLINK, "EMLINK", "Too many links"),
+#endif
+#if defined (EPIPE)
+ ENTRY(EPIPE, "EPIPE", "Broken pipe"),
+#endif
+#if defined (EDOM)
+ ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
+#endif
+#if defined (ERANGE)
+ ENTRY(ERANGE, "ERANGE", "Math result not representable"),
+#endif
+#if defined (ENOMSG)
+ ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
+#endif
+#if defined (EIDRM)
+ ENTRY(EIDRM, "EIDRM", "Identifier removed"),
+#endif
+#if defined (ECHRNG)
+ ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
+#endif
+#if defined (EL2NSYNC)
+ ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
+#endif
+#if defined (EL3HLT)
+ ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
+#endif
+#if defined (EL3RST)
+ ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
+#endif
+#if defined (ELNRNG)
+ ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
+#endif
+#if defined (EUNATCH)
+ ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
+#endif
+#if defined (ENOCSI)
+ ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
+#endif
+#if defined (EL2HLT)
+ ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
+#endif
+#if defined (EDEADLK)
+ ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
+#endif
+#if defined (ENOLCK)
+ ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
+#endif
+#if defined (EBADE)
+ ENTRY(EBADE, "EBADE", "Invalid exchange"),
+#endif
+#if defined (EBADR)
+ ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
+#endif
+#if defined (EXFULL)
+ ENTRY(EXFULL, "EXFULL", "Exchange full"),
+#endif
+#if defined (ENOANO)
+ ENTRY(ENOANO, "ENOANO", "No anode"),
+#endif
+#if defined (EBADRQC)
+ ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
+#endif
+#if defined (EBADSLT)
+ ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
+#endif
+#if defined (EDEADLOCK)
+ ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
+#endif
+#if defined (EBFONT)
+ ENTRY(EBFONT, "EBFONT", "Bad font file format"),
+#endif
+#if defined (ENOSTR)
+ ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
+#endif
+#if defined (ENODATA)
+ ENTRY(ENODATA, "ENODATA", "No data available"),
+#endif
+#if defined (ETIME)
+ ENTRY(ETIME, "ETIME", "Timer expired"),
+#endif
+#if defined (ENOSR)
+ ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
+#endif
+#if defined (ENONET)
+ ENTRY(ENONET, "ENONET", "Machine is not on the network"),
+#endif
+#if defined (ENOPKG)
+ ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
+#endif
+#if defined (EREMOTE)
+ ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
+#endif
+#if defined (ENOLINK)
+ ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
+#endif
+#if defined (EADV)
+ ENTRY(EADV, "EADV", "Advertise error"),
+#endif
+#if defined (ESRMNT)
+ ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
+#endif
+#if defined (ECOMM)
+ ENTRY(ECOMM, "ECOMM", "Communication error on send"),
+#endif
+#if defined (EPROTO)
+ ENTRY(EPROTO, "EPROTO", "Protocol error"),
+#endif
+#if defined (EMULTIHOP)
+ ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
+#endif
+#if defined (EDOTDOT)
+ ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
+#endif
+#if defined (EBADMSG)
+ ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
+#endif
+#if defined (ENAMETOOLONG)
+ ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
+#endif
+#if defined (EOVERFLOW)
+ ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
+#endif
+#if defined (ENOTUNIQ)
+ ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
+#endif
+#if defined (EBADFD)
+ ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
+#endif
+#if defined (EREMCHG)
+ ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
+#endif
+#if defined (ELIBACC)
+ ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"),
+#endif
+#if defined (ELIBBAD)
+ ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
+#endif
+#if defined (ELIBSCN)
+ ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
+#endif
+#if defined (ELIBMAX)
+ ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
+#endif
+#if defined (ELIBEXEC)
+ ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
+#endif
+#if defined (EILSEQ)
+ ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
+#endif
+#if defined (ENOSYS)
+ ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
+#endif
+#if defined (ELOOP)
+ ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
+#endif
+#if defined (ERESTART)
+ ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
+#endif
+#if defined (ESTRPIPE)
+ ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
+#endif
+#if defined (ENOTEMPTY)
+ ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
+#endif
+#if defined (EUSERS)
+ ENTRY(EUSERS, "EUSERS", "Too many users"),
+#endif
+#if defined (ENOTSOCK)
+ ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
+#endif
+#if defined (EDESTADDRREQ)
+ ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
+#endif
+#if defined (EMSGSIZE)
+ ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
+#endif
+#if defined (EPROTOTYPE)
+ ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
+#endif
+#if defined (ENOPROTOOPT)
+ ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"),
+#endif
+#if defined (EPROTONOSUPPORT)
+ ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
+#endif
+#if defined (ESOCKTNOSUPPORT)
+ ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
+#endif
+#if defined (EOPNOTSUPP)
+ ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
+#endif
+#if defined (EPFNOSUPPORT)
+ ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
+#endif
+#if defined (EAFNOSUPPORT)
+ ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
+#endif
+#if defined (EADDRINUSE)
+ ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
+#endif
+#if defined (EADDRNOTAVAIL)
+ ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
+#endif
+#if defined (ENETDOWN)
+ ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
+#endif
+#if defined (ENETUNREACH)
+ ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
+#endif
+#if defined (ENETRESET)
+ ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
+#endif
+#if defined (ECONNABORTED)
+ ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
+#endif
+#if defined (ECONNRESET)
+ ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
+#endif
+#if defined (ENOBUFS)
+ ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
+#endif
+#if defined (EISCONN)
+ ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
+#endif
+#if defined (ENOTCONN)
+ ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
+#endif
+#if defined (ESHUTDOWN)
+ ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
+#endif
+#if defined (ETOOMANYREFS)
+ ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
+#endif
+#if defined (ETIMEDOUT)
+ ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
+#endif
+#if defined (ECONNREFUSED)
+ ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
+#endif
+#if defined (EHOSTDOWN)
+ ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
+#endif
+#if defined (EHOSTUNREACH)
+ ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
+#endif
+#if defined (EALREADY)
+ ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
+#endif
+#if defined (EINPROGRESS)
+ ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
+#endif
+#if defined (ESTALE)
+ ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
+#endif
+#if defined (EUCLEAN)
+ ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
+#endif
+#if defined (ENOTNAM)
+ ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
+#endif
+#if defined (ENAVAIL)
+ ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
+#endif
+#if defined (EISNAM)
+ ENTRY(EISNAM, "EISNAM", "Is a named type file"),
+#endif
+#if defined (EREMOTEIO)
+ ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
+#endif
+ ENTRY(0, NULL, NULL)
+};
+
+/* Translation table allocated and initialized at runtime. Indexed by the
+ errno value to find the equivalent symbolic value. */
+
+static char **error_names;
+static int num_error_names = 0;
+
+/* Translation table allocated and initialized at runtime, if it does not
+ already exist in the host environment. Indexed by the errno value to find
+ the descriptive string.
+
+ We don't export it for use in other modules because even though it has the
+ same name, it differs from other implementations in that it is dynamically
+ initialized rather than statically initialized. */
+
+#ifdef NEED_sys_errlist
+
+static int sys_nerr;
+static char **sys_errlist;
+
+#else
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+#endif
+
+
+/*
+
+NAME
+
+ init_error_tables -- initialize the name and message tables
+
+SYNOPSIS
+
+ static void init_error_tables ();
+
+DESCRIPTION
+
+ Using the error_table, which is initialized at compile time, generate
+ the error_names and the sys_errlist (if needed) tables, which are
+ indexed at runtime by a specific errno value.
+
+BUGS
+
+ The initialization of the tables may fail under low memory conditions,
+ in which case we don't do anything particularly useful, but we don't
+ bomb either. Who knows, it might succeed at a later point if we free
+ some memory in the meantime. In any case, the other routines know
+ how to deal with lack of a table after trying to initialize it. This
+ may or may not be considered to be a bug, that we don't specifically
+ warn about this particular failure mode.
+
+*/
+
+static void
+init_error_tables ()
+{
+ const struct error_info *eip;
+ int nbytes;
+
+ /* If we haven't already scanned the error_table once to find the maximum
+ errno value, then go find it now. */
+
+ if (num_error_names == 0)
+ {
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ if (eip -> value >= num_error_names)
+ {
+ num_error_names = eip -> value + 1;
+ }
+ }
+ }
+
+ /* Now attempt to allocate the error_names table, zero it out, and then
+ initialize it from the statically initialized error_table. */
+
+ if (error_names == NULL)
+ {
+ nbytes = num_error_names * sizeof (char *);
+ if ((error_names = (char **) malloc (nbytes)) != NULL)
+ {
+ memset (error_names, 0, nbytes);
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ error_names[eip -> value] = eip -> name;
+ }
+ }
+ }
+
+#ifdef NEED_sys_errlist
+
+ /* Now attempt to allocate the sys_errlist table, zero it out, and then
+ initialize it from the statically initialized error_table. */
+
+ if (sys_errlist == NULL)
+ {
+ nbytes = num_error_names * sizeof (char *);
+ if ((sys_errlist = (char **) malloc (nbytes)) != NULL)
+ {
+ memset (sys_errlist, 0, nbytes);
+ sys_nerr = num_error_names;
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ sys_errlist[eip -> value] = eip -> msg;
+ }
+ }
+ }
+
+#endif
+
+}
+
+/*
+
+NAME
+
+ errno_max -- return the max errno value
+
+SYNOPSIS
+
+ int errno_max ();
+
+DESCRIPTION
+
+ Returns the maximum errno value for which a corresponding symbolic
+ name or message is available. Note that in the case where
+ we use the sys_errlist supplied by the system, it is possible for
+ there to be more symbolic names than messages, or vice versa.
+ In fact, the manual page for perror(3C) explicitly warns that one
+ should check the size of the table (sys_nerr) before indexing it,
+ since new error codes may be added to the system before they are
+ added to the table. Thus sys_nerr might be smaller than value
+ implied by the largest errno value defined in <errno.h>.
+
+ We return the maximum value that can be used to obtain a meaningful
+ symbolic name or message.
+
+*/
+
+int
+errno_max ()
+{
+ int maxsize;
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+ maxsize = MAX (sys_nerr, num_error_names);
+ return (maxsize - 1);
+}
+
+/*
+
+NAME
+
+ strerror -- map an error number to an error message string
+
+SYNOPSIS
+
+ char *strerror (int errnoval)
+
+DESCRIPTION
+
+ Maps an errno number to an error message string, the contents of
+ which are implementation defined. On systems which have the external
+ variables sys_nerr and sys_errlist, these strings will be the same
+ as the ones used by perror().
+
+ If the supplied error number is within the valid range of indices
+ for the sys_errlist, but no message is available for the particular
+ error number, then returns the string "Error NUM", where NUM is the
+ error number.
+
+ If the supplied error number is not a valid index into sys_errlist,
+ returns NULL.
+
+ The returned string is only guaranteed to be valid only until the
+ next call to strerror.
+
+*/
+
+char *
+strerror (errnoval)
+ int errnoval;
+{
+ char *msg;
+ static char buf[32];
+
+#ifdef NEED_sys_errlist
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+
+#endif
+
+ if ((errnoval < 0) || (errnoval >= sys_nerr))
+ {
+ /* Out of range, just return NULL */
+ msg = NULL;
+ }
+ else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
+ {
+ /* In range, but no sys_errlist or no entry at this index. */
+ sprintf (buf, "Error %d", errnoval);
+ msg = buf;
+ }
+ else
+ {
+ /* In range, and a valid message. Just return the message. */
+ msg = sys_errlist[errnoval];
+ }
+
+ return (msg);
+}
+
+
+
+/*
+
+NAME
+
+ strerrno -- map an error number to a symbolic name string
+
+SYNOPSIS
+
+ char *strerrno (int errnoval)
+
+DESCRIPTION
+
+ Given an error number returned from a system call (typically
+ returned in errno), returns a pointer to a string containing the
+ symbolic name of that error number, as found in <errno.h>.
+
+ If the supplied error number is within the valid range of indices
+ for symbolic names, but no name is available for the particular
+ error number, then returns the string "Error NUM", where NUM is
+ the error number.
+
+ If the supplied error number is not within the range of valid
+ indices, then returns NULL.
+
+BUGS
+
+ The contents of the location pointed to are only guaranteed to be
+ valid until the next call to strerrno.
+
+*/
+
+char *
+strerrno (errnoval)
+ int errnoval;
+{
+ char *name;
+ static char buf[32];
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+
+ if ((errnoval < 0) || (errnoval >= num_error_names))
+ {
+ /* Out of range, just return NULL */
+ name = NULL;
+ }
+ else if ((error_names == NULL) || (error_names[errnoval] == NULL))
+ {
+ /* In range, but no error_names or no entry at this index. */
+ sprintf (buf, "Error %d", errnoval);
+ name = buf;
+ }
+ else
+ {
+ /* In range, and a valid name. Just return the name. */
+ name = error_names[errnoval];
+ }
+
+ return (name);
+}
+
+/*
+
+NAME
+
+ strtoerrno -- map a symbolic errno name to a numeric value
+
+SYNOPSIS
+
+ int strtoerrno (char *name)
+
+DESCRIPTION
+
+ Given the symbolic name of a error number, map it to an errno value.
+ If no translation is found, returns 0.
+
+*/
+
+int
+strtoerrno (name)
+ char *name;
+{
+ int errnoval = 0;
+
+ if (name != NULL)
+ {
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+ for (errnoval = 0; errnoval < num_error_names; errnoval++)
+ {
+ if ((error_names[errnoval] != NULL) &&
+ (strcmp (name, error_names[errnoval]) == 0))
+ {
+ break;
+ }
+ }
+ if (errnoval == num_error_names)
+ {
+ errnoval = 0;
+ }
+ }
+ return (errnoval);
+}
+
+
+/* A simple little main that does nothing but print all the errno translations
+ if MAIN is defined and this file is compiled and linked. */
+
+#ifdef MAIN
+
+main ()
+{
+ int errn;
+ int errnmax;
+ char *name;
+ char *msg;
+ char *strerrno ();
+ char *strerror ();
+
+ errnmax = errno_max ();
+ printf ("%d entries in names table.\n", num_error_names);
+ printf ("%d entries in messages table.\n", sys_nerr);
+ printf ("%d is max useful index.\n", errnmax);
+
+ /* Keep printing values until we get to the end of *both* tables, not
+ *either* table. Note that knowing the maximum useful index does *not*
+ relieve us of the responsibility of testing the return pointer for
+ NULL. */
+
+ for (errn = 0; errn <= errnmax; errn++)
+ {
+ name = strerrno (errn);
+ name = (name == NULL) ? "<NULL>" : name;
+ msg = strerror (errn);
+ msg = (msg == NULL) ? "<NULL>" : msg;
+ printf ("%-4d%-18s%s\n", errn, name, msg);
+ }
+}
+
+#endif
diff --git a/gnu/usr.bin/cvs/lib/version.c b/gnu/usr.bin/cvs/lib/version.c
new file mode 100644
index 0000000..071b112
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/version.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 1994 david d `zoo' zuhn
+ * Copyright (c) 1994 Free Software Foundation, Inc.
+ * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (c) 1989-1992, Brian Berliner
+ *
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with this CVS source distribution.
+ *
+ * version.c - the CVS version number
+ */
+
+#include "cvs.h"
+
+#ifndef lint
+static char rcsid[] = "$CVSid: @(#)version.c 1.15 94/10/03 $";
+USE(rcsid)
+#endif
+
+char *version_string = "\nConcurrent Versions System (CVS) 1.4 Alpha-2\n";
OpenPOWER on IntegriCloud