mirror of
https://github.com/git/git.git
synced 2026-01-09 01:34:00 +00:00
hook: provide stdin via callback
This adds a callback mechanism for feeding stdin to hooks alongside the existing path_to_stdin (which slurps a file's content to stdin). The advantage of this new callback is that it can feed stdin without going through the FS layer. This helps when feeding large amount of data and uses the run-command parallel stdin callback introduced in the preceding commit. Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
23a720e96b
commit
26238496a7
23
hook.c
23
hook.c
@@ -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,11 +65,22 @@ 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);
|
||||
}
|
||||
|
||||
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 = 1;
|
||||
cp->trace2_hook_name = hook_cb->hook_name;
|
||||
cp->dir = hook_cb->options->dir;
|
||||
@@ -77,6 +88,12 @@ static int pick_next_hook(struct child_process *cp,
|
||||
strvec_push(&cp->args, hook_path);
|
||||
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
|
||||
@@ -140,6 +157,7 @@ int run_hooks_opt(struct repository *r, const char *hook_name,
|
||||
|
||||
.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,9 @@ 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->invoked_hook)
|
||||
*options->invoked_hook = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user