From: Junio C Hamano Date: Wed, 5 Oct 2011 19:36:22 +0000 (-0700) Subject: Merge branch 'jc/run-receive-hook-cleanup' X-Git-Tag: v1.7.8-rc0~134 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/7451aee8e594fe902856a9bf418ca804171f9d19?ds=inline;hp=-c Merge branch 'jc/run-receive-hook-cleanup' * jc/run-receive-hook-cleanup: refactor run_receive_hook() --- 7451aee8e594fe902856a9bf418ca804171f9d19 diff --combined builtin/receive-pack.c index 9b56be3cc6,af429e1017..c1c5bac79e --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@@ -11,7 -11,6 +11,7 @@@ #include "transport.h" #include "string-list.h" #include "sha1-array.h" +#include "connected.h" static const char receive_pack_usage[] = "git receive-pack "; @@@ -26,8 -25,7 +26,8 @@@ static int deny_deletes static int deny_non_fast_forwards; static enum deny_action deny_current_branch = DENY_UNCONFIGURED; static enum deny_action deny_delete_current = DENY_UNCONFIGURED; -static int receive_fsck_objects; +static int receive_fsck_objects = -1; +static int transfer_fsck_objects = -1; static int receive_unpack_limit = -1; static int transfer_unpack_limit = -1; static int unpack_limit = 100; @@@ -81,11 -79,6 +81,11 @@@ static int receive_pack_config(const ch return 0; } + if (strcmp(var, "transfer.fsckobjects") == 0) { + transfer_fsck_objects = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "receive.denycurrentbranch")) { deny_current_branch = parse_deny_action(var, value); return 0; @@@ -212,21 -205,15 +212,15 @@@ static int copy_to_sideband(int in, in 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; @@@ -254,15 -241,13 +248,13 @@@ 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) @@@ -270,6 -255,47 +262,47 @@@ 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"; @@@ -586,43 -612,6 +619,43 @@@ static void check_aliased_updates(struc string_list_clear(&ref_list, 0); } +static int command_singleton_iterator(void *cb_data, unsigned char sha1[20]) +{ + struct command **cmd_list = cb_data; + struct command *cmd = *cmd_list; + + if (!cmd) + return -1; /* end of list */ + *cmd_list = NULL; /* this returns only one */ + hashcpy(sha1, cmd->new_sha1); + return 0; +} + +static void set_connectivity_errors(struct command *commands) +{ + struct command *cmd; + + for (cmd = commands; cmd; cmd = cmd->next) { + struct command *singleton = cmd; + if (!check_everything_connected(command_singleton_iterator, + 0, &singleton)) + continue; + cmd->error_string = "missing necessary objects"; + } +} + +static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20]) +{ + struct command **cmd_list = cb_data; + struct command *cmd = *cmd_list; + + if (!cmd) + return -1; /* end of list */ + *cmd_list = cmd->next; + hashcpy(sha1, cmd->new_sha1); + return 0; +} + static void execute_commands(struct command *commands, const char *unpacker_error) { struct command *cmd; @@@ -634,11 -623,6 +667,11 @@@ return; } + cmd = commands; + if (check_everything_connected(iterate_receive_command_list, + 0, &cmd)) + set_connectivity_errors(commands); + if (run_receive_hook(commands, pre_receive_hook)) { for (cmd = commands; cmd; cmd = cmd->next) cmd->error_string = "pre-receive hook declined"; @@@ -723,11 -707,6 +756,11 @@@ static const char *unpack(void struct pack_header hdr; const char *hdr_err; char hdr_arg[38]; + int fsck_objects = (receive_fsck_objects >= 0 + ? receive_fsck_objects + : transfer_fsck_objects >= 0 + ? transfer_fsck_objects + : 0); hdr_err = parse_pack_header(&hdr); if (hdr_err) @@@ -740,7 -719,7 +773,7 @@@ int code, i = 0; const char *unpacker[4]; unpacker[i++] = "unpack-objects"; - if (receive_fsck_objects) + if (fsck_objects) unpacker[i++] = "--strict"; unpacker[i++] = hdr_arg; unpacker[i++] = NULL; @@@ -760,7 -739,7 +793,7 @@@ keeper[i++] = "index-pack"; keeper[i++] = "--stdin"; - if (receive_fsck_objects) + if (fsck_objects) keeper[i++] = "--strict"; keeper[i++] = "--fix-thin"; keeper[i++] = hdr_arg;