How to implement SVN pre-commit hook with best performance?
We have the following tools in place:
- Subversion (Version 1.5.9)
- Polarion (version 3.2.2)
Polarion is based on Subversion, so on every action that changes anything (which is often the case), Polarion will use a Subversion commit to ch开发者_开发百科ange anything. All things are currently stored in one and only one repository, so every commit of every user (some 100-200 on the same repository) will trigger the pre-commit hook.
So what is the best strategy to provide pre-commit hooks that will
- trigger only for some, but not all projects
- run as fast as possible, because every pre-commit hook will block all other commits.
We have tried to implement pre-commit hooks with Java (using SVNKit), but this will start on every commit a Java VM. So any ideas how to implement that nicely?
I've used Python recently to implement a post-commit hook that scans for different projects in the same repository and then acts accordingly. I'm new to Python so there may be some inefficiencies in the following script (or even outright errors), but it does work for our purposes:
#!/usr/bin/env python
import commands
from subprocess import *
import os
import sys
# This is a post-commit hook. The arguments passed to the hook
# are different than a pre-commit hook, and the syntax/use for
# svnlook will probably be different too.
def check_repo_and_do_stuff(repos, rev):
dirs_changed_cmd =
p1 = Popen('%s dirs-changed %s -r %s' % (SVNLOOK, repos, rev)
dirs_changed = p1.communicate[0]
for line in dirs_changed:
if line.find('/part-of-path-for/project1') >= 0:
do_stuff_for_project1()
if line.find('/part-of-path-for/project2') >= 0:
do_stuff_for_project2()
def do_stuff_for_project1()...
def do_stuff_for_project2()...
SVNLOOK='/usr/bin/svnlook'
# Take the arguments that svnserve passes on the command-line
repos = sys.argv[1]
rev = sys.argv[2]
check_repo_and_do_stuff(repos, rev)
I hope this can help.
-Zachary
If Java is slowing things down, but Java is only used a small percentage of the time, then I'd write the hook in something lightweight. i.e. on Windows, use a .bat file. Then, for the projects (or files or users) that require it, call the more expensive Java hook from the lightweight hook. That way, you'll only slow down the Commit when it's needed.
Hook scripts based on Java are slow and impact response time of Subversion in general, esp. if you work on heavy loaded servers. Best performance will be achieved to implement audits and metrics to improve quality. By tracking traceability in audits project team can follow its progress gaining better and better levels.
In many cases heavy tasks are better handled by a continous integration server that monitors the repository for changes. This makes sure that the scripts never slow down the repository and these tools usually have better error reporting for build, verification and update tasks.
The disadvantage is that they can't deny a commit from happening... Those tasks must be handled as a hook, but in practice you can delay most work to some post commit processing.
The best thing you can do is stop using one repository for everything.
In addition to better performance, this will give you fine-grained control over your repos, allowing you to have separate access control, separate hooks per repo (project), etc.
精彩评论