Merge branch 'es/worktree-add-post-checkout-hook'

"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
This commit is contained in:
Junio C Hamano 2018-02-28 13:37:53 -08:00
commit 619e5218cb
2 changed files with 62 additions and 12 deletions

View 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 * Hook failure does not warrant worktree deletion, so run hook after
* is_junk is cleared, but do return appropriate code when hook fails. * is_junk is cleared, but do return appropriate code when hook fails.
*/ */
if (!ret && opts->checkout) if (!ret && opts->checkout) {
ret = run_hook_le(NULL, "post-checkout", oid_to_hex(&null_oid), const char *hook = find_hook("post-checkout");
oid_to_hex(&commit->object.oid), "1", NULL); 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); argv_array_clear(&child_env);
strbuf_release(&sb); strbuf_release(&sb);

View file

@ -451,32 +451,68 @@ test_expect_success 'git worktree --no-guess-remote option overrides config' '
' '
post_checkout_hook () { post_checkout_hook () {
test_when_finished "rm -f .git/hooks/post-checkout" && gitdir=${1:-.git}
mkdir -p .git/hooks && test_when_finished "rm -f $gitdir/hooks/post-checkout" &&
write_script .git/hooks/post-checkout <<-\EOF mkdir -p $gitdir/hooks &&
echo $* >hook.actual write_script $gitdir/hooks/post-checkout <<-\EOF
{
echo $*
git rev-parse --git-dir --show-toplevel
} >hook.actual
EOF EOF
} }
test_expect_success '"add" invokes post-checkout hook (branch)' ' test_expect_success '"add" invokes post-checkout hook (branch)' '
post_checkout_hook && 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 && 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)' ' test_expect_success '"add" invokes post-checkout hook (detached)' '
post_checkout_hook && 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 && 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' ' test_expect_success '"add --no-checkout" suppresses post-checkout hook' '
post_checkout_hook && post_checkout_hook &&
rm -f hook.actual && rm -f hook.actual &&
git worktree add --no-checkout gloopy && 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 test_done