5.3. 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 feature 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 watch relies 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.
5.3.1. 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. The file in the package may be an rcslock.pl or an rcslock.in file, or even just rcslock. In recent versions of CVS, 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:
ALL /usr/local/lib/cvs/rcslock [options]
If you are using a copy of rcslock that has the .pl extension, 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 like wizzard-libs and wizzardly, yet still match wizzard/src or wizard/docs.
Example 5-7. Configuring commitinfo to include 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.
5.3.2. 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 frontend to the RCS file-locking command (RCS, or Revision Control System, is a tool that CVS uses to store files, and that the rcslock script exploits to do its job). The rcslock script runs when CVS commits a file, and 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 run 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
Example 5-9 shows locking a file using cvs admin.
Example 5-9. Locking with cvs admin
5.3.3. 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
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
5.3.4. Releasing a File
If you wish to abort the changes to a file, unlock it so that someone else can reserve it. To unlock a file without committing changes, run the command cvs admin -u filename. This command is the CVS frontend to the RCS file-unlocking command. Example 5-12 shows unlocking a file with cvs admin.
Example 5-12. Unlocking with cvs admin
5.3.5. 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