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 @@ done:
* 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);

View File

@ -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