[PATCH 7/9] hook: allow out-of-repo 'git hook' invocations
From: Emily Shaffer <hidden>
Date: 2021-07-15 23:26:39
Subsystem:
the rest · Maintainer:
Linus Torvalds
Since hooks can now be supplied via the config, and a config can be
present without a gitdir via the global and system configs, we can start
to allow 'git hook run' to occur without a gitdir. This enables us to do
things like run sendemail-validate hooks when running 'git send-email'
from a nongit directory.
It still doesn't make sense to look for hooks in the hookdir in nongit
repos, though, as there is no hookdir.
Signed-off-by: Emily Shaffer <redacted>
---
Notes:
For hookdir hooks, do we want to run them in nongit dir when core.hooksPath
is set? For example, if someone set core.hooksPath in their global config and
then ran 'git hook run sendemail-validate' in a nongit dir?
git.c | 2 +-
hook.c | 18 ++++++++++--------
t/t1360-config-based-hooks.sh | 13 +++++++++++++
3 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/git.c b/git.c
index 540909c391..39988ee3b0 100644
--- a/git.c
+++ b/git.c@@ -538,7 +538,7 @@ static struct cmd_struct commands[] = { { "grep", cmd_grep, RUN_SETUP_GENTLY }, { "hash-object", cmd_hash_object }, { "help", cmd_help }, - { "hook", cmd_hook, RUN_SETUP }, + { "hook", cmd_hook, RUN_SETUP_GENTLY }, { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY | NO_PARSEOPT }, { "init", cmd_init_db }, { "init-db", cmd_init_db },
diff --git a/hook.c b/hook.c
index ed90edcad7..b08b876d5d 100644
--- a/hook.c
+++ b/hook.c@@ -202,7 +202,6 @@ static int hook_config_lookup(const char *key, const char *value, void *cb_data) struct list_head* hook_list(const char* hookname, int allow_unknown) { struct list_head *hook_head = xmalloc(sizeof(struct list_head)); - const char *hook_path; struct strbuf hook_key = STRBUF_INIT; struct hook_config_cb cb_data = { &hook_key, hook_head };
@@ -216,14 +215,17 @@ struct list_head* hook_list(const char* hookname, int allow_unknown) git_config(hook_config_lookup, &cb_data); - if (allow_unknown) - hook_path = find_hook_gently(hookname); - else - hook_path = find_hook(hookname); + if (have_git_dir()) { + const char *hook_path; + if (allow_unknown) + hook_path = find_hook_gently(hookname); + else + hook_path = find_hook(hookname); - /* Add the hook from the hookdir */ - if (hook_path) - append_or_move_hook(hook_head, hook_path)->from_hookdir = 1; + /* Add the hook from the hookdir */ + if (hook_path) + append_or_move_hook(hook_head, hook_path)->from_hookdir = 1; + } return hook_head; }
diff --git a/t/t1360-config-based-hooks.sh b/t/t1360-config-based-hooks.sh
index 12fca516ec..e4a7b06ad1 100755
--- a/t/t1360-config-based-hooks.sh
+++ b/t/t1360-config-based-hooks.sh@@ -34,6 +34,19 @@ test_expect_success 'git hook rejects commands without a hookname' ' test_must_fail git hook list ' +test_expect_success 'git hook runs outside of a repo' ' + setup_hooks && + + cat >expected <<-EOF && + $ROOT/path/def + EOF + + nongit git config --list --global && + + nongit git hook list pre-commit >actual && + test_cmp expected actual +' + test_expect_success 'git hook list orders by config order' ' setup_hooks &&
--
2.32.0.402.g57bb445576-goog