Web lists-archives.com

[PATCH v2 4/7] builtin/worktree: add support for multiple post-checkout hooks




Add support for multiple post-checkout hooks. We test only one possible
path in the multiple hook case because the same code path is used for
all checkouts and we know the hooks work from earlier assertions.

Signed-off-by: brian m. carlson <sandals@xxxxxxxxxxxxxxxxxxxx>
---
 builtin/worktree.c            | 44 ++++++++++++++++++++++-------------
 t/t5403-post-checkout-hook.sh |  8 +++++++
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index d2a7e2f3f1..1edcde8c84 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -262,6 +262,32 @@ static void validate_worktree_add(const char *path, const struct add_opts *opts)
 	free_worktrees(worktrees);
 }
 
+struct hook_data {
+	struct commit *commit;
+	const char *dir;
+};
+
+static int run_post_checkout_hook(const char *name, const char *path, void *p)
+{
+	struct hook_data *data = p;
+	struct commit *commit = data->commit;
+	const char *env[] = { "GIT_DIR", "GIT_WORK_TREE", NULL };
+	struct child_process cp = CHILD_PROCESS_INIT;
+
+	cp.git_cmd = 0;
+	cp.no_stdin = 1;
+	cp.stdout_to_stderr = 1;
+	cp.dir = data->dir;
+	cp.env = env;
+	cp.argv = NULL;
+	cp.trace2_hook_name = "post-checkout";
+	argv_array_pushl(&cp.args, absolute_path(path),
+			 oid_to_hex(&null_oid),
+			 oid_to_hex(&commit->object.oid),
+			 "1", NULL);
+	return run_command(&cp);
+}
+
 static int add_worktree(const char *path, const char *refname,
 			const struct add_opts *opts)
 {
@@ -395,22 +421,8 @@ static int add_worktree(const char *path, const char *refname,
 	 * 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 };
-			cp.git_cmd = 0;
-			cp.no_stdin = 1;
-			cp.stdout_to_stderr = 1;
-			cp.dir = path;
-			cp.env = env;
-			cp.argv = NULL;
-			cp.trace2_hook_name = "post-checkout";
-			argv_array_pushl(&cp.args, absolute_path(hook),
-					 oid_to_hex(&null_oid),
-					 oid_to_hex(&commit->object.oid),
-					 "1", NULL);
-			ret = run_command(&cp);
-		}
+		struct hook_data data = { commit, path };
+		ret = for_each_hook("post-checkout", run_post_checkout_hook, &data);
 	}
 
 	argv_array_clear(&child_env);
diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh
index a39b3b5c78..aa265ce610 100755
--- a/t/t5403-post-checkout-hook.sh
+++ b/t/t5403-post-checkout-hook.sh
@@ -5,6 +5,7 @@
 
 test_description='Test the post-checkout hook.'
 . ./test-lib.sh
+. "$TEST_DIRECTORY/lib-hooks.sh"
 
 test_expect_success setup '
 	mkdir -p .git/hooks &&
@@ -73,4 +74,11 @@ test_expect_success 'post-checkout hook is triggered by clone' '
 	test -f clone3/.git/post-checkout.args
 '
 
+cmd_rebase () {
+	git checkout -B hook-test rebase-on-me^ &&
+	git rebase rebase-on-me
+}
+
+test_multiple_hooks post-checkout cmd_rebase
+
 test_done