[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As long as you edit source files inside a working directory you can always find out the state of your files via `cvs status' and `cvs log'. But as soon as you export the files from your development environment it becomes harder to identify which revisions they are.
CVS can use a mechanism known as keyword
substitution (or keyword expansion) to help
identifying the files. Embedded strings of the form
$keyword$
and
$keyword:…$
in a file are replaced
with strings of the form
$keyword:value$
whenever you obtain
a new revision of the file.
12.1 Keyword List | Keywords | |
12.2 Using keywords | ||
12.3 Avoiding substitution | ||
12.4 Substitution modes | ||
12.5 Configuring Keyword Expansion | Configuring keyword expansion | |
12.6 Problems with the $Log$ keyword. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is a list of the keywords:
$Author$
The login name of the user who checked in the revision.
$CVSHeader$
A standard header (similar to $Header$, but with the CVS root stripped off). It contains the relative pathname of the RCS file to the CVS root, the revision number, the date (UTC), the author, the state, and the locker (if locked). Files will normally never be locked when you use CVS.
Note that this keyword has only been recently
introduced to CVS and may cause problems with
existing installations if $CVSHeader$ is already
in the files for a different purpose. This keyword may
be excluded using the KeywordExpand=eCVSHeader
in the `CVSROOT/config' file.
See Configuring Keyword Expansion for more details.
$Date$
The date and time (UTC) the revision was checked in.
$Header$
A standard header containing the full pathname of the RCS file, the revision number, the date (UTC), the author, the state, and the locker (if locked). Files will normally never be locked when you use CVS.
$Id$
Same as $Header$
, except that the RCS
filename is without a path.
$Name$
Tag name used to check out this file. The keyword is
expanded only if one checks out with an explicit tag
name. For example, when running the command cvs
co -r first
, the keyword expands to `Name: first'.
$Locker$
The login name of the user who locked the revision
(empty if not locked, which is the normal case unless
cvs admin -l
is in use).
$Log$
The log message supplied during commit, preceded by a
header containing the RCS filename, the revision
number, the author, and the date (UTC). Existing log
messages are not replaced. Instead, the new log
message is inserted after $Log:…$
.
By default, each new line is prefixed with the same string which
precedes the $Log$
keyword, unless it exceeds the
MaxCommentLeaderLength
set in `CVSROOT/config'.
For example, if the file contains:
/* Here is what people have been up to: * * $Log: frob.c,v $ * Revision 1.1 1997/01/03 14:23:51 joe * Add the superfrobnicate option * */ |
then additional lines which are added when expanding
the $Log$
keyword will be preceded by ` * '.
Unlike previous versions of CVS and RCS, the
comment leader from the RCS file is not used.
The $Log$
keyword is useful for
accumulating a complete change log in a source file,
but for several reasons it can be problematic.
If the prefix of the $Log$
keyword turns out to be
longer than MaxCommentLeaderLength
, CVS will skip expansion of this
keyword unless UseArchiveCommentLeader
is also set in
`CVSROOT/config' and a `comment leader' is set in the RCS archive
file, in which case the comment leader will be used instead. For more on
setting the comment leader in the RCS archive file, See section admin—Administration. For more
on configuring the default $Log$
substitution
behavior, See section The CVSROOT/config configuration file.
See section Problems with the $Log$ keyword..
$RCSfile$
The name of the RCS file without a path.
$Revision$
The revision number assigned to the revision.
$Source$
The full pathname of the RCS file.
$State$
The state assigned to the revision. States can be
assigned with cvs admin -s
—see admin options.
Local keyword
The LocalKeyword
option in the `CVSROOT/config' file
may be used to specify a local keyword which is to be
used as an alias for one of the keywords: $Id$,
$Header$, or $CVSHeader$. For
example, if the `CVSROOT/config' file contains
a line with LocalKeyword=MYBSD=CVSHeader
, then a
file with the local keyword $MYBSD$ will be
expanded as if it were a $CVSHeader$ keyword. If
the src/frob.c file contained this keyword, it might
look something like this:
/* * $MYBSD: src/frob.c,v 1.1 2003/05/04 09:27:45 john Exp $ */ |
Many repositories make use of a such a “local
keyword” feature. An old patch to CVS provided
the LocalKeyword
feature using a tag=
option and called this the “custom tag” or “local
tag” feature. It was used in conjunction with the
what they called the tagexpand=
option. In
CVS this other option is known as the
KeywordExpand
option.
See Configuring Keyword Expansion for more
details.
Examples from popular projects include: $FreeBSD$, $NetBSD$, $OpenBSD$, $XFree86$, $Xorg$.
The advantage of this is that you can include your local version information in a file using this local keyword without disrupting the upstream version information (which may be a different local keyword or a standard keyword). Allowing bug reports and the like to more properly identify the source of the original bug to the third-party and reducing the number of conflicts that arise during an import of a new version.
All keyword expansion except the local keyword may be
disabled using the KeywordExpand
option in
the `CVSROOT/config' file—see
Configuring Keyword Expansion for more details.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To include a keyword string you simply include the
relevant text string, such as $Id$
, inside the
file, and commit the file. CVS will automatically (Or,
more accurately, as part of the update run that
automatically happens after a commit.)
expand the string as part of the commit operation.
It is common to embed the $Id$
string in
the source files so that it gets passed through to
generated files. For example, if you are managing
computer program source code, you might include a
variable which is initialized to contain that string.
Or some C compilers may provide a #pragma ident
directive. Or a document management system might
provide a way to pass a string through to generated
files.
The ident
command (which is part of the RCS
package) can be used to extract keywords and their
values from a file. This can be handy for text files,
but it is even more useful for extracting keywords from
binary files.
$ ident samp.c samp.c: $Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $ $ gcc samp.c $ ident a.out a.out: $Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $ |
SCCS is another popular revision control system.
It has a command, what
, which is very similar to
ident
and used for the same purpose. Many sites
without RCS have SCCS. Since what
looks for the character sequence @(#)
it is
easy to include keywords that are detected by either
command. Simply prefix the keyword with the
magic SCCS phrase, like this:
static char *id="@(#) $Id: ab.c,v 1.5 1993/10/19 14:57:32 ceder Exp $"; |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Keyword substitution has its disadvantages. Sometimes you might want the literal text string `$Author$' to appear inside a file without CVS interpreting it as a keyword and expanding it into something like `$Author: ceder $'.
There is unfortunately no way to selectively turn off keyword substitution. You can use `-ko' (see section Substitution modes) to turn off keyword substitution entirely.
In many cases you can avoid using keywords in
the source, even though they appear in the final
product. For example, the source for this manual
contains `$@asis{}Author$' whenever the text
`$Author$' should appear. In nroff
and troff
you can embed the null-character
\&
inside the keyword for a similar effect.
It is also possible to specify an explicit list of
keywords to include or exclude using the
KeywordExpand
option in the
`CVSROOT/config' file–see Configuring Keyword Expansion
for more details. This feature is intended primarily
for use with the LocalKeyword
option–see
Keyword List.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each file has a stored default substitution mode, and
each working directory copy of a file also has a
substitution mode. The former is set by the `-k'
option to cvs add
and cvs admin
; the
latter is set by the `-k' or `-A' options to cvs
checkout
or cvs update
.
cvs diff
and cvs rdiff
also
have `-k' options.
For some examples,
see Handling binary files, and Merging and keywords.
The modes available are:
Generate keyword strings using the default form, e.g.
$Revision: 5.7 $
for the Revision
keyword.
Like `-kkv', except that a locker's name is always
inserted if the given revision is currently locked.
The locker's name is only relevant if cvs admin
-l
is in use.
Generate only keyword names in keyword strings; omit
their values. For example, for the Revision
keyword, generate the string $Revision$
instead of $Revision: 5.7 $
. This option
is useful to ignore differences due to keyword
substitution when comparing different revisions of a
file (see section Merging and keywords).
Generate the old keyword string, present in the working
file just before it was checked in. For example, for
the Revision
keyword, generate the string
$Revision: 1.1 $
instead of
$Revision: 5.7 $
if that is how the
string appeared when the file was checked in.
Like `-ko', but also inhibit conversion of line
endings between the canonical form in which they are
stored in the repository (linefeed only), and the form
appropriate to the operating system in use on the
client. For systems, like unix, which use linefeed
only to terminate lines, this is very similar to
`-ko'. For more information on binary files, see
Handling binary files. In CVS version 1.12.2 and later
`-kb', as set by cvs add
, cvs admin
, or
cvs import
may not be overridden by a `-k' option
specified on the command line.
Generate only keyword values for keyword strings. For
example, for the Revision
keyword, generate the string
5.7
instead of $Revision: 5.7 $
.
This can help generate files in programming languages
where it is hard to strip keyword delimiters like
$Revision: $
from a string. However,
further keyword substitution cannot be performed once
the keyword names are removed, so this option should be
used with care.
One often would like to use `-kv' with cvs
export
—see section export—Export sources from CVS, similar to checkout. But be aware that doesn't
handle an export containing binary files correctly.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In a repository that includes third-party software on vendor branches, it is sometimes helpful to configure CVS to use a local keyword instead of the standard $Id$ or $Header$ keywords. Examples from real projects include $Xorg$, $XFree86$, $FreeBSD$, $NetBSD$, $OpenBSD$, and even $dotat$. The advantage of this is that you can include your local version information in a file using this local keyword (sometimes called a “custom tag” or a “local tag”) without disrupting the upstream version information (which may be a different local keyword or a standard keyword). In these cases, it is typically desirable to disable the expansion of all keywords except the configured local keyword.
The KeywordExpand
option in the
`CVSROOT/config' file is intended to allow for the
either the explicit exclusion of a keyword or list of
keywords, or for the explicit inclusion of a keyword or
a list of keywords. This list may include the
LocalKeyword
that has been configured.
The KeywordExpand
option is followed by
=
and the next character may either be i
to start an inclusion list or e
to start an
exclusion list. If the following lines were added to
the `CVSROOT/config' file:
# Add a "MyBSD" keyword and restrict keyword # expansion LocalKeyword=MyBSD=CVSHeader KeywordExpand=iMyBSD |
then only the $MyBSD$ keyword would be expanded. A list may be used. The this example:
# Add a "MyBSD" keyword and restrict keyword # expansion to the MyBSD, Name and Date keywords. LocalKeyword=MyBSD=CVSHeader KeywordExpand=iMyBSD,Name,Date |
would allow $MyBSD$, $Name$, and $Date$ to be expanded.
It is also possible to configure an exclusion list using the following:
# Do not expand the non-RCS keyword CVSHeader KeywordExpand=eCVSHeader |
This allows CVS to ignore the recently introduced $CVSHeader$ keyword and retain all of the others. The exclusion entry could also contain the standard RCS keyword list, but this could be confusing to users that expect RCS keywords to be expanded, so care should be taken to properly set user expectations for a repository that is configured in that manner.
If there is a desire to not have any RCS keywords
expanded and not use the -ko
flags everywhere,
an administrator may disable all keyword expansion
using the `CVSROOT/config' line:
# Do not expand any RCS keywords KeywordExpand=i |
this could be confusing to users that expect RCS keywords like $Id$ to be expanded properly, so care should be taken to properly set user expectations for a repository so configured.
It should be noted that a patch to provide both the
KeywordExpand
and LocalKeyword
features
has been around a long time. However, that patch
implemented these features using tag=
and
tagexpand=
keywords and those keywords are NOT
recognized.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The $Log$
keyword is somewhat
controversial. As long as you are working on your
development system the information is easily accessible
even if you do not use the $Log$
keyword—just do a cvs log
. Once you export
the file the history information might be useless
anyhow.
A more serious concern is that CVS is not good at
handling $Log$
entries when a branch is
merged onto the main trunk. Conflicts often result
from the merging operation.
People also tend to "fix" the log entries in the file
(correcting spelling mistakes and maybe even factual
errors). If that is done the information from
cvs log
will not be consistent with the
information inside the file. This may or may not be a
problem in real life.
It has been suggested that the $Log$
keyword should be inserted last in the file, and
not in the files header, if it is to be used at all.
That way the long list of change messages will not
interfere with everyday source file browsing.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Derek R. Price on October, 3 2005 using texi2html 1.77.