summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2015-12-01 17:19:52 -0500
committerJeff King <peff@peff.net>2015-12-01 17:19:52 -0500
commit347acea06a80324c7a184a856b5dac24d0ba2c92 (patch)
tree5414208483e8988f5c892fedf549f9173dd517c5
parent45e330f512b5a32f2e3aae800e57b07fd75f607e (diff)
parentaf65f68cdf7540764583956e5819d85c5f6c74d1 (diff)
downloadgit-347acea06a80324c7a184a856b5dac24d0ba2c92.tar.gz
Merge branch 'cb/hook-sigpipe' into maint
We now consistently allow all hooks to ignore their standard input, rather than having git complain of SIGPIPE. * cb/hook-sigpipe: allow hooks to ignore their standard input stream
-rw-r--r--builtin/commit.c3
-rwxr-xr-xt/t5571-pre-push-hook.sh33
-rw-r--r--transport.c11
3 files changed, 27 insertions, 20 deletions
diff --git a/builtin/commit.c b/builtin/commit.c
index dca09e2c3b..f2a8b78c7a 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -32,6 +32,7 @@
#include "sequencer.h"
#include "notes-utils.h"
#include "mailmap.h"
+#include "sigchain.h"
static const char * const builtin_commit_usage[] = {
N_("git commit [<options>] [--] <pathspec>..."),
@@ -1537,8 +1538,10 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
return code;
n = snprintf(buf, sizeof(buf), "%s %s\n",
sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
+ sigchain_push(SIGPIPE, SIG_IGN);
write_in_full(proc.in, buf, n);
close(proc.in);
+ sigchain_pop(SIGPIPE);
return finish_command(&proc);
}
diff --git a/t/t5571-pre-push-hook.sh b/t/t5571-pre-push-hook.sh
index 6f9916a390..ba975bb355 100755
--- a/t/t5571-pre-push-hook.sh
+++ b/t/t5571-pre-push-hook.sh
@@ -109,23 +109,20 @@ test_expect_success 'push to URL' '
diff expected actual
'
-# Test that filling pipe buffers doesn't cause failure
-# Too slow to leave enabled for general use
-if false
-then
- printf 'parent1\nrepo1\n' >expected
- nr=1000
- while test $nr -lt 2000
- do
- nr=$(( $nr + 1 ))
- git branch b/$nr $COMMIT3
- echo "refs/heads/b/$nr $COMMIT3 refs/heads/b/$nr $_z40" >>expected
- done
-
- test_expect_success 'push many refs' '
- git push parent1 "refs/heads/b/*:refs/heads/b/*" &&
- diff expected actual
- '
-fi
+test_expect_success 'set up many-ref tests' '
+ {
+ nr=1000
+ while test $nr -lt 2000
+ do
+ nr=$(( $nr + 1 ))
+ echo "create refs/heads/b/$nr $COMMIT3"
+ done
+ } | git update-ref --stdin
+'
+
+test_expect_success 'sigpipe does not cause pre-push hook failure' '
+ echo "exit 0" | write_script "$HOOK" &&
+ git push parent1 "refs/heads/b/*:refs/heads/b/*"
+'
test_done
diff --git a/transport.c b/transport.c
index 863eb524f9..37e4f5e42c 100644
--- a/transport.c
+++ b/transport.c
@@ -15,6 +15,7 @@
#include "submodule.h"
#include "string-list.h"
#include "sha1-array.h"
+#include "sigchain.h"
/* rsync support */
@@ -1126,6 +1127,8 @@ static int run_pre_push_hook(struct transport *transport,
return -1;
}
+ sigchain_push(SIGPIPE, SIG_IGN);
+
strbuf_init(&buf, 256);
for (r = remote_refs; r; r = r->next) {
@@ -1139,8 +1142,10 @@ static int run_pre_push_hook(struct transport *transport,
r->peer_ref->name, sha1_to_hex(r->new_sha1),
r->name, sha1_to_hex(r->old_sha1));
- if (write_in_full(proc.in, buf.buf, buf.len) != buf.len) {
- ret = -1;
+ if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
+ /* We do not mind if a hook does not read all refs. */
+ if (errno != EPIPE)
+ ret = -1;
break;
}
}
@@ -1151,6 +1156,8 @@ static int run_pre_push_hook(struct transport *transport,
if (!ret)
ret = x;
+ sigchain_pop(SIGPIPE);
+
x = finish_command(&proc);
if (!ret)
ret = x;