Skip to content

Commit

Permalink
Merge branch 'cb/hook-sigpipe' into maint
Browse files Browse the repository at this point in the history
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
  • Loading branch information
peff committed Dec 1, 2015
2 parents 45e330f + af65f68 commit 347acea
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 20 deletions.
3 changes: 3 additions & 0 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>..."),
Expand Down Expand Up @@ -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);
}

Expand Down
33 changes: 15 additions & 18 deletions t/t5571-pre-push-hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 9 additions & 2 deletions transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "submodule.h"
#include "string-list.h"
#include "sha1-array.h"
#include "sigchain.h"

/* rsync support */

Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}
}
Expand All @@ -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;
Expand Down

0 comments on commit 347acea

Please sign in to comment.