Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmily Shaffer <emilyshaffer@google.com>2021-12-22 06:59:36 +0300
committerJunio C Hamano <gitster@pobox.com>2022-01-08 02:19:34 +0300
commit1a3017d908824ab42ca7a5af7073f4cdc5c88fbf (patch)
tree1b6711e0a4033c7688eca8e909b307f8ea7e0f43
parent72ddf34d7c62a0b272d5cdd8f62fcfc782bb3a45 (diff)
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 <emilyshaffer@google.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Acked-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/worktree.c26
-rw-r--r--hook.c8
-rw-r--r--hook.h6
3 files changed, 25 insertions, 15 deletions
diff --git a/builtin/worktree.c b/builtin/worktree.c
index a396cfdc64..6f03afad97 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -382,21 +382,17 @@ done:
* is_junk is cleared, but do return appropriate code when hook fails.
*/
if (!ret && opts->checkout) {
- const char *hook = find_hook("post-checkout");
- if (hook) {
- const char *env[] = { "GIT_DIR", "GIT_WORK_TREE", NULL };
- struct child_process cp = CHILD_PROCESS_INIT;
- cp.no_stdin = 1;
- cp.stdout_to_stderr = 1;
- cp.dir = path;
- strvec_pushv(&cp.env_array, env);
- cp.trace2_hook_name = "post-checkout";
- strvec_pushl(&cp.args, absolute_path(hook),
- oid_to_hex(null_oid()),
- oid_to_hex(&commit->object.oid),
- "1", NULL);
- ret = run_command(&cp);
- }
+ struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
+
+ strvec_pushl(&opt.env, "GIT_DIR", "GIT_WORK_TREE", NULL);
+ strvec_pushl(&opt.args,
+ oid_to_hex(null_oid()),
+ oid_to_hex(&commit->object.oid),
+ "1",
+ NULL);
+ opt.dir = path;
+
+ ret = run_hooks_opt("post-checkout", &opt);
}
strvec_clear(&child_env);
diff --git a/hook.c b/hook.c
index 1ad123422b..69a215b2c3 100644
--- a/hook.c
+++ b/hook.c
@@ -57,6 +57,7 @@ static int pick_next_hook(struct child_process *cp,
strvec_pushv(&cp->env_array, hook_cb->options->env.v);
cp->stdout_to_stderr = 1;
cp->trace2_hook_name = hook_cb->hook_name;
+ cp->dir = hook_cb->options->dir;
strvec_push(&cp->args, hook_path);
strvec_pushv(&cp->args, hook_cb->options->args.v);
@@ -109,6 +110,7 @@ static void run_hooks_opt_clear(struct run_hooks_opt *options)
int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
{
+ struct strbuf abs_path = STRBUF_INIT;
struct hook_cb_data cb_data = {
.rc = 0,
.hook_name = hook_name,
@@ -130,6 +132,11 @@ int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
}
cb_data.hook_path = hook_path;
+ if (options->dir) {
+ strbuf_add_absolute_path(&abs_path, hook_path);
+ cb_data.hook_path = abs_path.buf;
+ }
+
run_processes_parallel_tr2(jobs,
pick_next_hook,
notify_start_failure,
@@ -139,6 +146,7 @@ int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
hook_name);
ret = cb_data.rc;
cleanup:
+ strbuf_release(&abs_path);
run_hooks_opt_clear(options);
return ret;
}
diff --git a/hook.h b/hook.h
index 5452839595..18d90aedf1 100644
--- a/hook.h
+++ b/hook.h
@@ -12,6 +12,12 @@ struct run_hooks_opt
/* Emit an error if the hook is missing */
unsigned int error_if_missing:1;
+
+ /**
+ * An optional initial working directory for the hook,
+ * translates to "struct child_process"'s "dir" member.
+ */
+ const char *dir;
};
#define RUN_HOOKS_OPT_INIT { \