In the previous post, Converting a CVS project to a Git repository, I describe using cvs2git to convert a CVS project to a git repository. After I made the conversion, I wanted to make the CVS project read-only.
There’s probably no reason to keep the CVS project around (the history is in the git repo, and I have backups of the CVS project), but it felt like the right thing to do. The blog post Read-only CVS access for only certain projects was extremely helpful to accomplish this.
The key component is the CVSROOT/commitinfo
file within your CVS repository. Like any other project in CVS, you need to check this out to make changes:
cvs co CVSROOT
cd CVSROOT && vi commitinfo
You specify a regular expression and a script to run before committing data to a project matching that regular expression. If the script exits with a non-zero exit code (indicating an error), the commit is aborted. For initial testing, I used false
(or /bin/false
) for the script component, which does nothing and returns an exit code of 1.
I had some problems with this, in part because I was not sure what the project string would look like. I tried a few things:
^/testrepo/.* false
(didn’t work)
^testrepo/.* false
didn’t work
^t.* false
worked, but would match other projects as well
Eventually I switched to using the read-only-project.sh
example from the aforementioned blog post, which printed out the values of the project path and the filenames to be committed.
From there I could see that the project path:
- Does not include an initial slash
- Does not include a trailing slash
- May include additional slashes if the project contains subdirectories
The same script suggests including the following in commitinfo:
^projectname/.* /path/to/script "%p" %s
That regular expression does not work — it would match a file at projectname/subdir1/file1 but not projectname/file1.
And what do the “%p” and %s mean? From C.3.4 Commitinfo:
Currently, if no format strings are specified, a default string of ` %r/%p %{s}’ will be appended to the command line template before replacement is performed, but this feature is deprecated.
I found another document, C.3.1 The common syntax, which describes the format strings.
p
– the name of the directory being operated on within the repository.
{s}
– the file name(s), in curly braces because it is a list
The same page includes a sample regular expression that solves the problem I was having:
^module\(/\|$\)
Finally, here is what I added to CVSROOT/commitinfo
:
^testrepo\(/\|$\) /usr/local/script/read-only-project.sh
Note that this script needs to exist on the same machine as the CVS repository (which may or may not be the same machine as your checked-out copy).