Code

Merge branch 'jc/run-receive-hook-cleanup' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 26 Oct 2011 23:13:31 +0000 (16:13 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 26 Oct 2011 23:13:31 +0000 (16:13 -0700)
* jc/run-receive-hook-cleanup:
  refactor run_receive_hook()

builtin/receive-pack.c

index ae164da4d5a7b7a2c87937ba0983126586f1e646..af429e101777f1c5df09734433278cfb075e978c 100644 (file)
@@ -205,21 +205,15 @@ static int copy_to_sideband(int in, int out, void *arg)
        return 0;
 }
 
-static int run_receive_hook(struct command *commands, const char *hook_name)
+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)
 {
-       static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
-       struct command *cmd;
        struct child_process proc;
        struct async muxer;
        const char *argv[2];
-       int have_input = 0, code;
-
-       for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
-               if (!cmd->error_string)
-                       have_input = 1;
-       }
+       int code;
 
-       if (!have_input || access(hook_name, X_OK) < 0)
+       if (access(hook_name, X_OK) < 0)
                return 0;
 
        argv[0] = hook_name;
@@ -247,15 +241,13 @@ static int run_receive_hook(struct command *commands, const char *hook_name)
                return code;
        }
 
-       for (cmd = commands; cmd; cmd = cmd->next) {
-               if (!cmd->error_string) {
-                       size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
-                               sha1_to_hex(cmd->old_sha1),
-                               sha1_to_hex(cmd->new_sha1),
-                               cmd->ref_name);
-                       if (write_in_full(proc.in, buf, n) != n)
-                               break;
-               }
+       while (1) {
+               const char *buf;
+               size_t n;
+               if (feed(feed_state, &buf, &n))
+                       break;
+               if (write_in_full(proc.in, buf, n) != n)
+                       break;
        }
        close(proc.in);
        if (use_sideband)
@@ -263,6 +255,47 @@ static int run_receive_hook(struct command *commands, const char *hook_name)
        return finish_command(&proc);
 }
 
+struct receive_hook_feed_state {
+       struct command *cmd;
+       struct strbuf buf;
+};
+
+static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
+{
+       struct receive_hook_feed_state *state = state_;
+       struct command *cmd = state->cmd;
+
+       while (cmd && cmd->error_string)
+               cmd = cmd->next;
+       if (!cmd)
+               return -1; /* EOF */
+       strbuf_reset(&state->buf);
+       strbuf_addf(&state->buf, "%s %s %s\n",
+                   sha1_to_hex(cmd->old_sha1), sha1_to_hex(cmd->new_sha1),
+                   cmd->ref_name);
+       state->cmd = cmd->next;
+       if (bufp) {
+               *bufp = state->buf.buf;
+               *sizep = state->buf.len;
+       }
+       return 0;
+}
+
+static int run_receive_hook(struct command *commands, const char *hook_name)
+{
+       struct receive_hook_feed_state state;
+       int status;
+
+       strbuf_init(&state.buf, 0);
+       state.cmd = commands;
+       if (feed_receive_hook(&state, NULL, NULL))
+               return 0;
+       state.cmd = commands;
+       status = run_and_feed_hook(hook_name, feed_receive_hook, &state);
+       strbuf_release(&state.buf);
+       return status;
+}
+
 static int run_update_hook(struct command *cmd)
 {
        static const char update_hook[] = "hooks/update";