Merge branch 'es/worktree-add-post-checkout-hook'
authorJunio C Hamano <gitster@pobox.com>
Wed, 28 Feb 2018 21:37:53 +0000 (13:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 28 Feb 2018 21:37:53 +0000 (13:37 -0800)
"git worktree add" learned to run the post-checkout hook, just like
"git clone" runs it upon the initial checkout.

* es/worktree-add-post-checkout-hook:
worktree: add: fix 'post-checkout' not knowing new worktree location

builtin/worktree.c
t/t2025-worktree-add.sh
index 9efdc224661b02192d06c6877e49c5585ddbcdca..4e7c98758fcfb93c19e3dbf58fc3167829e998b8 100644 (file)
@@ -345,9 +345,23 @@ static int add_worktree(const char *path, const char *refname,
         * Hook failure does not warrant worktree deletion, so run hook after
         * is_junk is cleared, but do return appropriate code when hook fails.
         */
-       if (!ret && opts->checkout)
-               ret = run_hook_le(NULL, "post-checkout", oid_to_hex(&null_oid),
-                                 oid_to_hex(&commit->object.oid), "1", NULL);
+       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;
+                       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);
+               }
+       }
 
        argv_array_clear(&child_env);
        strbuf_release(&sb);
index 2b959449730e14dd4e650ce9115a463d71eedca4..d0d2e4f7ec3310ec51da7144fa87151129f393c0 100755 (executable)
@@ -451,32 +451,68 @@ test_expect_success 'git worktree --no-guess-remote option overrides config' '
 '
 
 post_checkout_hook () {
-       test_when_finished "rm -f .git/hooks/post-checkout" &&
-       mkdir -p .git/hooks &&
-       write_script .git/hooks/post-checkout <<-\EOF
-       echo $* >hook.actual
+       gitdir=${1:-.git}
+       test_when_finished "rm -f $gitdir/hooks/post-checkout" &&
+       mkdir -p $gitdir/hooks &&
+       write_script $gitdir/hooks/post-checkout <<-\EOF
+       {
+               echo $*
+               git rev-parse --git-dir --show-toplevel
+       } >hook.actual
        EOF
 }
 
 test_expect_success '"add" invokes post-checkout hook (branch)' '
        post_checkout_hook &&
-       printf "%s %s 1\n" $_z40 $(git rev-parse HEAD) >hook.expect &&
+       {
+               echo $_z40 $(git rev-parse HEAD) 1 &&
+               echo $(pwd)/.git/worktrees/gumby &&
+               echo $(pwd)/gumby
+       } >hook.expect &&
        git worktree add gumby &&
-       test_cmp hook.expect hook.actual
+       test_cmp hook.expect gumby/hook.actual
 '
 
 test_expect_success '"add" invokes post-checkout hook (detached)' '
        post_checkout_hook &&
-       printf "%s %s 1\n" $_z40 $(git rev-parse HEAD) >hook.expect &&
+       {
+               echo $_z40 $(git rev-parse HEAD) 1 &&
+               echo $(pwd)/.git/worktrees/grumpy &&
+               echo $(pwd)/grumpy
+       } >hook.expect &&
        git worktree add --detach grumpy &&
-       test_cmp hook.expect hook.actual
+       test_cmp hook.expect grumpy/hook.actual
 '
 
 test_expect_success '"add --no-checkout" suppresses post-checkout hook' '
        post_checkout_hook &&
        rm -f hook.actual &&
        git worktree add --no-checkout gloopy &&
-       test_path_is_missing hook.actual
+       test_path_is_missing gloopy/hook.actual
+'
+
+test_expect_success '"add" in other worktree invokes post-checkout hook' '
+       post_checkout_hook &&
+       {
+               echo $_z40 $(git rev-parse HEAD) 1 &&
+               echo $(pwd)/.git/worktrees/guppy &&
+               echo $(pwd)/guppy
+       } >hook.expect &&
+       git -C gloopy worktree add --detach ../guppy &&
+       test_cmp hook.expect guppy/hook.actual
+'
+
+test_expect_success '"add" in bare repo invokes post-checkout hook' '
+       rm -rf bare &&
+       git clone --bare . bare &&
+       {
+               echo $_z40 $(git --git-dir=bare rev-parse HEAD) 1 &&
+               echo $(pwd)/bare/worktrees/goozy &&
+               echo $(pwd)/goozy
+       } >hook.expect &&
+       post_checkout_hook bare &&
+       git -C bare worktree add --detach ../goozy &&
+       test_cmp hook.expect goozy/hook.actual
 '
 
 test_done