Originally "run_hook()" that used to live in builtin/commit.c had a perfectly appropriate API and name for a private function to spawn a hook from "git commit" command. The only necessary tweak in the context was to optionally specify which file to use as the index file. But then we stupidly moved this private API to run-command.c without making the interface suitable for general consumption, and there is no way to tweak environment variables other than GIT_INDEX_FILE when running a hook. Correct this mistake by adding run_hook_e() that takes an array of environment variables. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- * This is the third patch of the more complex of the two approaches. Instead of the simpler "setenv()" one, the final one tries to limit the environment change only to the hook scripts, without affecting the "git commit" process itself. It probably should not make much difference in the short run, but later when we want to distinguish where the authorship came from, it may be easier to tell with this approach as it does not contaminate the environment of "git commit" itself with what we obtained from "--author" option. Also this is independently a useful refactoring. run-command.c | 49 ++++++++++++++++++++++++++++++++++++------------- run-command.h | 1 + 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/run-command.c b/run-command.c index 1db8abf..a51d8e5 100644 --- a/run-command.c +++ b/run-command.c @@ -672,36 +672,59 @@ int finish_async(struct async *async) #endif } -int run_hook(const char *index_file, const char *name, ...) +static int run_hook_le(const char *const *env, + const char *name, + va_list args) { struct child_process hook; struct argv_array argv = ARGV_ARRAY_INIT; - const char *p, *env[2]; - char index[PATH_MAX]; - va_list args; + const char *p; int ret; if (access(git_path("hooks/%s", name), X_OK) < 0) return 0; - va_start(args, name); argv_array_push(&argv, git_path("hooks/%s", name)); while ((p = va_arg(args, const char *))) argv_array_push(&argv, p); - va_end(args); memset(&hook, 0, sizeof(hook)); hook.argv = argv.argv; hook.no_stdin = 1; hook.stdout_to_stderr = 1; - if (index_file) { - snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); - env[0] = index; - env[1] = NULL; - hook.env = env; - } - + hook.env = env; ret = run_command(&hook); argv_array_clear(&argv); return ret; } + +int run_hook(const char *index_file, const char *name, ...) +{ + const char *const *env = NULL, *env_buf[2]; + struct strbuf index_buf = STRBUF_INIT; + int status; + va_list args; + + va_start(args, name); + if (index_file) { + strbuf_addf(&index_buf, "GIT_INDEX_FILE=%s", index_file); + env_buf[0] = index_buf.buf; + env_buf[1] = NULL; + env = env_buf; + } + status = run_hook_le(env, name, args); + va_end(args); + strbuf_release(&index_buf); + return status; +} + +int run_hook_e(const char *const *env, const char *name, ...) +{ + int status; + va_list args; + + va_start(args, name); + status = run_hook_le(env, name, args); + va_end(args); + return status; +} diff --git a/run-command.h b/run-command.h index 44f7d2b..87207b9 100644 --- a/run-command.h +++ b/run-command.h @@ -47,6 +47,7 @@ int finish_command(struct child_process *); int run_command(struct child_process *); extern int run_hook(const char *index_file, const char *name, ...); +extern int run_hook_e(const char *const *, const char *name, ...); #define RUN_COMMAND_NO_STDIN 1 #define RUN_GIT_CMD 2 /*If this is to be git sub-command */ -- 1.7.10.rc0.33.g8866af -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html