Skip to content

Commit 1a3017d

Browse files
nasamuffingitster
authored andcommitted
hooks: convert worktree 'post-checkout' hook to hook library
Move the running of the 'post-checkout' hook away from run-command.h to the new hook.h library in builtin/worktree.c. For this special case we need a change to the hook API to teach it to run the hook from a given directory. We cannot skip the "absolute_path" flag and just check if "dir" is specified as we'd then fail to find our hook in the new dir we'd chdir() to. We currently don't have a use-case for running a hook not in our "base" repository at a given absolute path, so let's have "dir" imply absolute_path(find_hook(hook_name)). Signed-off-by: Emily Shaffer <[email protected]> Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Acked-by: Emily Shaffer <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 72ddf34 commit 1a3017d

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

builtin/worktree.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -382,21 +382,17 @@ static int add_worktree(const char *path, const char *refname,
382382
* is_junk is cleared, but do return appropriate code when hook fails.
383383
*/
384384
if (!ret && opts->checkout) {
385-
const char *hook = find_hook("post-checkout");
386-
if (hook) {
387-
const char *env[] = { "GIT_DIR", "GIT_WORK_TREE", NULL };
388-
struct child_process cp = CHILD_PROCESS_INIT;
389-
cp.no_stdin = 1;
390-
cp.stdout_to_stderr = 1;
391-
cp.dir = path;
392-
strvec_pushv(&cp.env_array, env);
393-
cp.trace2_hook_name = "post-checkout";
394-
strvec_pushl(&cp.args, absolute_path(hook),
395-
oid_to_hex(null_oid()),
396-
oid_to_hex(&commit->object.oid),
397-
"1", NULL);
398-
ret = run_command(&cp);
399-
}
385+
struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
386+
387+
strvec_pushl(&opt.env, "GIT_DIR", "GIT_WORK_TREE", NULL);
388+
strvec_pushl(&opt.args,
389+
oid_to_hex(null_oid()),
390+
oid_to_hex(&commit->object.oid),
391+
"1",
392+
NULL);
393+
opt.dir = path;
394+
395+
ret = run_hooks_opt("post-checkout", &opt);
400396
}
401397

402398
strvec_clear(&child_env);

hook.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ static int pick_next_hook(struct child_process *cp,
5757
strvec_pushv(&cp->env_array, hook_cb->options->env.v);
5858
cp->stdout_to_stderr = 1;
5959
cp->trace2_hook_name = hook_cb->hook_name;
60+
cp->dir = hook_cb->options->dir;
6061

6162
strvec_push(&cp->args, hook_path);
6263
strvec_pushv(&cp->args, hook_cb->options->args.v);
@@ -109,6 +110,7 @@ static void run_hooks_opt_clear(struct run_hooks_opt *options)
109110

110111
int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
111112
{
113+
struct strbuf abs_path = STRBUF_INIT;
112114
struct hook_cb_data cb_data = {
113115
.rc = 0,
114116
.hook_name = hook_name,
@@ -130,6 +132,11 @@ int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
130132
}
131133

132134
cb_data.hook_path = hook_path;
135+
if (options->dir) {
136+
strbuf_add_absolute_path(&abs_path, hook_path);
137+
cb_data.hook_path = abs_path.buf;
138+
}
139+
133140
run_processes_parallel_tr2(jobs,
134141
pick_next_hook,
135142
notify_start_failure,
@@ -139,6 +146,7 @@ int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
139146
hook_name);
140147
ret = cb_data.rc;
141148
cleanup:
149+
strbuf_release(&abs_path);
142150
run_hooks_opt_clear(options);
143151
return ret;
144152
}

hook.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ struct run_hooks_opt
1212

1313
/* Emit an error if the hook is missing */
1414
unsigned int error_if_missing:1;
15+
16+
/**
17+
* An optional initial working directory for the hook,
18+
* translates to "struct child_process"'s "dir" member.
19+
*/
20+
const char *dir;
1521
};
1622

1723
#define RUN_HOOKS_OPT_INIT { \

0 commit comments

Comments
 (0)