Merge branch 'jc/ignore-sigpipe-while-running-hooks'
authorJunio C Hamano <gitster@pobox.com>
Fri, 26 Sep 2014 21:39:44 +0000 (14:39 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 26 Sep 2014 21:39:44 +0000 (14:39 -0700)
pre- and post-receive hooks are no longer required to read all
their inputs.

* jc/ignore-sigpipe-while-running-hooks:
receive-pack: allow hooks to ignore its standard input stream

1  2 
builtin/receive-pack.c
diff --combined builtin/receive-pack.c
index afb8d9926496de2bed8bcab793dd79562e575e18,516386fdd3b757ecde1402c1ce02e9be2f540b9f..daf0600ca30eb3969e0583cc1096e6f33291d4aa
@@@ -15,6 -15,7 +15,7 @@@
  #include "connected.h"
  #include "argv-array.h"
  #include "version.h"
+ #include "sigchain.h"
  
  static const char receive_pack_usage[] = "git receive-pack <git-dir>";
  
@@@ -255,7 -256,7 +256,7 @@@ static int copy_to_sideband(int in, in
  typedef int (*feed_fn)(void *, const char **, size_t *);
  static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state)
  {
 -      struct child_process proc;
 +      struct child_process proc = CHILD_PROCESS_INIT;
        struct async muxer;
        const char *argv[2];
        int code;
  
        argv[1] = NULL;
  
 -      memset(&proc, 0, sizeof(proc));
        proc.argv = argv;
        proc.in = -1;
        proc.stdout_to_stderr = 1;
                return code;
        }
  
+       sigchain_push(SIGPIPE, SIG_IGN);
        while (1) {
                const char *buf;
                size_t n;
        close(proc.in);
        if (use_sideband)
                finish_async(&muxer);
+       sigchain_pop(SIGPIPE);
        return finish_command(&proc);
  }
  
@@@ -349,7 -356,7 +355,7 @@@ static int run_receive_hook(struct comm
  static int run_update_hook(struct command *cmd)
  {
        const char *argv[5];
 -      struct child_process proc;
 +      struct child_process proc = CHILD_PROCESS_INIT;
        int code;
  
        argv[0] = find_hook("update");
        argv[3] = sha1_to_hex(cmd->new_sha1);
        argv[4] = NULL;
  
 -      memset(&proc, 0, sizeof(proc));
        proc.no_stdin = 1;
        proc.stdout_to_stderr = 1;
        proc.err = use_sideband ? -1 : 0;
@@@ -473,6 -481,7 +479,6 @@@ static const char *update(struct comman
        const char *namespaced_name;
        unsigned char *old_sha1 = cmd->old_sha1;
        unsigned char *new_sha1 = cmd->new_sha1;
 -      struct ref_lock *lock;
  
        /* only refs/... are allowed */
        if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) {
                return NULL; /* good */
        }
        else {
 +              struct strbuf err = STRBUF_INIT;
 +              struct ref_transaction *transaction;
 +
                if (shallow_update && si->shallow_ref[cmd->index] &&
                    update_shallow_ref(cmd, si))
                        return "shallow error";
  
 -              lock = lock_any_ref_for_update(namespaced_name, old_sha1,
 -                                             0, NULL);
 -              if (!lock) {
 -                      rp_error("failed to lock %s", name);
 -                      return "failed to lock";
 -              }
 -              if (write_ref_sha1(lock, new_sha1, "push")) {
 -                      return "failed to write"; /* error() already called */
 +              transaction = ref_transaction_begin(&err);
 +              if (!transaction ||
 +                  ref_transaction_update(transaction, namespaced_name,
 +                                         new_sha1, old_sha1, 0, 1, &err) ||
 +                  ref_transaction_commit(transaction, "push", &err)) {
 +                      ref_transaction_free(transaction);
 +
 +                      rp_error("%s", err.buf);
 +                      strbuf_release(&err);
 +                      return "failed to update ref";
                }
 +
 +              ref_transaction_free(transaction);
 +              strbuf_release(&err);
                return NULL; /* good */
        }
  }
@@@ -603,7 -604,7 +609,7 @@@ static void run_update_post_hook(struc
        struct command *cmd;
        int argc;
        const char **argv;
 -      struct child_process proc;
 +      struct child_process proc = CHILD_PROCESS_INIT;
        char *hook;
  
        hook = find_hook("post-update");
        }
        argv[argc] = NULL;
  
 -      memset(&proc, 0, sizeof(proc));
        proc.no_stdin = 1;
        proc.stdout_to_stderr = 1;
        proc.err = use_sideband ? -1 : 0;
@@@ -915,7 -917,7 +921,7 @@@ static const char *unpack(int err_fd, s
        const char *hdr_err;
        int status;
        char hdr_arg[38];
 -      struct child_process child;
 +      struct child_process child = CHILD_PROCESS_INIT;
        int fsck_objects = (receive_fsck_objects >= 0
                            ? receive_fsck_objects
                            : transfer_fsck_objects >= 0
                argv_array_pushl(&av, "--shallow-file", alt_shallow_file, NULL);
        }
  
 -      memset(&child, 0, sizeof(child));
        if (ntohl(hdr.hdr_entries) < unpack_limit) {
                argv_array_pushl(&av, "unpack-objects", hdr_arg, NULL);
                if (quiet)