[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

How to debug hook scripts [LONG] (was Re: Hook Script problem with no error output)

From: John Peacock <john.peacock_at_havurah-software.org>
Date: 2007-10-12 12:59:58 CEST

ratnavel ps wrote:
> Hi all,
>
> Even I'm facing the same issue can anuone help me out to fix this..........

OK, here is breakdown of how to deal with pre/post commit scripts. I'm starting
with a strong suggestion that you *don't* write your own script - there really
is no reason to do this, as there are perfectly functional examples available here:

        http://subversion.tigris.org/tools_contrib.html

as well as the simpler shell scripts included inside the hooks directory of
every repo. I can also recommend my own solutions to keeping a working copy
synced with a repository (if that is your actual goal):

        http://search.cpan.org/dist/SVN-Notify-Mirror/
        http://search.cpan.org/dist/SVN-Notify-Config/

which do far more than that, and in a simple-to-manage way.

However, if you are intent on recreating the wheel, here are some guidelines to
working with hook scripts (in order of operation, don't just skip around).

1) Always develop your hook scripts on a test repository. You would think this
would be obvious, but a surprising number of people blindly add hook scripts to
their primary repository and then break other people's commits. If you are
trying to do anything remotely tricky (like force all commits to a given path to
require a ticket number for example), recreate enough of your repository layout
to make the test valid. You *do not* need to use a copy of your primary
repository, just enough of a skeleton to mirror the layout.

2) Use the examples provided as a basis. All of the template scripts in the
repo/hooks directory /work/. And by work, I mean that the instructions inside
must be followed (copy the pre-commit.tmpl file to pre-commt and mark it
executable). You would be wise to read and try the example hook scripts before
writing your own. In particular, you need to understand that the hook scripts
must have the equivalent of 'exit 0' to signify that the hook succeeded or must
use 'exit 1' (actually any non-zero return) to signify that the hook failed.

3) Write your script and confirm it is working *outside* of Subversion itself
first (whether you are running Apache or svnserve). Your script will receive
different values on the commandline, depending on what hook the script is
prividing (the hooks/*.tmpl have full details). For discussion purposes below,
I wll focus solely on post-commit, for the simple reason that you can run it on
any revision number on your repo after the fact for testing. Pre-commit is
trickier because you need to have an active transaction, so leave that for later.

At this point, let's have an example. Attachment 1 is a recipe for setting up a
single project repository with a couple of files. I'll wait while you download
that and set this up in your /tmp directory. Those of you playing along in
Windows will need to do something slightly different, sorry, but I no longer
have to use Windows [YEAH!!!], so I can't test my examples. My advice is to
install Cygwin, which will allow you to use the same syntax as any other *nix
system.

OK, are you ready now? cd into the test-repo/hooks directory and copy
post-commit.tmpl to post-commit and mark that file as executable. Edit the
script you just copied and delete the line that starts with
"commit-access-control.pl..." since we aren't going their yet (it requires more
setup). Instead append the following lines (NOTE, don't include the '>'
character; I'm only showing those lines as "quotations" to make them stand out
from the rest of this bloated text):

> CHANGED=`svnlook changed -r $REV $REPOS`
>
> exec 1>&2
> echo "These were the file(s) that were changed:"
> echo $CHANGED

If you don't know what that does, the 'exec 1>&2' line changes the behavior so
that echo now goes to STDERR, which we will see is important later.

Let's find out whether that worked, without involving Subversion at all. DON'T
SKIP THIS STEP! You need to write and understand what your script will do by
itself before involving the interface between Subversion and your script. So,
still from within the hooks folder, run this:

$ ./post-commit $PWD/.. 1
These were the file(s) that were changed:
A branches/ A tags/ A trunk/ A trunk/dir1/ A trunk/file1 A trunk/file2

and if you set up the repo as in Attachment 1, you should see that same output.

Now, let's continue with the numbered recommendations:

4) Once you have confirmed that your post-commit script executes and does what
you expected it to do, you can test it in Subversion itself. Go back and edit
the post-commit script and add

> exit 1

to the bottom of the script. Why "1" you might ask? This signifies to
Subversion that the script *failed* and this is the only time that you will
receive any output from the script. Attachment 2 is a transcript of the steps
to add two new files and try and commit them. The important thing to note is
that Subversion reported that the script returned non-zero as well as displayed
the message we printed to STDERR.

Now change the post-commit script and make it 'exit 0' and create another file
(I can leave that up to your imagination). Now when you commit that file, you
get no error message back from Subversion:

$ svn ci -m 'Yet another commit to trigger the post-commit script'
Adding trunk/file5
Transmitting file data .
Committed revision 3.

Where did the message we echoed to STDERR go? Because the script succeeded,
Subversion doesn't echo that message (this is a good thing).

5) When you change a post-commit hook script, always try it outside of
Subversion before you try it inside. You need to make sure that you know the
script itself will execute, before you test whether Subversion will execute it.

I hope this *long* e-mail serves you well in writing your own attempts to
recreate the wheel. Did I mention, I've written a couple of very-easy-to-use
Perl modules that make this trivial??? ;-)

John

$ svnadmin create test-repo

$ svn co file:///$PWD/test-repo/ test-wc
Checked out revision 0.

$ cd test-wc

$ md trunk tags branches

$ cd trunk/

$ echo "This is file 1" > file1

$ echo "This is file 2" > file2

$ md dir1

$ cd ..

$ svn add *
A branches
A tags
A trunk
A trunk/file2
A trunk/dir1
A trunk/file1

$ svn ci -m 'Skeleton'
Adding branches
Adding tags
Adding trunk
Adding trunk/dir1
Adding trunk/file1
Adding trunk/file2
Transmitting file data ..
Committed revision 1.

$ svn info
Path: .
URL: file:///tmp/test-repo
Repository Root: file:///tmp/test-repo
Repository UUID: aaad3d6a-353c-0410-92c4-f3ef12ebead9
Revision: 0
Node Kind: directory
Schedule: normal
Last Changed Rev: 0
Last Changed Date: 2007-10-11 06:53:40 -0400 (Thu, 11 Oct 2007)

$ cd ../../test-wc/trunk

$ ls
dir1 file1 file2

$ echo "This is file3" > dir1/file3

$ echo "This is file4" > dir1/file4

$ svn add dir1/*
A dir1/file3
A dir1/file4

$ svn ci -m 'Another commit to trigger the post-commit script'
Adding trunk/dir1/file3
Adding trunk/dir1/file4
Transmitting file data ..
Committed revision 2.

Warning: 'post-commit' hook failed (exited with a non-zero exitcode of 1). The following error output was produced by the hook:
These were the file(s) that were changed:
A trunk/dir1/file3 A trunk/dir1/file4

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org
Received on Fri Oct 12 13:00:07 2007

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.