2006-12-31 10:20:23 +03:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2006 Shawn O. Pearce
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='Test the update hook infrastructure.'
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success setup '
|
|
|
|
echo This is a test. >a &&
|
2007-07-03 09:52:14 +04:00
|
|
|
git update-index --add a &&
|
|
|
|
tree0=$(git write-tree) &&
|
|
|
|
commit0=$(echo setup | git commit-tree $tree0) &&
|
2006-12-31 10:20:23 +03:00
|
|
|
echo We hope it works. >a &&
|
2007-07-03 09:52:14 +04:00
|
|
|
git update-index a &&
|
|
|
|
tree1=$(git write-tree) &&
|
|
|
|
commit1=$(echo modify | git commit-tree $tree1 -p $commit0) &&
|
2020-11-19 02:44:29 +03:00
|
|
|
git update-ref refs/heads/main $commit0 &&
|
2007-07-03 09:52:14 +04:00
|
|
|
git update-ref refs/heads/tofail $commit1 &&
|
2010-02-10 05:01:29 +03:00
|
|
|
git clone --bare ./. victim.git &&
|
|
|
|
GIT_DIR=victim.git git update-ref refs/heads/tofail $commit1 &&
|
2020-11-19 02:44:29 +03:00
|
|
|
git update-ref refs/heads/main $commit1 &&
|
2007-07-03 09:52:14 +04:00
|
|
|
git update-ref refs/heads/tofail $commit0
|
2006-12-31 10:20:23 +03:00
|
|
|
'
|
|
|
|
|
2010-02-10 05:01:29 +03:00
|
|
|
cat >victim.git/hooks/pre-receive <<'EOF'
|
2007-03-08 00:52:05 +03:00
|
|
|
#!/bin/sh
|
2008-01-30 09:21:56 +03:00
|
|
|
printf %s "$@" >>$GIT_DIR/pre-receive.args
|
2007-03-10 11:28:16 +03:00
|
|
|
cat - >$GIT_DIR/pre-receive.stdin
|
2007-03-08 00:52:05 +03:00
|
|
|
echo STDOUT pre-receive
|
|
|
|
echo STDERR pre-receive >&2
|
|
|
|
EOF
|
2010-02-10 05:01:29 +03:00
|
|
|
chmod u+x victim.git/hooks/pre-receive
|
2007-03-08 00:52:05 +03:00
|
|
|
|
2010-02-10 05:01:29 +03:00
|
|
|
cat >victim.git/hooks/update <<'EOF'
|
2006-12-31 10:20:23 +03:00
|
|
|
#!/bin/sh
|
2007-03-08 00:52:05 +03:00
|
|
|
echo "$@" >>$GIT_DIR/update.args
|
2008-01-30 09:21:56 +03:00
|
|
|
read x; printf %s "$x" >$GIT_DIR/update.stdin
|
2007-03-08 00:52:05 +03:00
|
|
|
echo STDOUT update $1
|
|
|
|
echo STDERR update $1 >&2
|
2020-11-19 02:44:29 +03:00
|
|
|
test "$1" = refs/heads/main || exit
|
2006-12-31 10:20:23 +03:00
|
|
|
EOF
|
2010-02-10 05:01:29 +03:00
|
|
|
chmod u+x victim.git/hooks/update
|
2006-12-31 10:20:23 +03:00
|
|
|
|
2010-02-10 05:01:29 +03:00
|
|
|
cat >victim.git/hooks/post-receive <<'EOF'
|
2007-03-08 00:52:05 +03:00
|
|
|
#!/bin/sh
|
2008-01-30 09:21:56 +03:00
|
|
|
printf %s "$@" >>$GIT_DIR/post-receive.args
|
2007-03-10 11:28:16 +03:00
|
|
|
cat - >$GIT_DIR/post-receive.stdin
|
2007-03-08 00:52:05 +03:00
|
|
|
echo STDOUT post-receive
|
|
|
|
echo STDERR post-receive >&2
|
|
|
|
EOF
|
2010-02-10 05:01:29 +03:00
|
|
|
chmod u+x victim.git/hooks/post-receive
|
2007-03-08 00:52:05 +03:00
|
|
|
|
2010-02-10 05:01:29 +03:00
|
|
|
cat >victim.git/hooks/post-update <<'EOF'
|
2006-12-31 10:20:23 +03:00
|
|
|
#!/bin/sh
|
2007-03-08 00:52:05 +03:00
|
|
|
echo "$@" >>$GIT_DIR/post-update.args
|
2008-01-30 09:21:56 +03:00
|
|
|
read x; printf %s "$x" >$GIT_DIR/post-update.stdin
|
2006-12-31 10:20:23 +03:00
|
|
|
echo STDOUT post-update
|
|
|
|
echo STDERR post-update >&2
|
|
|
|
EOF
|
2010-02-10 05:01:29 +03:00
|
|
|
chmod u+x victim.git/hooks/post-update
|
2006-12-31 10:20:23 +03:00
|
|
|
|
2008-02-01 12:50:53 +03:00
|
|
|
test_expect_success push '
|
2010-02-10 05:01:29 +03:00
|
|
|
test_must_fail git send-pack --force ./victim.git \
|
2020-11-19 02:44:29 +03:00
|
|
|
main tofail >send.out 2>send.err
|
2007-03-08 00:52:05 +03:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'updated as expected' '
|
2020-11-19 02:44:29 +03:00
|
|
|
test $(GIT_DIR=victim.git git rev-parse main) = $commit1 &&
|
2010-02-10 05:01:29 +03:00
|
|
|
test $(GIT_DIR=victim.git git rev-parse tofail) = $commit1
|
2006-12-31 10:20:23 +03:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'hooks ran' '
|
2010-02-10 05:01:29 +03:00
|
|
|
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
|
2006-12-31 10:20:23 +03:00
|
|
|
'
|
|
|
|
|
2007-03-10 11:28:16 +03:00
|
|
|
test_expect_success 'pre-receive hook input' '
|
2020-11-19 02:44:29 +03:00
|
|
|
(echo $commit0 $commit1 refs/heads/main &&
|
2007-03-10 11:28:16 +03:00
|
|
|
echo $commit1 $commit0 refs/heads/tofail
|
2010-02-10 05:01:29 +03:00
|
|
|
) | test_cmp - victim.git/pre-receive.stdin
|
2007-03-08 00:52:05 +03:00
|
|
|
'
|
|
|
|
|
2006-12-31 10:20:23 +03:00
|
|
|
test_expect_success 'update hook arguments' '
|
2020-11-19 02:44:29 +03:00
|
|
|
(echo refs/heads/main $commit0 $commit1 &&
|
2007-03-08 00:52:05 +03:00
|
|
|
echo refs/heads/tofail $commit1 $commit0
|
2010-02-10 05:01:29 +03:00
|
|
|
) | test_cmp - victim.git/update.args
|
2007-03-08 00:52:05 +03:00
|
|
|
'
|
|
|
|
|
2007-03-10 11:28:16 +03:00
|
|
|
test_expect_success 'post-receive hook input' '
|
2020-11-19 02:44:29 +03:00
|
|
|
echo $commit0 $commit1 refs/heads/main |
|
2010-02-10 05:01:29 +03:00
|
|
|
test_cmp - victim.git/post-receive.stdin
|
2006-12-31 10:20:23 +03:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'post-update hook arguments' '
|
2020-11-19 02:44:29 +03:00
|
|
|
echo refs/heads/main |
|
2010-02-10 05:01:29 +03:00
|
|
|
test_cmp - victim.git/post-update.args
|
2006-12-31 10:20:23 +03:00
|
|
|
'
|
|
|
|
|
2007-03-08 00:52:05 +03:00
|
|
|
test_expect_success 'all hook stdin is /dev/null' '
|
2018-08-20 00:57:22 +03:00
|
|
|
test_must_be_empty victim.git/update.stdin &&
|
|
|
|
test_must_be_empty victim.git/post-update.stdin
|
2006-12-31 10:20:23 +03:00
|
|
|
'
|
|
|
|
|
2007-03-10 11:28:16 +03:00
|
|
|
test_expect_success 'all *-receive hook args are empty' '
|
2018-08-20 00:57:22 +03:00
|
|
|
test_must_be_empty victim.git/pre-receive.args &&
|
|
|
|
test_must_be_empty victim.git/post-receive.args
|
2007-03-10 11:28:16 +03:00
|
|
|
'
|
|
|
|
|
2008-02-01 12:50:53 +03:00
|
|
|
test_expect_success 'send-pack produced no output' '
|
2018-08-20 00:57:22 +03:00
|
|
|
test_must_be_empty send.out
|
2006-12-31 10:20:23 +03:00
|
|
|
'
|
|
|
|
|
2007-03-08 00:52:05 +03:00
|
|
|
cat <<EOF >expect
|
2010-02-05 23:57:42 +03:00
|
|
|
remote: STDOUT pre-receive
|
|
|
|
remote: STDERR pre-receive
|
2020-11-19 02:44:29 +03:00
|
|
|
remote: STDOUT update refs/heads/main
|
|
|
|
remote: STDERR update refs/heads/main
|
2010-02-05 23:57:42 +03:00
|
|
|
remote: STDOUT update refs/heads/tofail
|
|
|
|
remote: STDERR update refs/heads/tofail
|
2010-02-10 20:34:12 +03:00
|
|
|
remote: error: hook declined to update refs/heads/tofail
|
2010-02-05 23:57:42 +03:00
|
|
|
remote: STDOUT post-receive
|
|
|
|
remote: STDERR post-receive
|
|
|
|
remote: STDOUT post-update
|
|
|
|
remote: STDERR post-update
|
2007-03-08 00:52:05 +03:00
|
|
|
EOF
|
2006-12-31 10:20:23 +03:00
|
|
|
test_expect_success 'send-pack stderr contains hook messages' '
|
2010-02-05 23:57:42 +03:00
|
|
|
grep ^remote: send.err | sed "s/ *\$//" >actual &&
|
2010-02-10 20:34:12 +03:00
|
|
|
test_cmp expect actual
|
2006-12-31 10:20:23 +03:00
|
|
|
'
|
|
|
|
|
receive-pack: allow hooks to ignore its standard input stream
The pre-receive and post-receive hooks were designed to be an
improvement over old style update and post-update hooks, which take
the update information on their command line and are limited by the
command line length limit. The same information is fed from the
standard input to pre/post-receive hooks instead to lift this
limitation. It has been mandatory for these new style hooks to
consume the update information fully from the standard input stream.
Otherwise, they would risk killing the receive-pack process via
SIGPIPE.
If a hook does not want to look at all the information, it is easy
to send its standard input to /dev/null (perhaps a niche use of hook
might need to know only the fact that a push was made, without
having to know what objects have been pushed to update which refs),
and this has already been done by existing hooks that are written
carefully.
However, because there is no good way to consistently fail hooks
that do not consume the input fully (a small push may result in a
short update record that may fit within the pipe buffer, to which
the receive-pack process may manage to write before the hook has a
chance to exit without reading anything, which will not result in a
death-by-SIGPIPE of receive-pack), it can lead to a hard to diagnose
"once in a blue moon" phantom failure.
Lift this "hooks must consume their input fully" mandate. A mandate
that is not enforced strictly is not helping us to catch mistakes in
hooks. If a hook has a good reason to decide the outcome of its
operation without reading the information we feed it, let it do so
as it pleases.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-09-13 02:48:07 +04:00
|
|
|
test_expect_success 'pre-receive hook that forgets to read its input' '
|
|
|
|
write_script victim.git/hooks/pre-receive <<-\EOF &&
|
|
|
|
exit 0
|
|
|
|
EOF
|
|
|
|
rm -f victim.git/hooks/update victim.git/hooks/post-update &&
|
|
|
|
|
|
|
|
for v in $(test_seq 100 999)
|
|
|
|
do
|
2020-11-19 02:44:29 +03:00
|
|
|
git branch branch_$v main || return
|
receive-pack: allow hooks to ignore its standard input stream
The pre-receive and post-receive hooks were designed to be an
improvement over old style update and post-update hooks, which take
the update information on their command line and are limited by the
command line length limit. The same information is fed from the
standard input to pre/post-receive hooks instead to lift this
limitation. It has been mandatory for these new style hooks to
consume the update information fully from the standard input stream.
Otherwise, they would risk killing the receive-pack process via
SIGPIPE.
If a hook does not want to look at all the information, it is easy
to send its standard input to /dev/null (perhaps a niche use of hook
might need to know only the fact that a push was made, without
having to know what objects have been pushed to update which refs),
and this has already been done by existing hooks that are written
carefully.
However, because there is no good way to consistently fail hooks
that do not consume the input fully (a small push may result in a
short update record that may fit within the pipe buffer, to which
the receive-pack process may manage to write before the hook has a
chance to exit without reading anything, which will not result in a
death-by-SIGPIPE of receive-pack), it can lead to a hard to diagnose
"once in a blue moon" phantom failure.
Lift this "hooks must consume their input fully" mandate. A mandate
that is not enforced strictly is not helping us to catch mistakes in
hooks. If a hook has a good reason to decide the outcome of its
operation without reading the information we feed it, let it do so
as it pleases.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-09-13 02:48:07 +04:00
|
|
|
done &&
|
|
|
|
git push ./victim.git "+refs/heads/*:refs/heads/*"
|
|
|
|
'
|
|
|
|
|
2006-12-31 10:20:23 +03:00
|
|
|
test_done
|