allow hooks to ignore their standard input stream
Since ec7dbd145 (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 <clemens.buchacher@intel.com> Signed-off-by: Jeff King <peff@peff.net>
Clemens Buchacher committed
Nov 16, 2015 at 09:05 UTC
af65f68cdf7540764583956e5819d85c5f6c74d1
3 files changed
+27
-20
builtin/commit.c
+3
@@ -32,6 +32,7 @@
32
#include "sequencer.h"
33
#include "notes-utils.h"
34
#include "mailmap.h"
35
+#include "sigchain.h"
36
37
static const char * const builtin_commit_usage[] = {
38
N_("git commit [<options>] [--] <pathspec>..."),
@@ -1537,8 +1538,10 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
1538
return code;
1539
n = snprintf(buf, sizeof(buf), "%s %s\n",
1540
sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
1541
+ sigchain_push(SIGPIPE, SIG_IGN);
1542
write_in_full(proc.in, buf, n);
1543
close(proc.in);
1544
+ sigchain_pop(SIGPIPE);
1545
return finish_command(&proc);
1546
}
1547
t/t5571-pre-push-hook.sh
+15
-18
@@ -109,23 +109,20 @@ test_expect_success 'push to URL' '
109
diff expected actual
110
'
111
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
+'
127
128
test_done
transport.c
+9
-2
@@ -15,6 +15,7 @@
15
#include "submodule.h"
16
#include "string-list.h"
17
#include "sha1-array.h"
18
+#include "sigchain.h"
19
20
/* rsync support */
21
@@ -1126,6 +1127,8 @@ static int run_pre_push_hook(struct transport *transport,
1127
return -1;
1128
}
1129
1130
+ sigchain_push(SIGPIPE, SIG_IGN);
1131
+
1132
strbuf_init(&buf, 256);
1133
1134
for (r = remote_refs; r; r = r->next) {
@@ -1139,8 +1142,10 @@ static int run_pre_push_hook(struct transport *transport,
1142
r->peer_ref->name, sha1_to_hex(r->new_sha1),
1143
r->name, sha1_to_hex(r->old_sha1));
1144
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;
1149
break;
1150
}
1151
}
@@ -1151,6 +1156,8 @@ static int run_pre_push_hook(struct transport *transport,
1156
if (!ret)
1157
ret = x;
1158
1159
+ sigchain_pop(SIGPIPE);
1160
+
1161
x = finish_command(&proc);
1162
if (!ret)
1163
ret = x;