Skip to content

Commit bc0afba

Browse files
nasamuffingitster
authored andcommitted
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>
1 parent 5abec8f commit bc0afba

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

hook.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,22 @@ static int pick_next_hook(struct child_process *cp,
6565

6666
cp->no_stdin = 1;
6767
strvec_pushv(&cp->env, hook_cb->options->env.v);
68+
69+
if (hook_cb->options->path_to_stdin && hook_cb->options->feed_pipe)
70+
BUG("options path_to_stdin and feed_pipe are mutually exclusive");
71+
6872
/* reopen the file for stdin; run_command closes it. */
6973
if (hook_cb->options->path_to_stdin) {
7074
cp->no_stdin = 0;
7175
cp->in = xopen(hook_cb->options->path_to_stdin, O_RDONLY);
7276
}
77+
78+
if (hook_cb->options->feed_pipe) {
79+
cp->no_stdin = 0;
80+
/* start_command() will allocate a pipe / stdin fd for us */
81+
cp->in = -1;
82+
}
83+
7384
cp->stdout_to_stderr = 1;
7485
cp->trace2_hook_name = hook_cb->hook_name;
7586
cp->dir = hook_cb->options->dir;
@@ -140,6 +151,7 @@ int run_hooks_opt(struct repository *r, const char *hook_name,
140151

141152
.get_next_task = pick_next_hook,
142153
.start_failure = notify_start_failure,
154+
.feed_pipe = options->feed_pipe,
143155
.task_finished = notify_hook_finished,
144156

145157
.data = &cb_data,
@@ -148,6 +160,9 @@ int run_hooks_opt(struct repository *r, const char *hook_name,
148160
if (!options)
149161
BUG("a struct run_hooks_opt must be provided to run_hooks");
150162

163+
if (options->path_to_stdin && options->feed_pipe)
164+
BUG("choose only one method to populate hook stdin");
165+
151166
if (options->invoked_hook)
152167
*options->invoked_hook = 0;
153168

hook.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef HOOK_H
22
#define HOOK_H
33
#include "strvec.h"
4+
#include "run-command.h"
45

56
struct repository;
67

@@ -37,6 +38,28 @@ struct run_hooks_opt
3738
* Path to file which should be piped to stdin for each hook.
3839
*/
3940
const char *path_to_stdin;
41+
42+
/**
43+
* Callback to ask for more content to pipe to each hook stdin.
44+
*
45+
* If a hook needs to consume large quantities of data (e.g. a
46+
* list of all refs received in a client push), feeding data via
47+
* in-memory strings or slurping to/from files via path_to_stdin
48+
* is inefficient, so this callback allows for piecemeal writes.
49+
*
50+
* Add initalization context to hook.feed_pipe_ctx.
51+
*
52+
* The caller owns hook.feed_pipe_ctx and has to release any
53+
* resources after hooks finish execution.
54+
*/
55+
feed_pipe_fn feed_pipe;
56+
void *feed_pipe_ctx;
57+
58+
/**
59+
* Use this to keep internal state for your feed_pipe_fn callback.
60+
* Only useful when using run_hooks_opt.feed_pipe, otherwise ignore it.
61+
*/
62+
void *feed_pipe_cb_data;
4063
};
4164

4265
#define RUN_HOOKS_OPT_INIT { \

0 commit comments

Comments
 (0)