diff options
| author | Junio C Hamano <gitster@pobox.com> | 2026-02-04 09:22:21 -0800 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2026-02-04 09:22:21 -0800 |
| commit | 468b5f75c3e277d84e2d739e642fbad27ccdb666 (patch) | |
| tree | bc9d89124c0313cf4023ca2ed8af47fbb0acb4de /hook.c | |
| parent | b2826b52eb7caff9f4ed6e85ec45e338bf02ad09 (diff) | |
| parent | b5e9ad508c2f340bd2d2547d7370ae7ac6a0d65d (diff) | |
| download | git-468b5f75c3e277d84e2d739e642fbad27ccdb666.tar.xz | |
Merge branch 'ar/run-command-hook-take-2' into ar/config-hooks
* ar/run-command-hook-take-2:
receive-pack: convert receive hooks to hook API
receive-pack: convert update hooks to new API
run-command: poll child input in addition to output
hook: add jobs option
reference-transaction: use hook API instead of run-command
transport: convert pre-push to hook API
hook: allow separate std[out|err] streams
hook: convert 'post-rewrite' hook in sequencer.c to hook API
hook: provide stdin via callback
run-command: add stdin callback for parallelization
run-command: add helper for pp child states
t1800: add hook output stream tests
Diffstat (limited to 'hook.c')
| -rw-r--r-- | hook.c | 32 |
1 files changed, 28 insertions, 4 deletions
@@ -55,7 +55,7 @@ int hook_exists(struct repository *r, const char *name) static int pick_next_hook(struct child_process *cp, struct strbuf *out UNUSED, void *pp_cb, - void **pp_task_cb UNUSED) + void **pp_task_cb) { struct hook_cb_data *hook_cb = pp_cb; const char *hook_path = hook_cb->hook_path; @@ -65,12 +65,23 @@ static int pick_next_hook(struct child_process *cp, cp->no_stdin = 1; strvec_pushv(&cp->env, hook_cb->options->env.v); + + if (hook_cb->options->path_to_stdin && hook_cb->options->feed_pipe) + BUG("options path_to_stdin and feed_pipe are mutually exclusive"); + /* reopen the file for stdin; run_command closes it. */ if (hook_cb->options->path_to_stdin) { cp->no_stdin = 0; cp->in = xopen(hook_cb->options->path_to_stdin, O_RDONLY); } - cp->stdout_to_stderr = 1; + + if (hook_cb->options->feed_pipe) { + cp->no_stdin = 0; + /* start_command() will allocate a pipe / stdin fd for us */ + cp->in = -1; + } + + cp->stdout_to_stderr = hook_cb->options->stdout_to_stderr; cp->trace2_hook_name = hook_cb->hook_name; cp->dir = hook_cb->options->dir; @@ -78,6 +89,12 @@ static int pick_next_hook(struct child_process *cp, strvec_pushv(&cp->args, hook_cb->options->args.v); /* + * Provide per-hook internal state via task_cb for easy access, so + * hook callbacks don't have to go through hook_cb->options. + */ + *pp_task_cb = hook_cb->options->feed_pipe_cb_data; + + /* * This pick_next_hook() will be called again, we're only * running one hook, so indicate that no more work will be * done. @@ -135,11 +152,12 @@ int run_hooks_opt(struct repository *r, const char *hook_name, .tr2_category = "hook", .tr2_label = hook_name, - .processes = 1, - .ungroup = 1, + .processes = options->jobs, + .ungroup = options->jobs == 1, .get_next_task = pick_next_hook, .start_failure = notify_start_failure, + .feed_pipe = options->feed_pipe, .task_finished = notify_hook_finished, .data = &cb_data, @@ -148,6 +166,12 @@ int run_hooks_opt(struct repository *r, const char *hook_name, if (!options) BUG("a struct run_hooks_opt must be provided to run_hooks"); + if (options->path_to_stdin && options->feed_pipe) + BUG("options path_to_stdin and feed_pipe are mutually exclusive"); + + if (!options->jobs) + BUG("run_hooks_opt must be called with options.jobs >= 1"); + if (options->invoked_hook) *options->invoked_hook = 0; |
