Require subversion comments - a perl pre-commit hook

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.

10 Responses to “Require subversion comments - a perl pre-commit hook”

  1. 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.

  2. patrick Says:

    Where does this go?

  3. Ryan 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.

  4. patrick 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.

  5. Ryan 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.

  6. patrick Says:

    Thanks a lot. I used your perl script. Couldn’t get the bash script the other guy posted to work.

  7. Uzo 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!!!

  8. Asim 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):
    Error: ‘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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    Error: ‘#’ is not recognized as an internal or external command,
    Error: operable program or batch file.
    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.

  9. Rob 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.

  10. Asim 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 :(

Leave a Reply