> +int hook_exists(const char *hookname) > +{ > + const char *value = NULL; > + struct strbuf hook_key = STRBUF_INIT; > + strbuf_addf(&hook_key, "hook.%s.command", hookname); > + > + return (!git_config_get_value(hook_key.buf, &value)) || !!find_hook(hookname); > +} I was surprised that this didn't share code with hook_list. Upon further thought, hook_list might be expensive if hooks are present, but if we can cache results, I think it's worth it. A caller that calls this function usually will run hooks if they are present, so it's not wasted work to construct the hook list.