Add a helper to easily determine whether any hooks exist for a given hook event. Many callers want to check whether some state could be modified by a hook; that check should include the config-based hooks as well. Optimize by checking the config directly. Since commands which execute hooks might want to take args to replace 'hook.runHookDir', let 'hook_exists()' mirror the behavior of 'hook.runHookDir'. Signed-off-by: Emily Shaffer <emilyshaffer@xxxxxxxxxx> --- Notes: Since v4, a little more nuance when deciding whether a hookdir hook can happen. hook.c | 14 ++++++++++++++ hook.h | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/hook.c b/hook.c index 1494a32c1a..e3d289d0e9 100644 --- a/hook.c +++ b/hook.c @@ -218,6 +218,20 @@ struct list_head* hook_list(const struct strbuf* hookname) return hook_head; } +int hook_exists(const char *hookname, enum hookdir_opt should_run_hookdir) +{ + const char *value = NULL; /* throwaway */ + struct strbuf hook_key = STRBUF_INIT; + + int could_run_hookdir = (should_run_hookdir == hookdir_interactive || + should_run_hookdir == hookdir_warn || + should_run_hookdir == hookdir_yes) + && !!find_hook(hookname); + + strbuf_addf(&hook_key, "hook.%s.command", hookname); + + return (!git_config_get_value(hook_key.buf, &value)) || could_run_hookdir; +} int run_hooks(const char *const *env, const char *hookname, const struct strvec *args, enum hookdir_opt run_hookdir) diff --git a/hook.h b/hook.h index 6eb1dc99c4..bf8ea3ee11 100644 --- a/hook.h +++ b/hook.h @@ -36,6 +36,15 @@ enum hookdir_opt * command line arguments. */ enum hookdir_opt configured_hookdir_opt(void); + +/* + * Returns 1 if any hooks are specified in the config or if a hook exists in the + * hookdir. Typically, invoke hook_exsts() like: + * hook_exists(hookname, configured_hookdir_opt()); + * Like with run_hooks, if you take a --run-hookdir flag, reflect that + * user-specified behavior here instead. + */ +int hook_exists(const char *hookname, enum hookdir_opt should_run_hookdir); /* * Runs all hooks associated to the 'hookname' event in order. Each hook will be * passed 'env' and 'args'. -- 2.28.0.rc0.142.g3c755180ce-goog