views:

778

answers:

6

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.

A: 

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.

Tom Duckering
I want to reject the commit if the pre-commit hook fails *and* the log message does *not* contain "I accept liability" or whatever. The pre-commit hook ensures that the files are valid, but in the event that committing files that break the rules is necessary I want to ensure that the log mentions it. I want to be able to check both the committed message *and* the committed files before allowing the commit.
dreamlax
The problem is, the pre-commit hook doesn't seem to be able to access the commit message to ensure that the failed verification is logged as deliberate, and the verifymsg hook can't access the changed files to verify that the changes comply with the rules.
dreamlax
You're right, the verifymsg can't get at the files being commited. You'd have to implement them separately. So if one fails the whole commit will fail. Does that do what you want?Also, to clarify, as far as I recall, you can't get at the actual files in the pre-commit hook you're simply told the paths/names.
Tom Duckering
I can get the actual files being committed in the pre-commit hook (with the changes that were made). I think I'll have to implement them separately, but I only want it to fail if the files failed validation and there is no evidence of any deliberation.
dreamlax
A: 

Check this link for your answer

http://durak.org/cvswebsites/doc/cvs%5F197.php#SEC197

Rashid Khan
This doesn't help, I still can't do what I want to achieve. I want to check the files, if the files fail the test then I want to check the commit message. If the commit message contains a certain word or phrase, then the commit is allowed, even though the files failed the test. If the files *did* pass the test, then the commit message isn't inspected.
dreamlax
+3  A: 

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.

deepwaters
Thanks for that. I would go for this answer except that as you stated it is experimental, and I need something a little more concrete.
dreamlax
+1  A: 

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.

Rob Van Dam
What version of CVS have you tried this with? With my version, when I specify %s in the `verifymsg` file I don't get the committed files, I still only get the log file.
dreamlax
@dreamlax I haven't ever had a need to use `verifymsg` like you have, I've only used `loginfo` and `commitinfo` but I thought I had found some examples online that showed `verifymsg` accepting both the log file and %s. If that doesn't work for you, you may have to fall back to some kind of communication between a `commitinfo` script and the `verifymsg` script.
Rob Van Dam
@dreamlax Also, could you make do with requiring both criteria? Then a earlier version of my answer which used commitinfo and verifymsg would work for. I guess it depends on whether you meant logical **or** or more typically english **or**.
Rob Van Dam
@Rob: I think I'll have to make do for the time being. I can always check the commit messages manually for a while. Perhaps I should move away from CVS altogether, even though it has been rather suited to my needs up until now.
dreamlax
@dreamlax Yeah, the commit hooks are really useful for simple things but they get pretty tedious to deal with as your requirements get more complex.
Rob Van Dam
A: 

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.

Brad
A: 

Hi, i want to force commit messages when a user commits in cvs server... can any one help me out in this. I have made some changes in verifymsg file in CVSROOT folder. The changes made are as below: DEFAULT /repositoryname %l %s.

Can any one help me out in this

Mohsin