summaryrefslogtreecommitdiff
path: root/t/t5401-update-hooks.sh
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2007-03-07 21:52:05 (GMT)
committerJunio C Hamano <junkio@cox.net>2007-03-07 23:03:33 (GMT)
commit05ef58ec1f2fb69d6e7ae7fca84163f75bd95050 (patch)
tree82e444216aef4ce945e8b5d6dac4b5adfedb4f39 /t/t5401-update-hooks.sh
parent8aaf7d6410119ee221f5d3ebdc4fc5a57f862665 (diff)
downloadgit-05ef58ec1f2fb69d6e7ae7fca84163f75bd95050.zip
git-05ef58ec1f2fb69d6e7ae7fca84163f75bd95050.tar.gz
git-05ef58ec1f2fb69d6e7ae7fca84163f75bd95050.tar.bz2
Teach receive-pack to run pre-receive/post-receive hooks
Bill Lear pointed out that it is easy to send out notifications of changes with the update hook, but successful execution of the update hook does not necessarily mean that the ref was actually updated. Lock contention on the ref or being unable to append to the reflog may prevent the ref from being changed. Sending out notifications prior to the ref actually changing is very misleading. To help this situation I am introducing two new hooks to the receive-pack flow: pre-receive and post-receive. These new hooks are invoked only once per receive-pack execution and are passed three arguments per ref (refname, old-sha1, new-sha1). The new post-receive hook is ideal for sending out notifications, as it has the complete list of all refnames that were successfully updated as well as the old and new SHA-1 values. This allows more interesting notifications to be sent. Multiple ref updates could be easily summarized into one email, for example. The new pre-receive hook is ideal for logging update attempts, as it is run only once for the entire receive-pack operation. It can also be used to verify multiple updates happen at once, e.g. an update to the `maint` head must also be accompained by a new annotated tag. Lots of documentation improvements for receive-pack are included in this change, as we want to make sure the new hooks are clearly explained. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 't/t5401-update-hooks.sh')
-rwxr-xr-xt/t5401-update-hooks.sh93
1 files changed, 73 insertions, 20 deletions
diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 0514056..0c0034e 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -11,47 +11,91 @@ test_expect_success setup '
git-update-index --add a &&
tree0=$(git-write-tree) &&
commit0=$(echo setup | git-commit-tree $tree0) &&
- git-update-ref HEAD $commit0 &&
- git-clone ./. victim &&
echo We hope it works. >a &&
git-update-index a &&
tree1=$(git-write-tree) &&
commit1=$(echo modify | git-commit-tree $tree1 -p $commit0) &&
- git-update-ref HEAD $commit1
+ git-update-ref refs/heads/master $commit0 &&
+ git-update-ref refs/heads/tofail $commit1 &&
+ git-clone ./. victim &&
+ GIT_DIR=victim/.git git-update-ref refs/heads/tofail $commit1 &&
+ git-update-ref refs/heads/master $commit1 &&
+ git-update-ref refs/heads/tofail $commit0
'
+cat >victim/.git/hooks/pre-receive <<'EOF'
+#!/bin/sh
+echo "$@" >>$GIT_DIR/pre-receive.args
+read x; printf "$x" >$GIT_DIR/pre-receive.stdin
+echo STDOUT pre-receive
+echo STDERR pre-receive >&2
+EOF
+chmod u+x victim/.git/hooks/pre-receive
+
cat >victim/.git/hooks/update <<'EOF'
#!/bin/sh
-echo "$@" >$GIT_DIR/update.args
+echo "$@" >>$GIT_DIR/update.args
read x; printf "$x" >$GIT_DIR/update.stdin
-echo STDOUT update
-echo STDERR update >&2
+echo STDOUT update $1
+echo STDERR update $1 >&2
+test "$1" = refs/heads/master || exit
EOF
chmod u+x victim/.git/hooks/update
+cat >victim/.git/hooks/post-receive <<'EOF'
+#!/bin/sh
+echo "$@" >>$GIT_DIR/post-receive.args
+read x; printf "$x" >$GIT_DIR/post-receive.stdin
+echo STDOUT post-receive
+echo STDERR post-receive >&2
+EOF
+chmod u+x victim/.git/hooks/post-receive
+
cat >victim/.git/hooks/post-update <<'EOF'
#!/bin/sh
-echo "$@" >$GIT_DIR/post-update.args
+echo "$@" >>$GIT_DIR/post-update.args
read x; printf "$x" >$GIT_DIR/post-update.stdin
echo STDOUT post-update
echo STDERR post-update >&2
EOF
chmod u+x victim/.git/hooks/post-update
-test_expect_success push '
- git-send-pack ./victim/.git/ master >send.out 2>send.err
+test_expect_failure push '
+ git-send-pack --force ./victim/.git master tofail >send.out 2>send.err
+'
+
+test_expect_success 'updated as expected' '
+ test $(GIT_DIR=victim/.git git-rev-parse master) = $commit1 &&
+ test $(GIT_DIR=victim/.git git-rev-parse tofail) = $commit1
'
test_expect_success 'hooks ran' '
+ test -f victim/.git/pre-receive.args &&
+ test -f victim/.git/pre-receive.stdin &&
test -f victim/.git/update.args &&
test -f victim/.git/update.stdin &&
+ test -f victim/.git/post-receive.args &&
+ test -f victim/.git/post-receive.stdin &&
test -f victim/.git/post-update.args &&
test -f victim/.git/post-update.stdin
'
+test_expect_success 'pre-receive hook arguments' '
+ echo \
+ refs/heads/master $commit0 $commit1 \
+ refs/heads/tofail $commit1 $commit0 \
+ | diff - victim/.git/pre-receive.args
+'
+
test_expect_success 'update hook arguments' '
+ (echo refs/heads/master $commit0 $commit1;
+ echo refs/heads/tofail $commit1 $commit0
+ ) | diff - victim/.git/update.args
+'
+
+test_expect_success 'post-receive hook arguments' '
echo refs/heads/master $commit0 $commit1 |
- diff -u - victim/.git/update.args
+ diff - victim/.git/post-receive.args
'
test_expect_success 'post-update hook arguments' '
@@ -59,23 +103,32 @@ test_expect_success 'post-update hook arguments' '
diff -u - victim/.git/post-update.args
'
-test_expect_failure 'update hook stdin is /dev/null' '
- test -s victim/.git/update.stdin
-'
-
-test_expect_failure 'post-update hook stdin is /dev/null' '
- test -s victim/.git/post-update.stdin
+test_expect_success 'all hook stdin is /dev/null' '
+ ! test -s victim/.git/pre-receive.stdin &&
+ ! test -s victim/.git/update.stdin &&
+ ! test -s victim/.git/post-receive.stdin &&
+ ! test -s victim/.git/post-update.stdin
'
test_expect_failure 'send-pack produced no output' '
test -s send.out
'
+cat <<EOF >expect
+STDOUT pre-receive
+STDERR pre-receive
+STDOUT update refs/heads/master
+STDERR update refs/heads/master
+STDOUT update refs/heads/tofail
+STDERR update refs/heads/tofail
+STDOUT post-receive
+STDERR post-receive
+STDOUT post-update
+STDERR post-update
+EOF
test_expect_success 'send-pack stderr contains hook messages' '
- grep "STDOUT update" send.err &&
- grep "STDERR update" send.err &&
- grep "STDOUT post-update" send.err &&
- grep "STDERR post-update" send.err
+ egrep ^STD send.err >actual &&
+ diff - actual <expect
'
test_done