Question

Is it possible to use the commit message in a pre-commit hook in CVS? The CVS server is running remotely, and I access it using pserver.

Ideally, I want to allow the commit if the files pass the filter or the commit message contains certain text.

I don't have a choice to use another versioning system.

Was it helpful?

Solution

Here are some useful tutorials to read more:

http://durak.org/sean/pubs/software/cvsbook/The-commitinfo-And-loginfo-And-rcsinfo-Files.html
http://durak.org/sean/pubs/software/cvsbook/The-verifymsg-And-rcsinfo-Files.html#The-verifymsg-And-rcsinfo-Files

You can't do what you want with just one hook but you can use two hooks, commitinfo will let you verify the files themselves and verifymsg will let you verify the message. Both can be used to cancel the commit (the programs just need to exit with status 1). In case you weren't aware, checkoutlist, commitinfo and 'verifymsg' can all be found in the CVSROOT directory of your repository. I would recommend putting any scripts you write as hooks in that directory as well, but it doesn't really matter as you get to specify the full path. Also, perl is not necessary or required, just simple for me to write some (silly) examples in:

checkoutlist

# these files will be automatically checked out for you
acceptable

verifymsg

# specifies which file to run as hook, %l is filename of log message
# bar$     /path/to/repo/CVSROOT/verify_ends_in_bar %l
DEFAULT    /path/to/repo/CVSROOT/acceptable %l %s

acceptable

#/usr/bin/perl -w

use strict;
use warnings;

# this would be simpler if cvs passed sane arguments
my ($logfile, $dir, @files) = @ARGV;
my $grep = `grep -i 'accept liability' $logfile`;
exit 0 if $grep;

my $found = 0;
foreach my $file (@files) {
    my $path = join '/', $dir, $file;
    die "Can't find file $path" if ! -e $path;
    my $grep = `grep -i 'evidence of any deliberation' $path`;
    $found++ if $grep;
}
die "You must accept liability or show evidence of deliberation" if $found < @files;

Caveat emptor: I wrote most of this off the top of my head with no testing so I can't guarantee it works but it should get you at least close.

Edit again, I just realized that I was originally wrong and you can pass both the logfile and the committed filenames to verifymsg making the answer quite a bit simpler.

OTHER TIPS

The CVS::Trigger Perl module seems to have an experimental feature that allows for caching values between the call of different triggers. The page explicitly mentions passing the filenames from commitinfo to verifymsg, so maybe it helps you to achieve what you want.

You can use the verifymsg file in the CVSROOT directory. You can configure it to call a script which can verify the contents of the checkin comment. You can reject the commit by returning non-zero.

The default verifymsg file contains more details.

I have been dealing with the same issue. So far my best solution has been to get the parent process Id (getppid()) and use it ina temp file that I can put the list of files into from commitinfo. This parent ID seems to be the same for the verifymsg process (on AIX at least). Good luck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top