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.
This is a list of the keywords:
$Author: alexp $
$Date: 2000/08/19 22:46:01 $
$Header: /cvsroot/cvsgui/www/howto/cvsdoc/cvs_12.html,v 1.1.1.1
2000/08/19 22:46:01 alexp Exp $
$Id: cvs_12.html,v 1.1.1.1 2000/08/19 22:46:01 alexp Exp $
$Header: /cvsroot/cvsgui/www/howto/cvsdoc/cvs_12.html,v
1.1.1.1 2000/08/19 22:46:01 alexp Exp $
, except that the RCS filename
is without a path.
$Name: $
cvs co -r first
, the keyword expands to `Name:
first'.
$Locker: $
cvs admin -l
is in use).
$Log: cvs_12.html,v $
Revision 1.1.1.1 2000/08/19 22:46:01 alexp
first in
Revision 1.2 2000/02/15 13:16:25 shh
*** empty log message ***
- 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: cvs_12.html,v $ message is inserted after
Revision 1.1.1.1 2000/08/19 22:46:01 alexp message is inserted after
first in message is inserted after message is inserted after
Revision 1.2 2000/02/15 13:16:25 shh message is inserted after ***
empty log message *** message is inserted after
. Each new line
is prefixed with the same string which precedes the $Log
keyword.
For example, if the file contains /* Here is what people have been up to:
*
* $Log: cvs_12.html,v $
* Revision 1.1.1.1 2000/08/19 22:46:01 alexp
* first in
*
* Revision 1.2 2000/02/15 13:16:25 shh
* *** empty log message ***
*
* 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. See section Problems with the
$Log: cvs_12.html,v $ See section Problems with the
Revision 1.1.1.1 2000/08/19 22:46:01 alexp See section Problems with the
first in See section Problems with the
See section Problems with the
Revision 1.2 2000/02/15 13:16:25 shh See section Problems with the
*** empty log message *** See section Problems with the
keyword..
$RCSfile: cvs_12.html,v $
- The name of the RCS file without a path.
$Revision: 1.1.1.1 $
- The revision number assigned to the revision.
$Source: /cvsroot/cvsgui/www/howto/cvsdoc/cvs_12.html,v $
- The full pathname of the RCS file.
$State: Exp $
- The state assigned to the revision. States can be assigned with
cvs
admin -s
---see section admin
options.
To include a keyword string you simply include the relevant text string, such
as $Id: cvs_12.html,v 1.1.1.1 2000/08/19 22:46:01 alexp Exp $
,
inside the file, and commit the file. CVS will automatically 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: cvs_12.html,v 1.1.1.1 2000/08/19 22:46:01 alexp Exp $ $ gcc samp.c $ ident a.out a.out: $Id: cvs_12.html,v 1.1.1.1 2000/08/19 22:46:01 alexp 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: cvs_12.html,v 1.1.1.1 2000/08/19 22:46:01 alexp Exp $";
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.
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
also has a
`-k' option. For some examples, see section Handling binary
files, and section Merging and
keywords.
The modes available are:
$
Revision: 5.7 $ for the Revision
keyword.
cvs admin -l
is in use.
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).
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.
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. 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.
Go to the first, previous, next, last section, table of contents.