(Prep for a multi-directory CVS commit)




This program is designed to run from CVS's commitinfo administrative file and make a note of the last directorie involved in the commit. It is used to support merging of multi-directory CVS commits into a single notification by cvslog (cvslog knows to stop merging commits when it sees the notification for the final directory recorded by cvsprep).

It should be run from commitinfo with something like:


If you are using CVS version 1.12.6 or later, the format strings for commitinfo rules have changed. This line should instead be:

    DEFAULT     $CVSROOT/CVSROOT/cvsprep -- %r/%p

once you've set UseNewInfoFmtStrings=yes in config.

The directory in which the commit is occurring is saved in a file named directory in a directory in TMPDIR named cvs.<uid>.<group>, where <uid> is the UID of the committing user and <group> is the process group of the commit process. If TMPDIR is not used, /tmp is used as the parent directory.

For details on how to install this program as part of a cvslog installation, see cvslog(1).


-h, --help

Print out this documentation (which is done simply by feeding the script to perldoc -t).

-v, --version

Print out the version of cvsprep and exit.


can't create %s: %s

(Fatal) cvsprep was unable to create either the directory or the file in that directory needed to pass information to cvslog, or the directory already exists and is owned by someone other than the current user. The directory for this commit won't be recorded, and cvslog will therefore not merge this multi-directory commit.

CVS didn't provide a directory

(Fatal) No directory was given on the cvsprep command line. If run out of commitinfo as described above, CVS should pass the name of the directory in which the commit is happening as the first argument to cvsprep.



cvslog expects this file to contain the name of the final directory affected by a multidirectory commit. cvsprep creates the parent directory and stores its first argument in this file.

The first %d is the numeric UID of the user running cvslog. The second %d is the process group cvslog is part of. The process group is included in the directory name so that if you're running a shell that calls setpgrp() (any modern shell with job control should), multiple commits won't collide with each other even when done from the same shell.

If TMPDIR isn't set in the environment, /tmp is used for TMPDIR.



If set, specifies the temporary directory to use instead of /tmp for storing information about multidirectory commits. Setting this to some private directory is recommended if you're doing CVS commits on a multiuser machine with other untrusted users due to the standard troubles with safely creating files in /tmp. (Note that other programs besides cvslog also use TMPDIR.)


cvsprep inherently creates directories in TMPDIR (/tmp by default) with very predictable names. It creates directories rather than files because this should be less risky, but this is still something of a security risk. Because of this, I highly recommend that you set TMPDIR to some other directory that only you have write access to, such as a subdirectory of your home directory.

For more warnings, see cvslog(1).


This process of noting the final directory of a commit so that cvslog knows when to stop merging is a horrible hack. There's just no better way to do it given how CVS handles commit notification, which is completely undocumented and truly bizarre.


cvs(1), cvsprep(1).

Current versions of this program are available from the cvslog web site at <>. cvslog is available from this same location.


Russ Allbery <>.


Copyright 2001, 2002, 2003, 2004 Board of Trustees, Leland Stanford Jr. University.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Last modified and spun 2014-07-26