From: Adrian Ratiu Date: Thu, 18 Dec 2025 17:11:14 GMT Subject: [PATCH v5 00/11] Convert remaining hooks to hook.h Message-ID: <20251218171126.588066-1-adrian.ratiu@collabora.com> In-Reply-To: <20250925125352.1728840-1-adrian.ratiu@collabora.com> Hello everyone, This series finishes the hook.[ch] conversion for the remaining hooks in preparation for adding config-based hooks and enabling parallel hook execution where possible (that will be a separate series from this one). v5 is just a minor cleanup refresh: details + range-diff below. It is based on the latest master branch. There are no conflicts with next and seen branches, the code is available on GitHub [1] and a successful CI run [2] is also provided. 1: https://github.com/10ne1/git/tree/dev/aratiu/hooks-conversion-v5 2: https://github.com/10ne1/git/actions/runs/20274558658 Changes in v5: * Dropped some REF_STATUS_REJECT_* additions which are mostly unrelated (Patrick) * Made a null output buffer in hook_output_to_sideband() trigger a BUG (Patrick) * Cleaned up the diff in patch 11 to not unnecessarily move hook_output_to_sideband() around, though this looks a bit ugly in the range-diff for patches 10 & 11 (Adrian) * Two small nitpicks / typos (Patrick) Range-diff between v4 -> v5: 1: b252d447f5 = 1: 8c16f1bcbf run-command: add first helper for pp child states 2: f6fd3b9b0f = 2: 5e6e05ba92 run-command: add stdin callback for parallelization 3: 59c07b618e ! 3: 3669acfe6a hook: provide stdin via callback @@ hook.h: struct run_hooks_opt + * used for smaller inputs, where it gets called only once. + * + * Add hook callback initalization context to `feed_pipe_ctx`. -+ * Add Hook callback internal state to `feed_pipe_cb_data`. ++ * Add hook callback internal state to `feed_pipe_cb_data`. + * + */ + feed_pipe_fn feed_pipe; 4: 8f591319a4 = 4: bf9d8680e4 hook: convert 'post-rewrite' hook in sequencer.c to hook API 5: 2427717a26 ! 5: bdcc1cff34 transport: convert pre-push to hook API @@ transport.c: static void die_with_unpushed_submodules(struct string_list *needs_ - finish_command(&proc); - return -1; + switch (r->status) { -+ case REF_STATUS_REJECT_ALREADY_EXISTS: -+ case REF_STATUS_REJECT_FETCH_FIRST: -+ case REF_STATUS_REJECT_NEEDS_FORCE: -+ case REF_STATUS_REJECT_NODELETE: + case REF_STATUS_REJECT_NONFASTFORWARD: + case REF_STATUS_REJECT_REMOTE_UPDATED: -+ case REF_STATUS_REJECT_SHALLOW: + case REF_STATUS_REJECT_STALE: + case REF_STATUS_UPTODATE: + return 0; /* skip refs which won't be pushed */ 6: 22467bb074 = 6: 9c1d5e8726 reference-transaction: use hook API instead of run-command 7: 9b0b13379c = 7: 0b986bf0fb hook: allow overriding the ungroup option 8: cae3c984e2 = 8: 5f07d07acc run-command: allow capturing of collated output 9: 0383be2ebd = 9: c4ff1e2270 hooks: allow callers to capture output 10: d8e234c453 ! 10: 15c831ca15 receive-pack: convert update hooks to new API @@ Commit message Signed-off-by: Adrian Ratiu ## builtin/receive-pack.c ## -@@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands, - return status; +@@ builtin/receive-pack.c: static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep) + return 0; } --static int run_update_hook(struct command *cmd) +static void hook_output_to_sideband(struct strbuf *output, void *cb_data UNUSED) ++{ ++ if (!output) ++ BUG("output must be non-NULL"); ++ ++ /* buffer might be empty for keepalives */ ++ if (output->len) ++ send_sideband(1, 2, output->buf, output->len, use_sideband); ++} ++ + static int run_receive_hook(struct command *commands, + const char *hook_name, + int skip_broken, +@@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands, + + static int run_update_hook(struct command *cmd) { - struct child_process proc = CHILD_PROCESS_INIT; - int code; @@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands, - - if (!hook_path) - return 0; -+ if (output && output->len) -+ send_sideband(1, 2, output->buf, output->len, use_sideband); -+} - +- - strvec_push(&proc.args, hook_path); - strvec_push(&proc.args, cmd->ref_name); - strvec_push(&proc.args, oid_to_hex(&cmd->old_oid)); - strvec_push(&proc.args, oid_to_hex(&cmd->new_oid)); -+static int run_update_hook(struct command *cmd) -+{ + struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT; - proc.no_stdin = 1; 11: 6bad9aed4d ! 11: 4bd2c2974a receive-pack: convert receive hooks to hook API @@ builtin/receive-pack.c: struct receive_hook_feed_state { - finish_async(&muxer); - sigchain_pop(SIGPIPE); -+ state->cmd = cmd; - +- - return finish_command(&proc); -+ if (state->buf.len > 0) { -+ int ret = write_in_full(hook_stdin_fd, state->buf.buf, state->buf.len); -+ if (ret < 0) { -+ if (errno == EPIPE) -+ return 1; /* child closed pipe */ -+ return ret; -+ } -+ } -+ -+ return state->cmd ? 0 : 1; /* 0 = more to come, 1 = EOF */ - } +-} ++ state->cmd = cmd; -static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep) -+static void hook_output_to_sideband(struct strbuf *output, void *cb_data UNUSED) - { +-{ - struct receive_hook_feed_state *state = state_; - struct command *cmd = state->cmd; - @@ builtin/receive-pack.c: struct receive_hook_feed_state { - if (bufp) { - *bufp = state->buf.buf; - *sizep = state->buf.len; -- } ++ if (state->buf.len > 0) { ++ int ret = write_in_full(hook_stdin_fd, state->buf.buf, state->buf.len); ++ if (ret < 0) { ++ if (errno == EPIPE) ++ return 1; /* child closed pipe */ ++ return ret; ++ } + } - return 0; -+ if (output && output->len) -+ send_sideband(1, 2, output->buf, output->len, use_sideband); ++ ++ return state->cmd ? 0 : 1; /* 0 = more to come, 1 = EOF */ } - static int run_receive_hook(struct command *commands, + static void hook_output_to_sideband(struct strbuf *output, void *cb_data UNUSED) @@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands, int skip_broken, const struct string_list *push_options) @@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands, - status = run_and_feed_hook(hook_name, feed_receive_hook, &state); - strbuf_release(&state.buf); - return status; --} - --static void hook_output_to_sideband(struct strbuf *output, void *cb_data UNUSED) --{ -- if (output && output->len) -- send_sideband(1, 2, output->buf, output->len, use_sideband); ++ + if (push_options) { + int i; + for (i = 0; i < push_options->nr; i++) Adrian Ratiu (3): run-command: add first helper for pp child states reference-transaction: use hook API instead of run-command hook: allow overriding the ungroup option Emily Shaffer (8): run-command: add stdin callback for parallelization hook: provide stdin via callback hook: convert 'post-rewrite' hook in sequencer.c to hook API transport: convert pre-push to hook API run-command: allow capturing of collated output hooks: allow callers to capture output receive-pack: convert update hooks to new API receive-pack: convert receive hooks to hook API builtin/hook.c | 6 + builtin/receive-pack.c | 272 ++++++++++++++++-------------------- commit.c | 3 + hook.c | 29 +++- hook.h | 51 +++++++ refs.c | 100 ++++++------- run-command.c | 142 +++++++++++++++---- run-command.h | 38 +++++ sequencer.c | 42 +++--- t/helper/test-run-command.c | 67 ++++++++- t/t0061-run-command.sh | 38 +++++ transport.c | 89 ++++++------ 12 files changed, 585 insertions(+), 292 deletions(-) -- 2.51.2