Change {pre,post}-receive hooks to use stdin
Sergey Vlasov, Andy Parkins and Alex Riesen all pointed out that it is possible for a single invocation of receive-pack to be given more refs than the OS might allow us to pass as command line parameters to a single hook invocation. We don't want to break these up into multiple invocations (like xargs might do) as that makes it impossible for the pre-receive hook to verify multiple related ref updates occur at the same time, and it makes it harder for post-receive to send out a single batch notification. Instead we pass the reference data on a pipe connected to the hook's stdin, supplying one ref per line to the hook. This way a single hook invocation can obtain an infinite amount of ref data, without bumping into any operating system limits. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:

committed by
Junio C Hamano

parent
1d9e8b56fe
commit
f43cd49fb8
@ -25,8 +25,8 @@ test_expect_success setup '
|
||||
|
||||
cat >victim/.git/hooks/pre-receive <<'EOF'
|
||||
#!/bin/sh
|
||||
echo "$@" >>$GIT_DIR/pre-receive.args
|
||||
read x; printf "$x" >$GIT_DIR/pre-receive.stdin
|
||||
printf "$@" >>$GIT_DIR/pre-receive.args
|
||||
cat - >$GIT_DIR/pre-receive.stdin
|
||||
echo STDOUT pre-receive
|
||||
echo STDERR pre-receive >&2
|
||||
EOF
|
||||
@ -44,8 +44,8 @@ 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
|
||||
printf "$@" >>$GIT_DIR/post-receive.args
|
||||
cat - >$GIT_DIR/post-receive.stdin
|
||||
echo STDOUT post-receive
|
||||
echo STDERR post-receive >&2
|
||||
EOF
|
||||
@ -80,11 +80,10 @@ test_expect_success 'hooks ran' '
|
||||
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 \
|
||||
| git diff - victim/.git/pre-receive.args
|
||||
test_expect_success 'pre-receive hook input' '
|
||||
(echo $commit0 $commit1 refs/heads/master;
|
||||
echo $commit1 $commit0 refs/heads/tofail
|
||||
) | git diff - victim/.git/pre-receive.stdin
|
||||
'
|
||||
|
||||
test_expect_success 'update hook arguments' '
|
||||
@ -93,9 +92,9 @@ test_expect_success 'update hook arguments' '
|
||||
) | git diff - victim/.git/update.args
|
||||
'
|
||||
|
||||
test_expect_success 'post-receive hook arguments' '
|
||||
echo refs/heads/master $commit0 $commit1 |
|
||||
git diff - victim/.git/post-receive.args
|
||||
test_expect_success 'post-receive hook input' '
|
||||
echo $commit0 $commit1 refs/heads/master |
|
||||
git diff - victim/.git/post-receive.stdin
|
||||
'
|
||||
|
||||
test_expect_success 'post-update hook arguments' '
|
||||
@ -104,12 +103,15 @@ test_expect_success 'post-update hook arguments' '
|
||||
'
|
||||
|
||||
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_success 'all *-receive hook args are empty' '
|
||||
! test -s victim/.git/pre-receive.args &&
|
||||
! test -s victim/.git/post-receive.args
|
||||
'
|
||||
|
||||
test_expect_failure 'send-pack produced no output' '
|
||||
test -s send.out
|
||||
'
|
||||
|
Reference in New Issue
Block a user