diff options
author | nate <nate@FreeBSD.org> | 1995-03-31 07:45:34 +0000 |
---|---|---|
committer | nate <nate@FreeBSD.org> | 1995-03-31 07:45:34 +0000 |
commit | be14a246dbdfdafe4e22e067d862ed30754d5139 (patch) | |
tree | 76b9e6d63661acd2c9a59057133e3b9a1c98e286 | |
parent | 07c952b4808f6d2d72179e048c5b6b8ce43d8041 (diff) | |
parent | 97dcd3ee2c52c29f7f4f4ad1a792395166114f77 (diff) | |
download | FreeBSD-src-be14a246dbdfdafe4e22e067d862ed30754d5139.zip FreeBSD-src-be14a246dbdfdafe4e22e067d862ed30754d5139.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r7516,
which included commits to RCS files with non-trunk default branches.
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"; |