Skip to content

Commit af65f68

Browse files
Clemens Buchacherpeff
authored andcommitted
allow hooks to ignore their standard input stream
Since ec7dbd1 (receive-pack: allow hooks to ignore its standard input stream) the pre-receive and post-receive hooks ignore SIGPIPE. Do the same for the remaining hooks pre-push and post-rewrite, which read from standard input. The same arguments for ignoring SIGPIPE apply. Include test by Jeff King which checks that SIGPIPE does not cause pre-push hook failure. With the use of git update-ref --stdin it is fast enough to be enabled by default. Signed-off-by: Clemens Buchacher <[email protected]> Signed-off-by: Jeff King <[email protected]>
1 parent af40944 commit af65f68

File tree

3 files changed

+27
-20
lines changed

3 files changed

+27
-20
lines changed

builtin/commit.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "sequencer.h"
3333
#include "notes-utils.h"
3434
#include "mailmap.h"
35+
#include "sigchain.h"
3536

3637
static const char * const builtin_commit_usage[] = {
3738
N_("git commit [<options>] [--] <pathspec>..."),
@@ -1537,8 +1538,10 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
15371538
return code;
15381539
n = snprintf(buf, sizeof(buf), "%s %s\n",
15391540
sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
1541+
sigchain_push(SIGPIPE, SIG_IGN);
15401542
write_in_full(proc.in, buf, n);
15411543
close(proc.in);
1544+
sigchain_pop(SIGPIPE);
15421545
return finish_command(&proc);
15431546
}
15441547

t/t5571-pre-push-hook.sh

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -109,23 +109,20 @@ test_expect_success 'push to URL' '
109109
diff expected actual
110110
'
111111

112-
# Test that filling pipe buffers doesn't cause failure
113-
# Too slow to leave enabled for general use
114-
if false
115-
then
116-
printf 'parent1\nrepo1\n' >expected
117-
nr=1000
118-
while test $nr -lt 2000
119-
do
120-
nr=$(( $nr + 1 ))
121-
git branch b/$nr $COMMIT3
122-
echo "refs/heads/b/$nr $COMMIT3 refs/heads/b/$nr $_z40" >>expected
123-
done
124-
125-
test_expect_success 'push many refs' '
126-
git push parent1 "refs/heads/b/*:refs/heads/b/*" &&
127-
diff expected actual
128-
'
129-
fi
112+
test_expect_success 'set up many-ref tests' '
113+
{
114+
nr=1000
115+
while test $nr -lt 2000
116+
do
117+
nr=$(( $nr + 1 ))
118+
echo "create refs/heads/b/$nr $COMMIT3"
119+
done
120+
} | git update-ref --stdin
121+
'
122+
123+
test_expect_success 'sigpipe does not cause pre-push hook failure' '
124+
echo "exit 0" | write_script "$HOOK" &&
125+
git push parent1 "refs/heads/b/*:refs/heads/b/*"
126+
'
130127

131128
test_done

transport.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "submodule.h"
1616
#include "string-list.h"
1717
#include "sha1-array.h"
18+
#include "sigchain.h"
1819

1920
/* rsync support */
2021

@@ -1126,6 +1127,8 @@ static int run_pre_push_hook(struct transport *transport,
11261127
return -1;
11271128
}
11281129

1130+
sigchain_push(SIGPIPE, SIG_IGN);
1131+
11291132
strbuf_init(&buf, 256);
11301133

11311134
for (r = remote_refs; r; r = r->next) {
@@ -1139,8 +1142,10 @@ static int run_pre_push_hook(struct transport *transport,
11391142
r->peer_ref->name, sha1_to_hex(r->new_sha1),
11401143
r->name, sha1_to_hex(r->old_sha1));
11411144

1142-
if (write_in_full(proc.in, buf.buf, buf.len) != buf.len) {
1143-
ret = -1;
1145+
if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
1146+
/* We do not mind if a hook does not read all refs. */
1147+
if (errno != EPIPE)
1148+
ret = -1;
11441149
break;
11451150
}
11461151
}
@@ -1151,6 +1156,8 @@ static int run_pre_push_hook(struct transport *transport,
11511156
if (!ret)
11521157
ret = x;
11531158

1159+
sigchain_pop(SIGPIPE);
1160+
11541161
x = finish_command(&proc);
11551162
if (!ret)
11561163
ret = x;

0 commit comments

Comments
 (0)