We’ve been having some issues with people committing to the subversion server without entering a comment. Its easy to to require a comment using a “pre-commit” hook, which is a script that runs before someone’s changes are committed to the repository. A sample commit hook is supplied with subversion that you can enable to require comments. The problem is it doesn’t report back any error message (users will just get a generic “commit failed” in their svn client), and there is no provision for making sure the comment is a minimum length.
I tried to modify the example script, but I’m pretty bad with shell scripting. I looked for a perl one, which I knew I could easily modify, but couldn’t find any. So I whipped this one up:
#!/usr/bin/perl
# config section
$minchars = 4;
$svnlook = '/usr/bin/svnlook';
#--------------------------------------------
$repos = $ARGV[0];
$txn = $ARGV[1];
$comment = `$svnlook log -t "$txn" "$repos"`;
chomp($comment);
if ( length($comment) == 0 ) {
print STDERR "A comment is required!";
exit(1);
}
elsif ( length($comment) < $minchars ) {
print STDERR "Comment must be at least $minchars characters.";
exit(1);
}
exit(0);
Those error messages get sent back to the client and display just fine in TortoiseSVN or whatever you use.
My subversion server is running on Linux, but the script should run on Windows with little modification, if you have perl installed.
Rob Wilkerson says:
If anyone’s interested in simply modifying the built-in script, here’s what I’ve done:
SVNLOOK=/usr/bin/svnlook
LOGMSG=`$SVNLOOK log -t “$TXN” “$REPOS” | grep “[a-zA-Z0-9]” | wc -c`
if [ “$LOGMSG” -lt 1 ]; then
echo -e “Please provide a meaningful comment when committing changes.” 1>&2
exit 1
fi
The “1>&2” operator redirects to the standard error rather than the standard output which is what allows the message to display in TortoiseSVN. I’ve never run Svn on a Windows box, so your mileage may vary. This works great on a Linux install to which I connect via TSVN, Subclipse and the command line.
Hope this helps.
16 June 2008, 6:08 pmpatrick says:
Where does this go?
18 June 2008, 4:48 pmRyan Stille says:
Patrick, there is a “hooks” subdirectory under your repository directory. All your hook scripts go into there. By repository directory, I mean where your repository is actually stored on the machine that is running the subversion server.
18 June 2008, 4:51 pmpatrick says:
Thanks so much for the quick reply. I must be doing something incorrectly; this is my pre-commit.tmpl in hooks/
REPOS=”$1″
TXN=”$2″
# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
#$SVNLOOK log -t “$TXN” “$REPOS” | \
# grep “[a-zA-Z0-9]” > /dev/null || exit 1
LOGMSG=`$SVNLOOK log -t “$TXN” “$REPOS” | grep “[a-zA-Z0-9]” | wc -c`
if [ “$LOGMSG” -lt 5 ]; then
echo -e “Please provide a meaningful comment when committing changes.” 1>&2
exit 1
fi
# Check that the author of this commit has the rights to perform
# the commit on the files and directories being modified.
commit-access-control.pl “$REPOS” “$TXN” commit-access-control.cfg || exit 1
# All checks passed, so allow the commit.
exit 0
This seems to still let me put a single dot for the comment.
18 June 2008, 5:47 pmRyan Stille says:
You need to rename it to pre-commit, without the “.tmpl” on it, and make sure its executable. I probably should have gotten into more detail in my post.
18 June 2008, 5:49 pmpatrick says:
Thanks a lot. I used your perl script. Couldn’t get the bash script the other guy posted to work.
18 June 2008, 6:06 pmUzo says:
Hi I am trying to write a hook script that will fail the commit if there is no bug id. I am getting frustrated with not being able to do this. I have no technical knowledge though and this is what I encountered. I use the tortoiseSVN client, I noticed that there is no svnlook in my bin directory. I copied it across manually and this script was written for me in python
#!/usr/bin/python
# commit acceptance python client for SVN
import os
import re
import sys
import urlparse
# configure svnlook path
svnlookPath = ‘\”C:\\Program Files\\VisualSVN Server\\bin\\svnlook.exe\”‘
# get committer
try:
f = os.popen(svnlookPath + ‘ author -t ‘ + sys.argv[2] + ‘ ‘ + sys.argv[1])
committer = f.read()
if f.close():
raise 1
committer = committer.rstrip(“\n\r”)
except:
print >> sys.stderr, ‘Unable to get committer with svnlook.’
print >> sys.stderr, svnlookPath
print >> sys.stderr, sys.argv[1]
print >> sys.stderr, sys.argv[2]
sys.exit(1)
# get commit message
try:
f = os.popen(svnlookPath + ‘ log -t ‘ + sys.argv[2] + ‘ ‘ + sys.argv[1])
commitMessage = f.read()
if f.close():
raise 1
commitMessage = commitMessage.rstrip(‘\n\r’)
except:
print >> sys.stderr, ‘Unable to get commit message with svnlook.’
print >> sys.stderr, svnlookPath
print >> sys.stderr, sys.argv[1]
print >> sys.stderr, sys.argv[2]
sys.exit(1)
# print arguments
# print >> sys.stderr, ‘Committer: ‘ + committer
print >> sys.stderr, ‘Commit message: “‘ + commitMessage + ‘”‘
if (re.match(‘^[a-zA-Z]+-[0-9]+([\s]+|$)’,commitMessage)):
print >> sys.stderr, ‘Commit accepted.’
sys.exit(0)
else:
print >> sys.stderr, ‘Commit rejected: This repository requires a commit message to begin with a Jira issue number.\n\reg JIRAPRJ-1’
sys.exit(1)
PLEASE HELP!!!
3 July 2008, 5:10 amRob Wilkerson says:
I’ve never installed Svn on Windows, but “#!” is a Unix script indicator. The paths you reference also appear Unix-centric. Are you sure you installed the Windows version of Svn server (assuming there is such a thing)? Changing the extension to .bat is meaningless if the syntax is that of a Unix shell script.
25 July 2008, 12:42 pmAsim says:
Hi Rob,
Thanks for the quick update. I actually did download the Windows version and for some reason it has the same pre-hooks as unix then.
I followed these steps to install it:
http://blogs.vertigosoftware.com/teamsystem/archive/2006/01/16/Setting_up_a_Subversion_Server_under_Windows.aspx
And its running fine as is, no pre-commits message checks though 🙁
25 July 2008, 1:03 pmAsim says:
Hi Guys,
I’m new to SVN. Its my second day with SVN today and I’m trying to setup a pre-hook to force a properly formatted commit message. I have installed SVN on windows and renamed the pre-hook file to .bat but it throws these error messages.
Does this mean that I need to install some sort of an environment there? Please help!!
Thanks
Error: Commit failed (details follow):
25 July 2008, 12:31 pmError: ‘pre-commit’ hook failed with error output:
Error: ‘#!’ is not recognized as an internal or external command,
Error: operable program or batch file.
Error: ‘#’ is not recognized as an internal or external command,
Error: operable program or batch file.
[ long list of this snipped… ]
Error: ‘REPOS’ is not recognized as an internal or external command,
Error: operable program or batch file.
Error: ‘TXN’ is not recognized as an internal or external command,
Error: operable program or batch file.
Error: ‘#’ is not recognized as an internal or external command,
Error: operable program or batch file.
Error: Unknown command: ‘=/usr/local/bin/svnlook’
Error: Type ‘svnlook help’ for usage.
Error: ‘$SVNLOOK’ is not recognized as an internal or external command,
Error: operable program or batch file.
Felix says:
No Commit Without Comment 🙂
17 September 2008, 12:49 pmMartin says:
I can’t for the life of me get my hooks to print in stderr. Not through a bash script, not in python scripts. I managed to do a few errors in the python script which prompted the python interpreter to write those errors through stderr during a commit 😛 But other than that? It just won’t work.
Any environmental things that need setting up or some such? hm
12 October 2008, 3:00 pmAnonymous says:
What would be a Windows equivalent of this script by editing the .tmpl?
15 May 2009, 10:11 amDave Schinkel says:
I assume this script would not work by pasting it and using it in a Windows environment. So how would you do this in a Windows environment and add this same kind of hook? Anyone, anyone?
31 July 2009, 3:01 pmRyan says:
Dave you could install Perl for Windows and use this script. You'll need to change a few things of course, the path to the svnlook program won't be the same for example.
Or you could try a windows batch file.
31 July 2009, 3:11 pmDave Schinkel says:
Nice, thank you!
5 August 2009, 9:43 amDave Schinkel says:
I was also told by a former collegue that you can just use the property tsvn:logminsize on your entire repository
5 August 2009, 2:00 pmDan Walker says:
Nice, clean Perl script. Thanks!
9 June 2010, 2:48 pmNeil says:
Thanks so much! Beautiful script
9 November 2010, 11:45 pmShah says:
many thanks 🙂
14 April 2011, 4:24 amI am trying to included code reviewer test as well, but being newbie not able to write perl code 🙁
shag says:
can i able to force commands only for cpp files in svn
13 December 2011, 3:27 amsagar says:
hello i m using webfaction hosting and i put that script as pre-commit.sh ..but its not executable ???..can u plz suggest me..??
3 January 2012, 7:31 amKeshav says:
Hello all,
I want to mandate a specific pattern(Should start with AS- ) in the commit message while I commit to SVN . Could someone help me in writing a script for this ?
Any help on this would be greatly appreciated …
Thanks,
10 January 2012, 7:33 amK
Johnny C says:
Thank you all. The STDERR thing is the tricky part that I was looking for.
8 August 2012, 1:24 pmsuma ramesh says:
HI
I want to include Pre commit script..
I have renamed the file from pre-commit to pre-commit.html.
REPOS=”$1″
TXN=”$2″
# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
$SVNLOOK log -t “$TXN” “$REPOS” | \
grep “[a-zA-Z0-9]” > /dev/null || exit 1
# Check that the author of this commit has the rights to perform
# the commit on the files and directories being modified.
commit-access-control.pl “$REPOS” “$TXN” commit-access-control.cfg || exit 1
# All checks passed, so allow the commit.
exit 0
Kindly tell me what are the changes i need to do…
22 September 2012, 1:28 am