Archive for June, 2012

Read-only CVS access for only certain projects

Friday, June 15th, 2012

I’ve recently decided to move from CVS to Subversion, but I’m not ready to move everything at once. Thus, I have decided to move some things and save others for later. In order to do that properly, I need to make some projects in CVS read-only while allowing others to remain active.

A bit of Googling easily reveals how to make CVS entirely read-only (add an empty ‘writers’ file to the CVSROOT project or to make projects write-only on a project-by-project basis (by setting group file permissions on the server), but those techniques are too heavy-handed for me: I want some projects to be writable and I want to be able to check-out old copies of read-only projects. Neither of the above techniques will do that for me.

So, I looked-into something I should have known all about after running a CVS repository for nearly 9 years: the commitinfo file. You can read all about the commitinfo file online. I decided that since I could use commit-time “checks” to veto any commit for virtually any reason, I could certainly affect read-only access on a project-by-project basis.

So, I set my commitinfo file up like this:

^read-write-project\(\|$\) true %n
^otherreadwriteproject\(/\|$\) true %n
DEFAULT /path/to/read-only-project.sh "%p" %s

Here is the script called read-only-project.sh:

#!/bin/sh
#
# This script is intended to be used as a failure script for CVS projects
# that are now in a read-only state.
#
# Configure this in CVSROOT/commitinfo like this:
#
# ^projectname/.* /path/to/script "%p" %s
#
# Or, to make all projects read-only, you can do this:
# DEFAULT /path/to/script "%p" %s
#
echo "========================================================================="
echo "Cannot commit the following files because '${1}' is now read-only:"
shift
while (( "$#" )) ; do
echo "  $1"
shift
done
echo "========================================================================="

# Exit with a non-zero return code
false

The magic is all in the last line of the script:

false

This allows the script to exit with a non-zero status and therefore block the commit from occurring. This also allows all projects to be checked-out, updated, etc.: just no commits to those projects, which is exactly what I want.

Updated 2012-06-15 15:17 EDT – fixed regular expression for project-selector.

Updated 2012-06-19 15:16 EDT – Fixed regular expression again.