> On 12 Feb 2018, at 04:15, Eric Sunshine <sunshine@xxxxxxxxxxxxxx> wrote: > > Git commands which run hooks do so at the top level of the worktree in > which the command itself was invoked. However, the 'git worktree' > command may need to run hooks within some other directory. For > instance, when "git worktree add" runs the 'post-checkout' hook, the > hook must be run within the newly-created worktree, not within the > worktree from which "git worktree add" was invoked. > > To support this case, add 'run-hook' overloads which allow the > worktree directory to be specified. > > Signed-off-by: Eric Sunshine <sunshine@xxxxxxxxxxxxxx> > --- > run-command.c | 23 +++++++++++++++++++++-- > run-command.h | 4 ++++ > 2 files changed, 25 insertions(+), 2 deletions(-) > > diff --git a/run-command.c b/run-command.c > index 31fc5ea86e..0e3995bbf9 100644 > --- a/run-command.c > +++ b/run-command.c > @@ -1197,7 +1197,8 @@ const char *find_hook(const char *name) > return path.buf; > } > > -int run_hook_ve(const char *const *env, const char *name, va_list args) > +int run_hook_cd_ve(const char *dir, const char *const *env, const char *name, > + va_list args) > { > struct child_process hook = CHILD_PROCESS_INIT; > const char *p; > @@ -1206,9 +1207,10 @@ int run_hook_ve(const char *const *env, const char *name, va_list args) > if (!p) > return 0; > > - argv_array_push(&hook.args, p); > + argv_array_push(&hook.args, absolute_path(p)); > while ((p = va_arg(args, const char *))) > argv_array_push(&hook.args, p); > + hook.dir = dir; > hook.env = env; > hook.no_stdin = 1; > hook.stdout_to_stderr = 1; > @@ -1216,6 +1218,23 @@ int run_hook_ve(const char *const *env, const char *name, va_list args) > return run_command(&hook); > } > > +int run_hook_ve(const char *const *env, const char *name, va_list args) > +{ > + return run_hook_cd_ve(NULL, env, name, args); > +} I think we have only one more user for this function: builtin/commit.c: ret = run_hook_ve(hook_env.argv,name, args); The other function 'run_hook_le' is used in a few places: builtin/am.c: ret = run_hook_le(NULL, "applypatch-msg", am_path(state, "final-commit"), NULL); builtin/am.c: if (run_hook_le(NULL, "pre-applypatch", NULL)) builtin/am.c: run_hook_le(NULL, "post-applypatch", NULL); builtin/checkout.c: return run_hook_le(NULL, "post-checkout", builtin/clone.c: err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1), builtin/gc.c: if (run_hook_le(NULL, "pre-auto-gc", NULL)) builtin/merge.c: run_hook_le(NULL, "post-merge", squash ? "1" : "0", NULL); builtin/receive-pack.c: if (run_hook_le(env->argv, push_to_checkout_hook, Would it be an option to just use the new function signature everywhere and remove the wrapper? Or do we value the old interface? - Lars > + > +int run_hook_cd_le(const char *dir, const char *const *env, const char *name, ...) > +{ > + va_list args; > + int ret; > + > + va_start(args, name); > + ret = run_hook_cd_ve(dir, env, name, args); > + va_end(args); > + > + return ret; > +} > + > int run_hook_le(const char *const *env, const char *name, ...) > { > va_list args; > diff --git a/run-command.h b/run-command.h > index 3932420ec8..8beddffea8 100644 > --- a/run-command.h > +++ b/run-command.h > @@ -66,7 +66,11 @@ int run_command(struct child_process *); > extern const char *find_hook(const char *name); > LAST_ARG_MUST_BE_NULL > extern int run_hook_le(const char *const *env, const char *name, ...); > +extern int run_hook_cd_le(const char *dir, const char *const *env, > + const char *name, ...); > extern int run_hook_ve(const char *const *env, const char *name, va_list args); > +extern int run_hook_cd_ve(const char *dir, const char *const *env, > + const char *name, va_list args); > > #define RUN_COMMAND_NO_STDIN 1 > #define RUN_GIT_CMD 2 /*If this is to be git sub-command */ > -- > 2.16.1.291.g4437f3f132 >