Archive-name: cvs-faq
Hand Revision: 3.5 <<== Include this in your comments
Last Updated: 1995/03/09
$Revision: 1.3 $
$Date: 1995/06/28 02:13:47 $
===========================================================================
== 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:
Although an 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
Major revisions contain enough alterations to render change markers
meaningless. (Major revisions are those with a final digit of '0',
such as 2.0 or 3.0.) To help readers of previous versions of this
document, minor revisions will be annotated:
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.
Trivial changes, such as question reordering or spelling and grammar
corrections are not marked. Deleted questions will simply disappear,
as will any question that can be answered by "get the latest release".
Editorial comments are delimited by pairs of "[[" & "]]". They
contain either references to the (usually unfinished) nature of the
FAQ entry itself, version-specific comments to be removed (or
altered) when new revisions of CVS are released or snide remarks from
the editor.
If you plan to do anything with this document other than:
- Read it.
- Redistribute the whole document along with the date and revision.
- Post sections as answers to CVS questions (as long as you
identify it as coming from the FAQ.)
talk to the author first.
============================================
== 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 and Merging
D. Tricks of the Trade
E. Internal errors
F. Related Software
G. Engineering
H. Other Systems
5. Past & Future
A. Contributors.
B. Bugs and Patches
C. Development
D. Professional Support
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.4.
============================================
== 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?
**** 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 source changes 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 saves its version-control information in RCS files stored 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 a "checkout" command, handing it a
module name or directory path (relative to the $CVSROOT variable)
you want to work on. CVS copies the latest revision of each file
in the specified module or directory out of the Repository and
into a directory tree created in your current directory. You may
specify a particular branch to work on by symbolic name if you
don't want to work on the default (main or trunk) branch.
You may then modify files in the new directory tree, build them
into output files and test 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" produces 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 handle source control for files in three major
situations:
1. Multiple developers working on the same files.
The major advantage of using CVS over the 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 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. Tracking a stream of releases from a source vendor.
If you are making changes to sources distributed by someone
else, the CVS feature, called the Vendor Branch, allows you to
combine local modifications with repeated 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 may require work.
(e.g. GNU programs, X, CVS itself, etc.)
3. Branching development.
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.)
CVS's branch support is a bit primitive, but it was designed to
allow you to create branches, work on them for while and merge
them back into the main line of development. You should also
be able to merge work performed on the main branch into the
branch you are working on. 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. a tree of 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 require your Makefiles or build
procedures 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 use CVS to maintain the tools created to
support such a build system (scripts, Makefiles, etc).
CVS is not a substitute for management.
You and your project leaders are expected to plan what you are
doing. Everyone involved must be aware of schedules, merge
points, branch names, release dates and the range of
procedures needed to build products. (If you produce it and
someone else uses it, it is a product.) CVS can't cover for a
failure to manage your project.
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 command into dropping
conflict markers into the merged file.
CVS is not capable of figuring out distributed conflicts in
program logic. For example, if you change the arguments to
function X defined in file A and, at the same time, edit 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.
----------------
-- 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 files out of the archive if I don't have FTP?
1B.4 How do I get a copy of the latest version of CVS?
1B.5 Is there a mailing list devoted to CVS? How do I find it?
1B.6 What happened to the CVS Usenet newsgroup I heard about?
**** Answers:
1B.1 How do I get more information about CVS?
1. The first thing I would do is to read the Info file that comes
with the CVS sources under "doc". You can format and read the
cvs.texinfo file in two ways: 1. Use TeX to format it and a
"dvips" command to print it and 2. Install the cvs.info files
that are created by the Makefile and read them online using the
Emacs "info-mode" or a stand-alone "info" reader.
2. Then I'd run "cvsinit" to set up a Repository and read the man
page while trying out the commands.
Type "cvs -H" for general help or "cvs -H command" for
command-specific help.
3. For background, you can read the original CVS paper (in the
source tree, under "doc"). It describes the purpose of CVS and
some of how it was designed. Note that the emphasis of the
document (especially on multiple vendors providing the same
sources) is somewhat out of date.
4. For more detailed information about "internals", read the man
pages for RCS. If you are a programmer, you can also read the
source code to CVS.
5. Other information and tutorials may be available in the "doc"
directory of the FTP archive described below.
6. For current information, and a fair amount of detail, 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 extra documentation, patches
and a copy of the latest release.
ftp ftp.delos.com
>>> User: anonymous
>>> Passwd:
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.
A WWW home page is also available at http://www.delos.com/cvs.
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. FTPMAIL service is available from the same host as the FTP
server described above. Send mail to "[email protected]"
containing "help" in the body of the message. For example,
on most Unix systems, you can type:
echo help | Mail [email protected]
The FTPMAIL server will respond with a document describing how
to use the server. If the "Mail" command doesn't exist on your
system, try "mailx", "/usr/ucb/mail" or "/bin/mail".
2. If you are on BITNET, use Princeton's BITFTP server. Type
echo 'send help' | Mail [email protected]
(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.)
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
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 are
mirrors of the FSF archive on UUNET and other large Internet sites.
Program(s) Suggested revision
----------- -----------------------
CVS 1.4
RCS 5.6.0.1 (latest version available today)
GNU diff 2.7 (or later) [contained in diffutils-2.7]
GDBM 1.5 (or later) [optional]
The GNU version of diff is suggested by both the RCS and CVS
configuration instructions because it works better than the
standard version.
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 can probably afford.
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 a mailing list devoted to CVS? How do I find it?
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.
Throughout 1994, the list received an average of 100 messages per
month.
You can add yourself to the mailing list by sending an Email
message to:
[email protected]
(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:
[email protected]
An archive of the mailing list is maintained in the FTP archive
mentioned above.
1B.6 What happened to the CVS Usenet newsgroup I heard about?
A Usenet newsgroup named "gnu.cvs.info" was announced in April
1993, with an expected creation date of August, 1993.
As of this writing (October, 1994) it hasn't appeared.
If the newsgroup is ever created, it and the mailing list should
be bidirectionally gatewayed, meaning that you only need access to
one of them. Anything sent to the mailing list would be
automatically posted to "gnu.cvs.info" and anything posted to the
newsgroup would be automatically mailed to "info-cvs".
A newsgroup would be easier to use than a mailing list. If the
CVS newsgroup ever shows up, ask your system administrator whether
you get the "gnu" hierarchy. If so, select a news reader and dive
in.
----------------
-- 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/SparcWorks?
1C.5 How does CVS differ from Aegis?
1C.6 How does CVS differ from Shapetools?
1C.7 How does CVS differ from TeamNet?
1C.8 How does CVS differ from ProFrame?
1C.9 How does CVS differ from CaseWare/CM?
1C.10 How does CVS differ from Sublime?
1C.11 How does CVS differ from PVCS?
1C.12 How does CVS differ from CMVC?
**** 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
multiple files on the command line, but they are handled by
iterating over individual files. There is no pretense of
coordinated interaction among groups of 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 distributed client-server version control system.
ClearCase is a variant DSEE tools, formerly available on Apollo
platforms. The ClearCase tool set includes a few X-based
interface tools, a command-line interface, and C programmer API.
It is currently available on Sun, HP, SGI and OSF/1 platforms.
ClearCase uses a special Unix filesystem type, called "mvfs"
for "multi-version file system". Conceptually, mvfs adds
another dimension to a regular Unix filesystem. The new
axis is used to store the different versions of files and to
provide a tree-hierarchical view of a collection of objects that
might be scattered across any number of separate hosts on your
local network.
Each user acquires a "view" into the file database by creating a
special mvfs mount point on their machine. Each view has a
"configuration spec" containing a set of selection rules that
specify the particular version of each file to make visible in
that view. You can think of a "view" as a work area in CVS, except
that the files don't really exist on your local disk until you
modify them. This technique conserves disk space because it
doesn't keep private copies of read-only files.
Another advantage is that a view is "transparent" 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 (by
using what are called "unreserved checkouts" and the
checkin/checkout development model with file locking. Directories
are version-controlled objects as well as files. A graphical merge
tool is provided. Like RCS, 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 dependency lists 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. Hyper-links
between version controlled objects can record their relationship.
For more information, contact:
Atria Software, Inc.
24 Prime Park Way
Natick, MA 01760
[email protected]
(508) 650-1193 (phone)
(508) 650-1196 (fax)
Originally contributed by Steve Turner
Edited by the author of this FAQ.
#1C.4 How does CVS differ from TeamWare/SparcWorks?
TeamWare is a configuration management tool from Sun Microsystems,
a part of SparcWorks. It uses the same copy and merge model as
CVS. The central abstraction is a workspace, which corresponds to
either a CVS branch or a checked out module. TeamWare allows you
to manipulate workspaces directly, including moving and merging
code between workspaces. You can put your workspace on tape and
continue to work with it at home, just like you can with CVS.
TeamWare is built upon and compatible with SCCS.
TeamWare provides both a command line interface and a graphical
interface. The CodeManager tool will display the project as a
tree of workspaces, and allows you to manipulate them with drag
and drop. The other tools are VersionTool that displays and
manipulates a dag with a version history of a single file,
CheckPoint that will create symbolic tags, MakeTool, a make
compatible tool with a GUI, and FileMerge which will interactively
merge files when needed (like emerge for emacs). If you have a
sun, you can try /usr/old/mergetool for an old SunView version of
FileMerge.
Email: [email protected]
Originally extracted from TeamWare
Marketing literature by Per Abrahamsen.
Edited by the author of this FAQ.
For more information, contact:
SunExpress, Inc.
P.O. Box 4426
Bridgeton, MO 63044-9863
(800)873-7869
1C.5 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.6 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 version
controlled 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.7 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.8 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 RS6000, 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.9 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.10 How does CVS differ from Sublime?
Produced by AT&T.
[[Need more info here.]]
1C.11 How does CVS differ from PVCS?
PVCS works on single files like RCS and SCCS, CVS works on
complete subsystems. PVCS has a make utility (called a
configuration builder), CVS does not. PVCS has a GUI interface
for Unix, DOS, OS/2, and MS Windows.
Intersolv, Inc.
1700 NW 167th Place
OR 97006
Contributed by Per Abrahamsen
[Extracted from Intersolv Marketing literature.]
1C.12 How does CVS differ from CMVC?
CMVC is an IBM Configuration Management and Version Control
system. (Though I'm not certain that's the right acronym
expansion.) It runs on Suns, HPs, RS6000s, OS/2 and Windows.
Other than revision control, it apparently has features to manage
releases, bug tracking and the connection between alterations and
reported bugs and feature requests. It is a client/server system,
based on a choice of commercial Relational Database systems, and
it provides a Motif or command line interface.
Unlike CVS, it uses a strict locking protocol to serialize source
code alterations.
----------------
-- 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. See 4B.2 for more
information about CVSROOT files.
1D.2 What is an RCS file?
An RCS file is a text file 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. RCS file names normally end in ",v", but
that can be altered (via the RCS -x option) to conform to file
naming standards on platforms with unusual filename limitations.
1D.3 What is a working file?
A working file is 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)?
A working directory is the place where you work and the place
from which you "commit" files.
The "checkout" command creates a tree of working directories,
filling them with working files. Each working directory contains
a sub-directory named ./CVS containing three administrative files,
which are created by "checkout" and are always present:
./CVS/Entries
contains information about working files.
./CVS/Repository
contains the location of the directory within the
Repository that was used to create the working directory.
./CVS/Root
contains the value of $CVSROOT at the time you created
the working directory.
Other files may also appear in ./CVS depending on the state of
your working directory:
./CVS/Tag
contains the "sticky tag" associated with the whole
directory. See 3A.2 for its main purpose.
[Created by "checkout" or "update" when using "-r ".]
[Deleted by "checkout" or "update" when using '-A'.]
./CVS/Entries.Static
contains a fixed list of working files. If this file
exists, an "update" doesn't automatically bring newly
added files out of the Repository.
[Created and maintained by hand.]
./CVS/Checkin.prog
contains a program to run whenever anything in the
working directory is committed.
[Created by checkout if "-i " appears in the
modules file for the checked-out module.]
./CVS/Update.prog
contains a program to run whenever anything in the
working directory is updated.
[Created by checkout if "-u " appears in the
modules file for the checked-out module.]
./CVS/,p
./CVS/,t
contain (possibly zero-length) state information about an
"add" that has not been committed.
[Created by "add".]
[Deleted by "commit" or "remove".]
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. You normally execute "checkout" only once per
working directory (or tree of working directories), maintaining
them thereafter with the "update" command.
See section 3C on the "checkout" command.
1D.6 What is a revision?
A "revision" is a version of a file that was "committed"
("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" ("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.
The CVS "Tag" is implemented by applying RCS "symbols" to each
individual file. The Tags on a file (or collection of files) may
be displayed using the "log" command.
1D.8 What are "HEAD" and "BASE"?
HEAD and BASE 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
can become different in two ways:
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 " or "-D ". 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 again by executing "update -A".
1D.9 What is a Branch?
In general, a branch is any mechanism that allows one or more
developers to modify a file without affecting anyone other than
those working on the same branch.
There are four kinds of "branch" CVS can manage:
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 (or its
parent branch, if that is not the Main Branch) 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, its
purpose and the way it is managed are different. The major
difference is that a Release branch is normally 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 that 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 -j ". (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 can be files,
directories or module substitutions. No relative paths.
A module substitution occurs when you use a '&module-name'
reference. The module-name referred to is logically
substituted for the '&module-name' string.
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 /bin/emacs.helper gnu/emacs
The files checked out are exactly the same as the files
"checkout" would retrieve 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 /bin/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, plus exceptions.
Example:
my_work -a emacs !emacs/tests gnu/bison unix/bin/ls.c
The exception "!emacs/test" above is functionally equivalent
to specifying "!emacs/tests" on the "checkout" command line.
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.
See 4G.2 for some specific ideas about how to use the modules file.
1D.12 What does "merge" mean?
A merge is a way of combining changes made in two independent
copies of a common starting file. Checking out an RCS revision
produces a file, so for the purposes of a merge "file" and
"revision" are equivalent. So, we can say there are always three
"files" involved in a merge:
1. The original, starting, "base" or "branch point" file.
2. A copy of the base file modified in one way.
3. Another copy of the base file modified in a different way.
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 {optional files}" command merges
changes made on the given branch into your working files, which
is presumed to be on the Main line of development.
See 4C.6
3. The "update -j -j {optional files}" command merges
the difference between two specified revisions into files in
your working directory. The two revisions are usually on
the same branch and, when updating multiple files, they are
most useful when they are Tag names rather than numeric
revisions.
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 most likely assigned one or more persons to
understand, baby-sit and administer the CVS programs and the data
Repository. I call these persons Repository Administrators. They
should 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 was built with the RCSBIN directory set
to null (""), and you don't set the RCSBIN
variable mentioned below, 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.
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.
TMPDIR Used during import. It might also be used if your
platform's version of mktemp(3) is unusual, or
you have changed the source to use tmpnam(3).
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?
cd
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:
checkout, update, commit, diff, log, status, tag, add
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 , all tags are named (branch tags are
named ) and all files are named .
The checkout command will take a relative path name in place
of a module name. If you use a relative pathname in place of
, you should use the same relative path every place
you see 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 since my last update?
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 will be told that your
module name is . Then type:
cvs checkout
cd
emacs # Isn't Emacs a synonym for edit?
cvs commit
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 in the example above.
To work on a single file, you'll have to change "cd " to
"cd `dirname `".
2B.2 If I edit multiple files, must I type "commit" for each one?
No. You can commit a list of files and directories, including
relative paths into multiple directories. You can also commit
every modified file in the current directory or in all directories
and subdirectories from your current directory downward. 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 that created .
If you want to get rid of the CVS control information, but leave
the files and directories, type:
cvs release
If you want to obliterate the entire directory, type:
cvs release -d
("release -d" searches through the output of "cvs -n update" and
refuses to continue if the "update" command finds any modified
files or non-ignored foreign files. Foreign directories too.)
If you don't care about keeping "history", or checking for
modified and foreign files, you can just remove the whole
directory. That's "rm -rf " under Unix.
2B.4 How do I find out what has changed since my last update?
There are many ways to answer this.
To find out what you've changed in your current working directory
since your last checkout, update or 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 mark files CVS doesn't know about in
your working directory with a '?' indicator.
?
To add to the Repository, type:
cvs add
cvs commit
See 3A.[2-5] and 4C.8 for branch and merge considerations.
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 six possible results when you type
the "update" command:
1. If the file is lying in your working directory, but is not
under CVS, it will do nothing but print:
?
2. If neither you nor anyone else has committed changes to ,
since your last "checkout", "update" or "commit", "update"
will print nothing and do nothing.
3. If you have made no changes to a working file, but you or
others have committed changes to the Repository since your last
"checkout", "update" or "commit" of this working file, CVS will
remove your working file and replace it with a copy of the
latest revision of that file in the Repository. It will print:
U
You might want to examine the changes (using the CVS "diff"
command) to see if they mesh with your own in related files.
4. If you have made changes to a working file, but no one has
changed your BASE revision (the revision you retrieved from the
Repository in your last "checkout", "update" or "commit"),
"update" will print:
M
Nothing changes. You were told that you have a modified
file in your directory.
5. If you have made changes to your working file and you or others
have committed changes to the Repository, 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. "update" will print:
RCS file: /Repository/module/
retrieving revision 1.X
retrieving revision 1.Y
Merging differences between 1.X and 1.Y into
M
If you execute "diff" before and after this step, you should
see the same output, since both the base file and your working
file changed in parallel. This is one of the few times the
otherwise nonsensical phrase "same difference" means something.
6. If both you and those who committed files (since your last
checkout, update or commit) have made changes to the same
section of a file, CVS will merge the changes into your file as
in #5 above, but it will leave conflict indicators in the file.
"update" will print:
RCS file: /Repository/module/
retrieving revision 1.X
retrieving revision 1.Y
Merging differences between 1.X and 1.Y into
rcsmerge warning: overlaps during merge
cvs update: conflicts found in
C
This is a "conflict". The file will contain markers
surrounding the overlapping text. The 'C' conflict indicator
is sticky -- subsequent "update" commands will continue to show
a 'C' until you edit the file.
You must examine the overlaps with care and resolve the problem
by analyzing how to retain the features of both changes. See
2D.7 and 3P.6 for more details on conflict resolution.
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
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
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 " option.
2. By date, via the "-D " option.
3. By branch tag (a type of tag with a magic format), via the
"-r " option.
4. By date within a branch, via the "-r :"
option.
5. By an explicit branch revision number ("-r "), 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 whole branch might have been abandoned
in the past.
6. An explicit revision number: "-r " Though this works, it
is almost useless for more than one file.
You type:
cvs checkout
cd
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 with the
rest of the developers working on your branch.
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.16 on
Administrator responsibilities.
----------------
-- 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 non-CVS 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 non-CVS sub-directories in my working directory?
Yes. Unless the directory exists in the Repository, "update" will
skip over them and print a '?' the way it does for files you
forgot to add. You can avoid seeing the '?' by adding the name
of the foreign directory to the ./.cvsignore file, just ask you
can do with files.
If you explicitly mention a foreign directory on the "update"
command line, it will traverse the directory and waste a bit of
time, but if any directory or sub-directory lacks the ./CVS
administrative directory, CVS will print an error and abort.
2C.2 How do I add new sub-directories to the Repository?
The "add" command will work on directories. You type:
mkdir
cvs add
It will respond:
Directory /Repos/ added to the repository
and will create both a matching directory in the Repository and a
./CVS administrative directory within the local 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
cvs remove
CVS registers the file for removal. To complete the removal, you
must type:
cvs commit
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 (to some, the only acceptable) way to get the
effect of renaming, while preserving the change log:
1. Copy the RCS (",v") file directly in the Repository.
cp $CVSROOT//,v $CVSROOT//,v
By duplicating the file, you will preserve the change
history and the ability to retrieve earlier revisions of the
old file via the "-r " or "-D " options to
"checkout" and "update".
2. Remove the old file using CVS.
cd /
rm
cvs remove
cvs commit
This will move the to the Attic associated with
.
3. Retrieve and remove all the Tags from it.
By stripping off all the old Tags, "checkout -r" and
"update -r" won't retrieve revisions Tagged before
the renaming.
cd /
cvs update
cvs log # Save the list of Tags
cvs tag -d
cvs tag -d
. . .
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 your build system (e.g. Makefile) in
your to know about the name change.
Warning: Stripping the old tags from the copied file will allow
"-r " to do the right thing, but you will still have problems
with "-D " because there is no place to store the "deletion
time". See 5B.3 for more details.
2C.5 How do I make sure that all the files and directories in my
working directory are really in the Repository?
A "cvs update", or "cvs -n update" (which won't modify your
working directory) will display foreign elements, which have no
counterpart in the Repository, preceded by a '?'. To register
foreign directories, you can use "cvs add". To register foreign
files, you can use "cvs add" followed by "cvs commit".
You could also checkout your module, or the Repository directory
associated with your working directory, a second time into another
work area and compare it to your working directory using the
(non-CVS) "diff -r" command.
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 modified,
update and conflict indicators ('M', 'U', and 'C' respectively) 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
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
and commit a file in the normal way:
cvs commit
then a branch will be created in the underlying ,v file and
the new revision of 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 start with the provided template for the "modules" file,
the CVSROOT and the "modules" module will have the "mkmodules"
program as a "commit helper". After a file is committed to such a
module, "mkmodules" will convert a number of standard files (See
4B.2) in the CVSROOT directory inside 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 , which already in the Repository,
into three pieces, , and .
1. Copy the RCS (",v") files directly in the Repository,
creating the new files, then bring readable copies of the
new files into the working directory via "update".
cp $CVSROOT//,v $CVSROOT//,v
cp $CVSROOT//,v $CVSROOT//,v
cvs update
2. Then remove all the from the new files by using:
cvs log # Save the list of
cvs tag -d
cvs tag -d
. . .
3. Edit each file until it has the data you want in it.
This is a hand-editing job, not something CVS can handle.
Then commit all the files.
[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
cvs commit
As in the "rename" case, by duplicating the files, you'll preserve
the change history and the ability to retrieve earlier revisions.
Of course, you have to alter your build system (e.g. Makefiles) to
take the new names and the change in contents into account.
----------------
-- 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 .#.1.3 file in my working directory come from?
2D.10 What is this "ignore" business? What is it ignoring?
2D.11 Is there a way to set user-specific configuration options?
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" or "truss" command that will display
all system calls as they happen. This is a *very* low-level
interface that does not normally follow the execution of external
commands, but it can be useful.
The most complete answer is to read the source, compile it
with the '-g' option and step through 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 ", CVS remembers the . 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 " on the command line.
It is most useful for a , which is a sticky tag
indicating what branch you are working on.
A revision number ("-r ") or date ("-D ") 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 " 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 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 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.
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 registers the desire to add a new file. If the
"directory tag" (./CVS/Tag) file exists at the time of the "add",
the value stored in ./CVS/Tag becomes the "sticky tag" on the new
file. The file doesn't exist in the Repository until you "commit"
it, but the ./CVS/Entries file holds the sticky tag name from the
time of the "add" forward.
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 copies of the file stored in the virtual "branch"
represented by your working directories. After one of you commits
a file, the other may not commit the same file until "update" has
merged the earlier committed changes into the later working file.
For example, say you both check out rev 1.2 of and make
change to your working files. Your coworker commits revision 1.3.
When you try to commit your file, CVS says:
cvs commit: Up-to-date check failed for `'
You must merge your coworker's changes into your working file by
typing:
cvs update
which will produce the output described in 2B.6.
If a conflict occurs, the filename will be shown with a status of
'C'. After you resolve any overlaps caused by the merging
process, you may then commit the file. See 3P.6 for info on
"sticky conflicts".
Even if you get a simple 'M', you should examine the differences
before committing the file. A smooth, error-free text merge is
still no indication that the file is in proper shape. Compile and
test it at least.
The answer to two obvious questions is "Yes".
Yes, the first one who commits avoids the merge. Later developers
have to merge the earlier changes into their working files before
committing the merged result. Depending on how difficult the merge
is and how important the contending projects are, the order of
commits and updates might have to be carefully staged.
And yes, between the time you execute "update" and "commit" (while
you are fixing conflicts and testing the results) someone else may
commit another revision of . 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. Or hiring a manager.
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 active
checkouts, who has them and where they were 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 .#.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 .
You both make changes -- different changes. B commits first, so
,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, and you
commit the file immediately, #4 and #5 will be the same. But you
can make arbitrary 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 ".#.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
blizzard 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
", which can be done in the
example above by the Unix shell command:
cvs update -p -r 1.3 | diff - .#.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, a sure
sign of carelessness.
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" business? What is it ignoring?
The "update" and "import" commands use collections of Unix
wildcards to skip over files and directories matching any of those
patterns.
You may add to the built-in ignore list by adding lines of
whitespace-separated 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 exclusively in directory trees where the
Makefiles are generated by "imake" or "configure" 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 generated files without known wildcard patterns.
In any of the 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.
A variant of the ignore-file scheme is used internally during
checkout. "Module names" found in the modules file (or on the
"checkout" command line) that begin with a '!' are ignored during
checkout. This is useful to permanently ignore (if the '!' path
is in the modules file) or temporarily ignore (if the '!' path is
on the command line) a sub-directory within a Repository
hierarchy. For example:
cvs checkout !gnu/emacs/tests gnu/emacs
would checkout the module (or relative path within $CVSROOT) named
"gnu/emacs", but ignore the "tests" directory within it.
2D.11 Is there a way to set user-specific configuration options?
User-specific configuration is available through use of a ".cvsrc"
file in your home directory.
CVS searches the first column of your ~/.cvsrc file for the cvs
command name you invoked. If the command is found, the rest of
the line is treated like a set of command line options, stuffed
into the command line before the arguments you actually typed.
For example, if you always want to see context diffs and you never
want to have to delete a file before you run "cvs remove", then
you should create a .cvsrc file containing the following:
diff -c
remove -f
which will add the given options to every invocation of the given
commands.
[[The rest of this will be removed someday, when CVS changes.]]
I would like to stop here with a comment that the command name to
use is the full, canonical one. But the command that the cvsrc
support uses is the string you typed on the command line, not the
proper command. So to get the full effect of the above example,
you should also add all the alternate command names:
di -c
dif -c
rm -f
delete -f
There are two other limitations that will probably be fixed when
CVS sprouts long option names:
1. It only affects options made available on the command line.
There is a limited number of short options. With long option
names, there is no problem. You can have as many long options
as you like, affecting anything that looks malleable.
2. The existing command line options do not come in on/off pairs,
so there is no easy way to override your ~/.cvsrc configuration
for a single invocation of a command.
Choosing a good set of long option pairs would fix this.
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
back out the "transaction" and 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.
Hitting Control-C 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 carefully re-applying the
tags via the "cvs admin -N" command, but you'll still have
to dig up from outside sources the information you use to
determine what tag was on what revision in what file.
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. A repeated "checkout" from above a directory acts like a
repeated "update -d" within it.
Halting "update" half-way will give you an unpredictable
collection of files and revisions. To continue, you can rerun the
update and it should move you forward into in a known state. To
back out, you'll have to examine the output from the first
"update" command, take a look at each file that was modified and
reconstruct the previous state by editing the ./CVS/Entries file
and by using "cvs admin". 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 are a few scripts that might help you out.
========================================
== 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 new file end up in the Attic?
3A.4 Now that it's in the Attic, how do I connect it to the Main branch?
3A.5 How do I avoid the hassle of reconnecting an Attic-only file to
the Main Branch?
3A.6 How do I cancel an "add"?
3A.7 What are the ./CVS/file,p and ./CVS/file,t files for?
3A.8 How do I "add" a binary file?
**** 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, 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?
The user actions for adding a file to any branch, including the
Main Branch, are exactly the same.
You are in a directory checked out (or updated) with the '-A'
option (to place you on the Main Branch) or the "-r "
option (to place you on a branch tagged with ). To
add to the branch you are on, you type:
cvs add
cvs commit
If no ./CVS/Tag file exists (the '-A' option deletes it), the
file will be added to the Main Branch. If a ./CVS/Tag file exists
(the "-r " option creates it), the file will be added
to the branch named (i.e. tagged with) .
Unless you took steps to first add the file to the Main Branch,
your new file ends up in the Attic.
3A.3 Why did my new file end up in the Attic?
The file is thrown into the Attic to keep it from being visible
when you check out the Main Branch, since it was never committed
to the Main Branch.
3A.4 Now that it's in the Attic, how do I connect it to the Main branch?
That can be considered a kind of "merge". See 4C.8
3A.5 How do I avoid the hassle of reconnecting an Attic-only file to
the Main Branch?
You create it on the Main Branch first, then branch it.
If you haven't yet added the file or if you decided to delete the
new Attic file and start over, then do the following:
(If you added the file (or worse, the 157 files) to the Attic and
don't want to start over, try the procedure in 4C.8.)
1. Temporarily remove the sticky branch information. Either:
A. Move the whole directory back to the Main Branch.
[This might not be a good idea if you have modified files,
since it will require a merge in each direction.]
cvs update -A
*or*
B. Move the ./CVS/Tag file out of the way.
mv ./CVS/Tag HOLD_Tag
2. Add and branch the file "normally":
cvs add
cvs commit
cvs tag -b
[ is the same Branch Tag as you used on all
the other files. Look at ./CVS/Entries or the output
from "cvs stat" for sticky tags.]
3. Clean up the temporary step.
A. If you moved the ./CVS/Tag file, put it back. Then
move the new file onto the branch where you are working.
mv HOLD_Tag ./CVS/Tag
cvs update -r
B. If you ran "update -A" rather than moving the ./CVS/Tag
file, move the whole directory (including the new file) back
onto the branch where you were working:
cvs update -r
3A.6 How do I cancel an "add"?
If you want to remove the file entirely and cancel the "add" at
the same time, type:
cvs remove -f
If you want to cancel the "add", but leave the file as it was
before you typed "cvs add", then you have to fake it:
mv .hold
cvs remove
mv .hold
3A.7 What are the ./CVS/file,p and ./CVS/file,t files for?
The ./CVS/file,p and ./CVS/file,t files are created by the "add"
command to hold command line options and message text between the
time of the "add" command and the expected "commit".
The ./CVS/file,p file is always null, since its function was
absorbed by the "options" field in the ./CVS/Entries file. If you
put something in this file it will be used as arguments to the RCS
"ci" command that commit uses to check the file in, but CVS itself
doesn't put anything there.
The ./CVS/file,t file is null unless you specify an initial
message in an "add -m 'message'" command. The text is handed to
"rcs -i -t./CVS/file,t" to create the initial RCS file container.
Both files must exist to commit a newly added file. If the
./CVS/file,p file doesn't exist, CVS prints an error and aborts
the commit. If the ./CVS/file,t file doesn't exist, RCS prints an
error and CVS gets confused, but does no harm.
To recover from missing ,p and ,t files, just create two
zero-length files and rerun the "commit".
3A.8 How do I "add" a binary file?
If you configured CVS to use the GNU version of "diff" and
"diff3", you only need to turn off RCS keyword expansion.
First you turn off RCS keyword expansion for the initial checkin
by using "add -ko". It works like "update -ko" in creating a
"sticky" option only for the copy of the file in the current
working directory.
cvs add -ko
Commit the file normally. The sticky -ko option will be used.
cvs commit
Then mark the RCS file in the Repository so that keyword
expansion is turned off for all checked out versions of the file.
cvs admin -ko
Since "admin -ko" records the keyword substitution value in the
Repository's RCS file, you no longer need the sticky option. You
can turn it off with the "update -A" command, but if you were on a
branch, you'll have to follow it "update -r " to put
yourself back on the branch.
Managing that binary file is another problem. See 4D.1.
----------------
-- 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) bypassing all safeguards and CVS
assumptions.
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 use "admin -o" (for "outdate") to remove revisions
you don't care about. This has its own problems, such as leaving
dangling Tags and confusing the "update" command.
There is some feeling among manipulators of binary files that
"admin -l" should be used to serialize access. See 3C.8.
An interesting use for "admin" came up while maintaining CVS
itself. I import versions of CVS onto the Vendor branch of my
copy of CVS, make changes to some files and ship the diffs
(created by "cvs diff -c -r TO_BRIAN") off to Brian Berliner.
After creating the diff, I retag ("cvs tag -F TO_BRIAN") the
working directory, which is then ready to produce the next patch.
I'll use "add.c" as an example (only because the name is short).
When the next release came out, I discovered that the released
"add.c" (version 1.1.1.3 on the Vendor branch) was exactly the
same as my modified file (version 1.3). I didn't care about the
changelog on versions 1.2 and 1.3 (or the evidence of having done
the work), so I decided to revert the file to the state where it
looked like I had not touched the file -- where I was just using
the latest on the vendor branch after a sequence of imports.
To do that, I removed all the revisions on the main branch, except
for the original 1.1 from which the Vendor branch sprouts:
cvs admin -o1.2: add.c
Then I set the RCS "default branch" back to the Vendor branch, the
way import would have created it:
cvs admin -b1.1.1 add.c
And I moved the "TO_BRIAN" Tag to the latest revision on the
Vendor branch, since that is the base from which further patches
would be created (if I made any):
cvs admin -NTO_BRIAN:1.1.1.3 add.c
Instead of 1.1.1.3, I could have used one of the "Release Tags"
last applied by "import" (3rd through Nth arguments).
Suggestion: Practice on non-essential files.
3B.4 What should I avoid when using "admin"?
If you know exactly what you are doing, hack away. But under
normal circumstances:
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.
See 3C.8 for a short discussion of how to use "admin -l" for
serializing access to binary files.
The "admin -o " 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 "_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 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 ,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
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 , not just the one on . 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 . 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 pointed to without using the "tag"
command. For example, if revision 1.3 has attached to it
and you "outdate" the 1.3 revision, 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 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 while I'm working on them 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" commands are nearly equivalent in how
they treat individual files. They 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" command 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 files in the ./CVS administrative directory.
4. The two commands generate completely different types of records
in the "history" file.
3C.5 Why can't I check out a file from within my working directory?
Though you *can* check out a file, you normally check out a module
or directory. 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 two pathnames: 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 "modules".
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.
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 while I'm working on them the way RCS does?
Until the day arrives of the all-powerful merge tool, there are
still files that must be accessed serially. For those instances,
here's a potential solution:
1. Install a pre-commit program in the "commitinfo" file to check
for RCS locks. The program "rcslock.pl" performs this
function. It can be found in the contrib directory of the CVS
source distribution.
2. When you want to make a change to a file you know can't be
merged, first use "cvs admin -l" to lock the file. If you
can't acquire the lock, use the standard "locked out" protocol:
go talk to the person holding the lock.
3. Make sure the pre-commit program prints a message and exits
with a non-zero status if someone besides the user running
"commit" has the file locked. This non-zero exist status will
cause the "commit" to fail cleanly.
4. Make sure the pre-commit program exits with a zero status if
the file is either unlocked or locked by the user running
"commit". The "cvs commit" command that kicked off the
pre-commit program will take a zero exist status as an OK and
checkin the file, which has the side-effect of unlocking it.
===> The following is opinion and context. Don't read it if you
are looking for a quick fix.
The topic of locking CVS files resurfaces on the network every so
often, producing the same results each time:
The Big Endians:
CVS was designed to avoid locks, using a copy-modify-merge
model. Locking is not necessary and you should take the time
to learn the CVS model which many people find workable. So why
not get with the program and learn how to think the CVS way?
The Little Endians:
The users determine how a tool is to be used, not the
designers. We, the users, have always used locking, our bosses
demand locking, locking is good, locking is God. I don't want
to hear any more lectures on the CVS model. Make locking work.
Any organization making active changes to a source base will
eventually face the need to do parallel development. Parallel
development implies merges. (If you plan to keep separate copies
of everything and never merge, good luck. Tell me who you work
for so I can buy stock in your disk suppliers this year and sell
your stock short next year.)
Merges will never go away. CVS chose to make "merges" stand
front and center as an important, common occurrence in
development. It is one way of looking at things.
For free-format text, the merge paradigm gives you a considerable
amount of freedom. It does take a bit of management, but any
project should be ready to deal with it.
On the other hand, there are many files that can't be merged using
text merge techniques. Straight text merge programs like "diff3"
are guaranteed to fail on executables (with relative branch
statements), files with self-referential counts stored in the file
(such as TAGS files), or files with relative motion statements in
them (such as Frame MIF files, many postscript files). They
aren't all binary files.
For these types of files, and many others, there are only two
solutions:
1. Complex merge tools that are intimately aware of the contents
of the files to be merged. (ClearCase, and probably others,
allow you to define your own "files types" with associated
"merge tools".)
2. Serialization of access to the file. The only technical
solution to the problem of serialization is "locking".
Since you can call a program that offers:
"Which one do you want? A/B?"
a "merge tool", more and more merge tools will appear which can be
hooked into a merge-intensive program like CVS. Think of a bitmap
"merge" tool that displays the bitmaps on the screen and offers a
"paint" interface to allow you to cut and paste, overlay, invert
or fuse the two images such that the result is a "merged" file.
My conclusion is that the need for locking is temporary, awaiting
better technology. For large development groups, locking is not
an alternative to merging for text files.
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 ") 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).
----------------
-- 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 `'
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 " put newly added files in the Attic?
3D.8 Why would a "commit" of a newly added file not produce rev 1.1?
**** 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, directory
names and relative pathnames on the command line and commit them
all with the same log message. If a file is unchanged, even if it
is explicitly listed on the command line, 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 `'
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 checkin of a minor alteration of a second copy of 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 the world of parallel 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 to be careful,
you should just grab an old version of the file ("update -p -r
" 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 records (i.e. makes "sticky") any "-r " argument
handed to the "checkout" or "update" commands. The 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 {files or dirs, default is '.'}
or you can move to the branch named by:
cvs update -r {files or dirs, default is '.'}
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
(It was not a big mistake. Branch-point tags can be useful.
But the must have a different name.)
If you don't know the name or don't use "modules",
you can also use "tag" this way:
cvs update -r
cvs tag -b .
Then, to put your working directory onto the branch, you type:
cvs update -r
You can't delete before adding , and I would
not advise deleting the 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
or
cvs tag -d .
Scenario3:
If you made the same mistake as in Scenario2 (of placing a
non-branch tag where you wanted a branch tag), but really want
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.
Warning: This is not a way to rename a branch tag. It is a way
to turn a non-branch tag into a branch tag with the
same name.
cvs rtag -r
cvs rtag -d
cvs rtag -b -r
Then, if you really must, delete the :
cvs rtag -d
Note: The unwieldy mixture of "tag" and "rtag" is mostly
because you can't specify a revision (-r ) to the
"tag" command.
See 4C.3 for more info on creating a branch.
3D.7 Why does "commit -r " put newly added files in the Attic?
If you specify "-r " (where is a dotted numeric number
like 2.4), it correctly sets the initial revision to , but it
also attaches the numeric as a sticky tag and throws the
file into the Attic. This is a bug. The obvious solution is to
move the file out of the Attic into the associated Repository
directory and "update -A" the file. There are no Tags to clean up.
If you specify "-r " to commit a newly added file, the
is treated like a , which becomes a symbolic RCS label
pointing to the string '1', which can be considered to be the
"Main branch number" when the main branch is still at revision
1.N. The file is also thrown into the Attic. See 4C.8 for a way
to recover from this.
In fact, a plain "commit" without the "-r" will throw a newly
added file into the Attic if you added it to a directory checked
out on a branch. See 3A.[2-5].
See Section 4C, on Branching, for many more details.
3D.8 Why would a "commit" of a newly added file not produce rev 1.1?
When committing a newly added file CVS looks for the highest main
branch major number in all files in the ./CVS/Entries file.
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 . Normally, the first revision is 1.1.
----------------
-- 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 long options, like --unified, to "diff"?
**** Answers:
3E.1 What is "diff" for?
1. To display the difference between a working file and its BASE
revision (the revision last checked out, updated or committed):
cvs diff
2. To display the difference between a working file and a
committed revision of the same file:
cvs diff -r
3. To display the difference between two committed revisions of
the same file:
cvs diff -r -r
You can specify any number of arguments. Without any
arguments, it compares the whole directory.
In the examples above, "-D " may be substituted wherever
"-r " appears. The revision a 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
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
3E.4 How do I display the difference between my working file and what
I checked in last Thursday?
cvs diff -D "last Thursday"
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 long options, like --unified, to "diff"?
CVS only handles single character '-X' arguments, not the FSF long
options. CVS also passes through only arguments it knows about,
because a few arguments are captured and interpreted by CVS.
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 doesn't "export" have a '-k' flag like "import" does?
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 as of the current revision: CVS 1.4.
3F.4 Why doesn't "export" have a '-k' flag like "import" does?
Export is intended for a specific purpose -- to remove all trace
of revision control on the way *out* of CVS.
3F.5 Why does "export -D" check out every file in the Attic?
See 5B.3 for an explanation of the same problem with "update".
----------------
-- 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 " and
"cvs history -t "?
3G.8 Why does "cvs history -c -t " 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?
3G.11 Can we merge history files when we merge Repositories?
**** 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?
You can use "release -f" to forcibly add a "release" record to the
history file for a working directory associated with a "module".
If your version of "release" doesn't have the '-f' option, or you
checked out the directory using a relative path, 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 " and
"cvs history -t "?
The '-t' option looks for a Tag record stored by "rtag" in the
history file and limits the search to dates after the last