diff --git a/hook.c b/hook.c index be69f6a4527662..9adb7aba23df51 100644 --- a/hook.c +++ b/hook.c @@ -219,9 +219,15 @@ static int write_post_index_change_sentinel(struct repository *r) */ static int post_index_change_sentinel_exists(struct repository *r) { - char *path = get_post_index_change_sentinel_name(r); + char *path; int res = 1; + /* It can't exist if we don't have a gitdir. */ + if (!r->gitdir) + return 0; + + path = get_post_index_change_sentinel_name(r); + if (unlink(path)) { if (is_missing_file_error(errno)) res = 0; @@ -233,6 +239,21 @@ static int post_index_change_sentinel_exists(struct repository *r) return res; } +static int check_worktree_change(const char *key, const char *value, + UNUSED const struct config_context *ctx, + void *data) +{ + int *enabled = data; + + if (!strcmp(key, "postcommand.strategy") && + !strcasecmp(value, "worktree-change")) { + *enabled = 1; + return 1; + } + + return 0; +} + /** * See if we can replace the requested hook with an internal behavior. * Returns 0 if the real hook should run. Returns nonzero if we instead @@ -242,9 +263,11 @@ static int handle_hook_replacement(struct repository *r, const char *hook_name, struct strvec *args) { - const char *strval; - if (repo_config_get_string_tmp(r, "postcommand.strategy", &strval) || - strcasecmp(strval, "worktree-change")) + int enabled = 0; + + read_early_config(r, check_worktree_change, &enabled); + + if (!enabled) return 0; if (!strcmp(hook_name, "post-index-change")) { @@ -290,8 +313,7 @@ int run_hooks_opt(struct repository *r, const char *hook_name, }; /* Interject hook behavior depending on strategy. */ - if (r && r->gitdir && - handle_hook_replacement(r, hook_name, &options->args)) + if (r && handle_hook_replacement(r, hook_name, &options->args)) return 0; hook_path = find_hook(r, hook_name); diff --git a/t/t0401-post-command-hook.sh b/t/t0401-post-command-hook.sh index 0cc41e6210b86e..f1d4700e7e8abe 100755 --- a/t/t0401-post-command-hook.sh +++ b/t/t0401-post-command-hook.sh @@ -78,12 +78,35 @@ test_expect_success 'with post-index-change config' ' test_cmp expect post-index-change.out && test_path_is_missing post-command.out && + # add keeps the worktree the same, so does not run post-command. + # and this should work through an alias. + git config alias.addalias add && + rm -f post-command.out post-index-change.out && + echo more stuff >>file && + git addalias file && + test_cmp expect post-index-change.out && + test_path_is_missing post-command.out && + echo stuff >>file && # reset --hard updates the worktree. + # even through an alias + git config alias.resetalias "reset --hard" && rm -f post-command.out post-index-change.out && - git reset --hard && + git resetalias && test_cmp expect post-index-change.out && - test_cmp expect post-command.out + test_cmp expect post-command.out && + + rm -f post-command.out && + test_must_fail git && # get help text + test_path_is_missing post-command.out && + + rm -f post-command.out && + git version && + test_path_is_missing post-command.out && + + rm -f post-command.out && + test_must_fail git typo && + test_path_is_missing post-command.out ' test_done