Essential CVS/Using CVS/Multiple Users

From WikiContent

< Essential CVS | Using CVS
Revision as of 13:08, 7 March 2008 by Docbook2Wiki (Talk)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search
Essential CVS

This chapter explains how CVS can be used for source or content control — how to manage a group of developers working together on a project without having them overwrite each other's work, causing loss of data. It also describes commands that show what each person has done to a file.

The problem of source control occurs when you don't have any management software. If you have a central location for data and two people are using the same storage, such as the same file, the second person to save a file can overwrite the first person's changes. Source control software can prevent this, by either capturing both sets of changes and merging them together, or by preventing two people from having the same file checked out at the same time.

CVS is designed to allow developers to work simultaneously on a file. Several people can work on the same file, each in their own sandbox, and CVS tries to merge their changes to the data in the central repository. If the changes can't be merged easily, the developer who commits the second set of changes is asked to resolve the conflict. This pattern is explained in Chapter 3.

An alternative to simultaneous development is exclusive development, where one developer at a time has the editing rights for a file. Some development teams prefer to use exclusive development, which is effective for files that can't be merged. CVS supports the exclusive development of files with a choice of two methods:

  • The first method permits, but does not enforce, exclusive development. This method uses the cvs watch, cvs edit, and cvs unedit command set.
  • The second method uses the cvs admin command to emulate file locking with reserved checkouts and relies on the rcslock script in the contrib directory of the CVS source code. This method requires the assistance of the repository administrator.

Whether you use exclusive or simultaneous development, source control works only if your project members use it. It is also essential that they communicate the basic design and structure of the project with each other. No source control system can take the place of a shared vision of the project.

Once you are working in a team, you need to be able to see the changes made by other team members. Studying the history of changes can help keep the team working toward the same goals, or it can help determine where the team's goals have diverged. CVS provides a range of commands for viewing changes.

The diff and rdiff commands display the changes made between specific revisions of a file and also allow you to make patches that can be installed with the GNU patch program. The annotate command displays the most recent change to each line of a file, along with the revision number of the revision in which the line was changed and the username of the user who made the change. The log command displays the log messages and status information for files.


Using Simultaneous Development

Simultaneous development allows multiple developers to work on the same file at the same time. If you and your coworker are working on different sections of a file, you can both edit the file and then have a program (such as CVS) merge the two versions of the file. Simultaneous development is also useful when you have developers distributed across many time zones, as it eliminates the need to check with other team members before editing a file.

CVS supports simultaneous development without requiring any configuration changes or setup. Simultaneous development is most helpful when you are using text or other line-based files, because CVS merges are based on the changes in lines. CVS is less able to merge binary files.

When multiple developers use the same repository directory, each should check out her own sandbox, develop in that sandbox, commit to the repository frequently, and update frequently. CVS merges most changes automatically, and if you update and commit frequently, there should be few cases where a human has to edit the changes.

Watching a File

CVS provides a set of commands to notify users when a file is being edited or committed. You can use these commands to monitor what each member of your team is doing and reduce the necessity of merging files when cvs updateis run. Together, the cvs watch , cvs edit, and cvs unedit commands make up the watch method of exclusive development, which is a lightly enforced method of exclusive development.

The watch method requires the repository administrator to set up the notify and users files in the CVSROOT directory of the CVS repository; it requires the developers to check whether a file is being edited before they attempt to edit it.

Use cvs watch like this:

  1. Check out your sandbox, including the files you want to watch.
  2. Issue the cvs watch on command to mark files for watching. (This does not set you as the watcher for the files; it just informs CVS that the files can be watched.) Once a file has been marked for watching, it remains marked unless it is cleared with cvs watch off.


    You need to use cvs watch on for a file only once, unless someone clears the setting. Usually, your project leader decides which files can be watched and will mark those files for watching.

  3. Issue the cvs watch add commandto set yourself as a watcher of the files you want to watch.
  4. Issue cvs edit to inform CVS and other users that you intend to edit a specific file. Other users watching the file will be notified that you are editing it.
  5. Edit the file in any editor.
  6. Commit your changes with cvs commit. This saves the changes to the repository and releases the file for others to edit. CVS notifies other users watching the file that you have committed it.
  7. If you don't want to commit your changes, but instead want to revert to the state of the file before you edited it, use cvs unedit to release it for others to edit. CVS notifies anyone watching the file that you are no longer editing it.

The watch method is voluntary; there is nothing preventing another user from making changes to a file you are editing. However, the cvs edit command automatically designates you as a temporary watcher on a file until you release the file. So, if another developer runs cvs edit on the file, you will be notified and can contact them to coordinate your changes.

The cvs edit and cvs unedit commands work in conjunction with CVS's watch feature to enable you to keep track of activity in your project's files. The watch and editing features can also be used independently of each other. The next few sections show how to use the watch method to coordinate development and monitor activity in your project files.

Configuring Watches

Before using the watch commands, you need to designate files as watchable and configure how you want CVS to notify watchers. You can designate which files are watchable with the cvs watch on command. This marks a file as watchable but does not make you a watcher.

CVS notifies a file's watchers when the file is committed, marked for editing, or released from editing. When the conditions exist for CVS to notify a watching user, CVS runs the commands in the repository's CVSROOT/notify file. This file usually contains a single line that causes the watcher to be emailed with the notification. Such a line is shown in Example 5-1.

Example 5-1. CVSROOT/notify

ALL mail %s -s "CVS Notification"

By default, this command sends an email to the user's CVS username at the computer that the repository is on. If there are users whose mailboxes (or other notification method) are not on the same computer or use different usernames, create a users file in the repository's CVSROOT directory. The format of this file is a separate line for each user, consisting of the CVS username[1] and the email address to send notifications to, in the following format:


Example 5-2 shows an example of a users file.

Example 5-2. CVSROOT/users

The full syntax for the notify and users files is explained in Chapter 6.

Marking a File for Watching

Before using the watch commands on a file, you need to set the file for watching. Files that are set for watching are checked out read-only, and the intent is that you use cvs edit to set a file read-write and notify other watchers that you intend to edit it. If a directory is designated as being watched, all new files in that directory are set for watching.

Use the command cvs watch on filename to set a file for watching, and use cvs watch off filename to revert it to normal mode. Note that setting the file for watching does not add you to the list of people watching the file; it only enables the watch system for that file.

The watch system is honor-based. You can set a file read-write without using the cvs edit command and then edit it without ever notifying other users. (They will get a message when you commit the file, however.) CVS also won't stop another user from using cvs watch offto turn off the watch you set. If you need a more restrictive system, consider using the rcslock system described in Section 5.3 later in this chapter.

Setting Your Watch

Watching a file sets CVS to notify you when someone signals their intent to edit the file, when someone commits that file, or when someone signals that they have stopped editing the file. CVS does not notify you of your own changes to the file. Use the command cvs watch add filename to add yourself to the list of people watching a file. cvs watch add takes the -a command option, which restricts the actions CVS should notify you of. The -a option has the parameters edit, unedit, commit, none, or all. The default case is all.

To stop watching a file, use cvs watch remove filename. cvs watch remove also takes the -a option with the same parameters as cvs watch add. Both commands use -R to operate recursively down a directory tree and -l to operate locally.

You can use cvs watch add or cvs watch remove without having the file set for watching — in other words, without executing cvs watch on first — but CVS can inform you of an edit only if the other developer uses cvs edit. If the file is not set for watching, the other developer is not reminded to use cvs edit.

Unfortunately, the cvs watch commands do not provide helpful feedback when they are called. Example 5-3 shows the use of the cvs watch commands.

Example 5-3. Using cvs watch

bash-2.05a$ cvs watch on Makefile
bash-2.05a$ cvs watch add -a edit Makefile
bash-2.05a$ cvs watch remove Makefile
bash-2.05a$ cvs watch off Makefile

Example 5-4 shows the mail CVS sends as a result of a cvs editcommand.

Example 5-4. Mail from CVS

Subject:   CVS Notification
Date:      17 Sep 2002 22:13:45 +1000     
wizzard Makefile
Triggered edit watch on /var/lib/cvs/wizzard
By Poppel

The syntax of the cvs watchcommand is:

cvs [cvs-options] watch {on|off|add|remove} [command-options] [filenames]

The cvs watch command can take filenames, directory names, or modules as parameters and use the sandbox directory as a parameter if no other parameter is given. If no -a option is given to cvs watch add orcvs watch remove, -a allis the default.

Example 5-5 demonstrates using cvs watch locally to set a specific watch for a directory, but not subdirectories. It also uses the watchers command to show some of the results of the watch.

Example 5-5. Using cvs watch options

bash-2.05a$ cvs watch add -l -a commit .  
bash-2.05a$ cvs watchers .
Changelog   jenn     unedit   commit
INSTALL     jenn     unedit   commit
Makefile    jenn     edit     unedit     commit
README               jenn     unedit     commit
TODO                 jenn     unedit     commit
doc/design/AcceptanceTest.doc            jenn     unedit
doc/design/Analysis.rtf                  jenn     unedit
src/config.h         doppel   edit       unedit   commit
   jenn     edit     unedit


The cvs watch command doesn't work if either the server or the client is running CVS version 1.6 or earlier.

Editing a File

Signal your intent to edit a file with the cvs edit filename command. This sets the file read-write, signals CVS to notify all watchers who are interested in edits, and temporarily adds you as one of the file's watchers. If you do not wish to watch the file, you can use -a none.

Once you have signalled your intent to edit a file, use your usual editor to make your changes. When you are finished, use cvs commit to save changes or cvs unedit to revert them.

The syntax of cvs edit is:

cvs [cvs-options] edit [command-options] [filenames]

The syntax of cvs unedit is:

cvs [cvs-options] unedit [command-options] [filenames]

Both commands can take filenames, directory names, or modules as parameters and use the sandbox directory as a parameter if no other parameter is given. Both commands use -R to operate recursively down a directory tree and -l to operate locally. The edit command also supports -a with the same parameters as cvs watch. If no -a option is given to cvs edit, -a all is set by default.


The cvs edit command does not restrict anyone else from editing the file you're working on; it only signals to them that you're editing it. It doesn't warn you if someone else is already editing the file.

Aborting an edit

When you commit a file with cvs commit , CVS clears the file's edit mark. If you want to clear the edit on a file but don't want to commit your changes, you can use the cvs unedit filename command, use cvs release on the directory the file is in, or delete the file and use cvs checkout or cvs update to recreate it.

The cvs unedit command sets the target file read-only, notifies CVS to signal users watching for unedits, clears you from watching the file if you had a temporary, cvs edit-based watch, and reverts the file to the repository revision on which it was based.


If you callcvs unediton a file that is not currently set for watching, CVS can revert the file only if CVS can contact the server.

Deleting the file and issuing cvs checkout or cvs update notifies watchers, clears you from watching the file, returns the file to the latest repository revision, and sets the file read-only if it is still a watched file.

Issuing cvs release or deleting the file and then issuing cvs checkout or cvs update sends a notification to users watching for an unedit and clears you from a temporary watch. Using cvs release also sets the directory to no longer be a sandbox directory.

Committing an edit

Use cvs commit to save your changes to the repository. This command also clears your edit signal, sets any watched files to read-only, signals users watching for commits, and clears you from watching the file if you had a temporary watch set on it.

Listing Watchers and Editors

Before editing a watched file, you should use the cvs editors command to see whether anyone else has issued cvs edit to indicate they are editing the file. You might also want to know who is watching the file you're about to edit.

The cvs watchers filename commandlists the people currently watching the file, showing their email addresses stored in the notify or users files in the repository's CVSROOT directory.

The cvs editors filename command lists the people currently editing the file, their email addresses, the time they began working with the file, and the host and path of the directory containing the file.

See Example 5-6 for an example of the cvs watchesand cvs editors commands.

Example 5-6. Using cvs watchers and cvs editors

bash-2.05a$ cvs watchers
Changelog   doppel     edit     unedit     commit
INSTALL     doppel     edit     unedit     commit
Makefile    doppel     edit     unedit     commit
     jenn   edit       unedit   commit
bash-2.05a$ cvs editors Makefile
Makefile     jenn     Tue Sep 17 12:13:44 2002 GMT     helit /home/jenn/cvs/wizzard

The syntax of cvs watchers is:

cvs [cvs-options] watchers [command-options] [filenames]

The syntax of cvs editors is:

cvs [cvs-options] editors [command-options] [filenames]

Both commands can take filenames, directory names, or modules as parameters and use the sandbox directory as a parameter if no other parameter is given. Both accept the-l (local) and-R (recursive) command options.

Reserving Files

CVS has a method of exclusive development that is based on reserving the ability to commit files, so that only a single user can commit a reserved file. This is useful when you want to enforce exclusive development, especially when you have files that cannot be merged and users who are not comfortable with the honor system that cvs watchrelies on.

This method requires the rcslock script (distributed in the contrib subdirectory of the CVS source code), file locking set to strict (the CVS default), the assistance of the repository administrator, and the active support of the developers. The rcslock script is provided as is; currently, it is an unsupported part of the CVS distribution.

File locking is set to strict by default in CVS, so there should be no need to set it that way manually. You can confirm the lock status of a file with the command cvs log -h filename.


Do not use the cvs admin -U command on any files in your project. This sets file locking to nonstrict and can cause problems. File locks can be set strict again with cvs admin -L.

Installing and Configuring rcslock

The rcslock script is distributed with the CVS source code. Chapter 2 includes the URL for the CVS source code, and most Linux or Unix packaging systems include an option to install the source from the package. In CVS 1.11.5, the rcslock script is called previous versions, it was called The CVS build script attempts to generate a version called rcslock, with a Perl invocation as the first line.

Install the rcslock script by copying it from the contrib directory to a sensible location and ensuring that your CVS users have permission to execute it. I recommend using /usr/local/lib/cvs as the location for this script, because /usr/local/lib is a standard location for components of locally installed software such as CVS. Edit the commitinfo file in the repository's CVSROOT directory and add a line to invoke the script:

                  /usr/local/lib/cvs/rcslock [options]

If you are using a copy of rcslock that has the .pl or .in extension, you need to include the full filename, with extension, in the commitinfo file. The ALL keyword may be replaced by a regular expression that covers the directories or files for which you wish to reserve checkouts. The regular-expression patterns used in CVS are explained in Chapter 11. Example 5-7 shows a commitinfo file that includes rcslock configured for the wizzard project. The characters after wizzard prevent CVS from matching names likewizzard-libs and wizzardly, yet still match wizzard/src or wizard/docs.

Example 5-7. Configuring commitinfo to include rcslock

^wizzard\(/\|$\)  /usr/local/lib/cvs/rcslock

The path in the rcslock file should be the path you installed the script to. The available options for the script are -v and -d, for verbose and debugging modes, respectively. The rcslock script runs quietly if no options are given.

Reserving a File

When using rcslock , reserve a file before you start editing it. Reserving the file ensures that no one else can commit it until you commit it or release it.

To reserve a file, lock it with the command cvs admin -l filename. The cvs admin -l command is a CVS front end to the RCS file-locking command. The rcslock script uses the RCS file lock to prevent anyone else from committing to the file before you do. CVS prevents you from locking a file that is already locked on the same branch or trunk. CVS and rcslock automatically release the lock when you use cvs commit on the file.

Example 5-8 shows an attempt to lock a file that has already been reserved.

Example 5-8. Failing to lock a reserved file

bash-2.05a$ cvs admin -l Makefile
RCS file: /var/lib/cvs/wizzard/Makefile,v
cvs [server aborted]: Revision 1.6 is already locked by doppel

Example 5-9 shows locking a file using rcslock.

Example 5-9. Locking with rcslock

doppel@teppic$ cvs admin -l Makefile 
RCS file: /var/lib/cvs/wizzard/Makefile,v
1.3 locked

Committing a File

When rcslock is active, you cannot commit a file if someone else has a lock on that file. Example 5-10 shows the error message CVS displays when you attempt to commit a file reserved by another user.

Example 5-10. Failing to commit a reserved file

jenn@helit$ cvs commit Makefile
cvs [server aborted]: Revision 1.3 is already locked by doppel
cvs commit: saving log message in /tmp/cvsuFw5r5

Example 5-11 shows a successful commit of a file reserved with rcslock. Committing a file also unlocks it so that another person can reserve it.

Example 5-11. Committing a reserved file

jenn@helit$ cvs commit Makefile
Checking in Makefile;320C written
/var/lib/cvs/wizzard/Makefile,v  <--  Makefile
new revision: 1.4; previous revision: 1.3

Releasing a File

If you wish to abort the changes to a file, you also need to unlock it so that someone else can reserve it. To unlock a file without committing changes, run the command cvs admin -u filename. This is the CVS front end to the RCS file-unlocking command. Example 5-12 shows unlocking a file with rcslock.

Example 5-12. Unlocking with rcslock

doppel@teppic$ cvs admin -u Makefile 
RCS file: /var/lib/cvs/wizzard/Makefile,v
1.3 unlocked

Combining rcslock with watch

I recommend using the rcslock file-reserving technique in combination with cvs watch. Use cvs watch to allow your project team to communicate which person is editing which file, and use rcslock to enforce exclusivity.

If you are using the command-line client, you can create a shell script that calls both cvs edit and cvs admin -l, to cut down on typing. You may also want a script for cvs unedit and cvs admin -u. Example 5-13 shows a bash script that executes both cvs edit and cvs admin -l on every file it acts on. Call this script with scriptname filenames. This script works only for files without whitespace in the filename.

Example 5-13. Script for cvs edit and cvs admin -l

#! /bin/sh
cvs edit $*
cvs admin -l $*

Comparing File Revisions

As your project develops, you sometimes need to compare a current revision with an old one, or compare two older revisions with each other. This usually happens when several developers are working on the same file and you need to know which changes were made to a file since you last worked on it.

The cvs diff command compares two revisions of a file and displays the differences. It uses a version of the GNU diff program internal to CVS; this code is also used when revisions are merged during cvs update.

The diff command and the similar rdiff command are also useful for creating patches to be installed by the GNU patch program.

cvs diff has the following syntax:

cvs [cvs-options] diff  [command_options] [filenames]

You can call cvs diff with filenames, directories, or module names. If you don't give a filename, the current working directory is the default.

Usually, you call cvs diff with at least one -r tag or -D date command option. If you invoke it with a single -r or -D parameter, CVS compares the current copy in the working directory with the version in the repository. For example, if you check out revision 1.6 of Makefile, edit the file, then run cvs diff -r 1.6 Makefile, diff displays the changes you made to Makefile since you checked it out.

If you invoke cvs diff with two -ror -D options, CVS compares the two revisions against each other. The command cvs diff -r 1.5 -r 1.7 Makefile displays the changes between revisions 1.5 and 1.7.

Example 5-14 shows a diff command that compares revisions 1.2 and 1.3 of the Makefile file, with the option to display a few lines of context around each change. The output starts with a header listing the filename, the repository copy of the file (listed as RCS file), the revisions to be retrieved, the diff options, and the times the revisions were committed.

diff then shows the sections that were changed. The diff in Example 5-14 shows the changes that occur when keywords are expanded, so the contents of the lines should help you understand the diff.

Example 5-14. Using cvs diff

bash-2.05a$ cvs diff -c -r 1.2 -r 1.3 Makefile
Index: Makefile
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =
RCS file: /var/lib/cvs/wizzard/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -c -r1.2 -r1.3
*** Makefile     1 Sep 2002 06:57:23 -0000     1.2
--- Makefile     12 Sep 2002 12:57:40 -0000    1.3
*** 2,10 ****
  # Makefile for the Wizzard project
  # First created by J Vesperman, 1 September 2002
! # Current revision $Revision: 1.3 $
  # On branch $Name:  $ (not expanded if this is the trunk)
! # Latest change by $Author: madd $ on $Date: 2003/07/07 21:52:50 $
  # Initial declarations
--- 2,10 ----
  # Makefile for the Wizzard project
  # First created by J Vesperman, 1 September 2002
! # Current revision $Revision: 1.3 $
  # On branch $Name:  $ (not expanded if this is the trunk)
! # Latest change by $Author: madd $ on $Date: 2003/07/07 21:52:50 $
  # Initial declarations
*** 34,39 ****
--- 33,41 ----
  # Log record for Makefile changes:
  # $Log: ch05.xml,v $
  # Revision 1.3  2003/07/07 21:52:50  madd
  # madd SC edits
  # Revision 1.2  2003/06/27 21:47:43  madd
  # madd R2 conversion edits
  # Revision 1.1  2003/06/26 22:22:10  madd
  # Initial revision
+ # Revision 1.3  2002/09/12 12:57:40  jenn
+ # Trying again with the wrappers..
+ #
  # Revision 1.2  2002/09/01 06:57:23  jenn
  # Initial code in the Makefile.

The first change occurs in the headers to the makefile, when the revision number and date are changed. These changes overwrite lines in the old revision, so the changed lines are denoted with an exclamation point (!) in the left column. The revision listed first in the parameter list is shown first, followed by the second revision.

The second change to the file is the new log message. This is only shown once, with plus marks (+) in the left column to show that the line was added.

Chapter 10 provides the full list of symbols and meanings for cvs diff.


In CVS 1.11.1 and later, you can also use cvs diff to generate files for patch.

The cvs rdiff command is a variant of cvs diff that can be used to create a patch file that can be installed using the standard GNU patch command. cvs rdiff is useful for publishing updates of programs. It does not require a sandbox but does require file, directory, or module name parameters. If cvs rdiff is used outside a sandbox, the repository path must be given with the -d CVS option or the CVSROOT environment variable. If cvs rdiff is used in a sandbox that connects to a repository other than the one you want to work from, the repository path must be given with the -d CVS option.

cvs rdiff has the following syntax:

cvs [cvs-options] rdiff  [command_options]   filenames

The filenames parameter can be one or more directories, filenames, or module names. Output from cvs rdiff is directed to stdout. If you intend to use the output as a patch file, you can redirect it to a file using the > shell operator. Example 5-15 shows how to make a patch for handheld.c that upgrades the file from revision 1.1 to the most current revision.

Example 5-15. Making a patch file

bash-2.05a$ cvs rdiff -r 1.1 -r HEAD wizzard/src/handheld.c  > patchfile

cvs diff and cvs rdiff take two types of options. The first are standard options that determine which revisions of which files are checked and which keyword mode is used. The second set of options determines the output format and affects how CVS compares the files. Chapter 10 provides the full list of options to cvs diff and cvs rdiff.

One of the most useful cvs diff (and cvs rdiff) options is -y, also available as --side-by-side. This option displays the differences between the files by showing the relevent lines beside each other. You will want to have a wide terminal window when using this option. Example 5-16 shows a side-by-side diff between the current revision of a file in the sandbox and the most recent revision in the repository.

Example 5-16. Displaying diff side-by-side

bash-2.05a$ cvs diff -y server.c
Index: server.c
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =
RCS file: /var/lib/cvs/wizzard/src/server.c,v
retrieving revision 1.1
diff --side-by-side -r1.1 server.c
/*                            /*
 * server.c                    * server.c 
 * Sep 13 2002                 * Sep 13 2002
 * Developer: Jenn Vesperman   * Developer: Jenn Vesperman 
 *                             * 
 * server code file            * server code file
 */                            */
                             > #include <iostream.h>
                             > int main (  ) {
                             >   cout << "Hello World\n";
                             >   return (0);
                             > }

Displaying Recent Changes

The cvs annotate command displays the most recent change for each line of a file in the repository. This is very helpful when you need to know which change broke the compilation or who rewrote a key paragraph in the documentation incorrectly. This command works off the repository copy, not the sandbox copy, so it does not show any changes in the sandbox that were not committed.

For each line, cvs annotate shows the revision number for the last change, the user, the date, and the contents of the line. This is a quick way of discovering who made which change. Example 5-17 shows some of the annotations for the wizzard.h file.

Example 5-17. Using cvs annotate

bash-2.05a$ cvs annotate src/wizzard.h
Annotations for src/wizzard.h
1.6     (doppel   15-Sep-02): #include "config.h"   /* using autoconf */
1.6     (doppel   15-Sep-02): #include "options.h"  /* manual options that can't 
1.1     (jenn     11-Sep-02): 
1.2     (jenn     13-Sep-02): #define TRUE 1
1.2     (jenn     13-Sep-02): #define FALSE 0

cvs annotate has the following syntax:

cvs [cvs-options] annotate [command-options] [filenames]

If you don't give a filename, cvs annotate attempts to run annotate on all the files in the current sandbox. The filenames can be directories or modules.


annotate doesn't work correctly on binary files. CVS tries to display them as text files, which can trigger the bell character and mess with your terminal window.

Use the -Foption to run cvs annotate on binary files. You can select which revision to display with-D date and -r revision (or tag), and you can use the -foption to force CVS to use the most recent revision on the trunk if no revision matches the specified date, revision, or tag. cvs annotate uses the usual -l and -R options to control local and recursive operation, respectively.

Displaying File History

The cvs log command displays information about files, directories, or modules. You pass a parameter to specify which file, directory, or module you are interested in. If you don't specify anything, cvs log displays log information about all files in the current sandbox directory. The user-provided part of this log information is entered when you run cvs commit or when you set the -m command option to cvs add.

cvs log is often used to help decide which two revisions to use to create a patch file, to determine a branch point, or to provide a quick guide to what the other developers are doing in a multiuser environment. Informative log messages are very important for all of these uses.

The options to cvs log reduce the amount of information it shows. By default, it displays everything it can. For each file, it displays a header; then, for each revision of the file it displays the revision number, date, author, state, log message, and number of lines added and deleted in that revision.

Example 5-18 shows a simple use of cvs log. Note that the keyword-substitution mode is the default mode, generating both keyword and value, and that the log message in revision 1.1 mentions both files that were added at the time.

Example 5-18. Using cvs log

bash-2.05a$ cvs log main.c
RCS file: /var/lib/cvs/wizzard/src/main.c,v
Working file: main.c
head: 1.9
locks: strict
access list:
symbolic names:
     beta_0-1_branch_root: 1.9
     pre_beta_0-1: 1.8
keyword substitution: kv
total revisions: 9;     selected revisions: 9
revision 1.9
date: 2002/09/12 08:14:19;  author: jenn;  state: Exp;  lines: +0 -0
Final test of re-addition methods.
revision 1.1
date: 2002/09/11 13:33:13;  author: jenn;  state: Exp;
Added main.c: parses parameters and calls functions in other files.
Added wizzard.h: defines compile-time global variables.
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =

The header for each file includes the path to the repository copy of the file, the name of the sandbox (or working) file, the revision number of the head revision, the current branch, if any, the lock status, the access list, tag (or symbolic) names and revision numbers, any keyword-substitution modes, the number of total revisions for the file, the number of revisions the log command is to display, and any description of the file stored in CVS.

The access list and the description are historical and exist because the files are stored in an RCS-based format. CVS relies on strict locking, so the lock status should always be strict. CVS files are created with strict locking; locking can only be set nonstrict through the cvs admin command or through editing the file directly.

cvs log has the following syntax:

cvs [cvs-options] log [command-options] [filenames]

If no file, directory, or module names are given, cvs log assumes the current sandbox directory as the parameter. The options to cvs log differ from the standard options for most other commands.

Most of the options to cvs log restrict the revisions for which information is displayed. cvs log normally displays only those revisions that match all the options you specify, so as you add options you tend to reduce the set of revisions for which cvs log displays information. For example, if both -b and -r options are selected, cvs log displays only the revisions that match both-b and -r parameters. If other options are also selected, cvs log displays the revisions that match -band -r and also fit the other options.

The -b option limits the cvs log output to the default branch, usually the latest branch off the trunk. -rrevision-range restricts the output to the revisions given in the revision range. Chapter 10 provides the syntax to use in specifying the revision range.

The-wusernames option limits cvs log output to revisions checked in by users in a comma-separated list of usernames. The list of usernames should not include spaces, and there should be no space between the -w and the list.

The -h and -t options limit the amount of information cvs log displays with each file. -h limits it to the header, and -t limits it to the header and the description. Using the -S option tells cvs log not to display the header of files where at least one revision will be displayed.

Chapter 10 provides the full list of options for cvs log.


  1. The CVS username is usually the system username, but it may be a special username if you are connecting with pserver. See Section 8.7 in Chapter 8.
Personal tools