mirror of
https://github.com/git/git.git
synced 2026-02-27 10:25:07 +00:00
hook: allow disabling config hooks
Hooks specified via configs are always enabled, however users might want to disable them without removing from the config, like locally disabling a global hook. Add a hook.<name>.enabled config which defaults to true and can be optionally set for each configured hook. Suggested-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
03b4043b91
commit
1ecce722cd
@@ -13,3 +13,10 @@ hook.<name>.event::
|
||||
specified event, the associated `hook.<name>.command` is executed.
|
||||
This is a multi-valued key. To run `hook.<name>` on multiple
|
||||
events, specify the key more than once. See linkgit:git-hook[1].
|
||||
|
||||
hook.<name>.enabled::
|
||||
Whether the hook `hook.<name>` is enabled. Defaults to `true`.
|
||||
Set to `false` to disable the hook without removing its
|
||||
configuration. This is particularly useful when a hook is defined
|
||||
in a system or global config file and needs to be disabled for a
|
||||
specific repository. See linkgit:git-hook[1].
|
||||
|
||||
20
hook.c
20
hook.c
@@ -164,6 +164,21 @@ static int hook_config_lookup_all(const char *key, const char *value,
|
||||
char *old = strmap_put(&data->commands, hook_name,
|
||||
xstrdup(value));
|
||||
free(old);
|
||||
} else if (!strcmp(subkey, "enabled")) {
|
||||
switch (git_parse_maybe_bool(value)) {
|
||||
case 0: /* disabled */
|
||||
if (!unsorted_string_list_lookup(&data->disabled_hooks,
|
||||
hook_name))
|
||||
string_list_append(&data->disabled_hooks,
|
||||
hook_name);
|
||||
break;
|
||||
case 1: /* enabled: undo a prior disabled entry */
|
||||
unsorted_string_list_remove(&data->disabled_hooks,
|
||||
hook_name);
|
||||
break;
|
||||
default:
|
||||
break; /* ignore unrecognised values */
|
||||
}
|
||||
}
|
||||
|
||||
free(hook_name);
|
||||
@@ -216,6 +231,11 @@ static void build_hook_config_map(struct repository *r, struct strmap *cache)
|
||||
const char *hname = hook_names->items[i].string;
|
||||
char *command;
|
||||
|
||||
/* filter out disabled hooks */
|
||||
if (unsorted_string_list_lookup(&cb_data.disabled_hooks,
|
||||
hname))
|
||||
continue;
|
||||
|
||||
command = strmap_get(&cb_data.commands, hname);
|
||||
if (!command)
|
||||
die(_("'hook.%s.command' must be configured or "
|
||||
|
||||
@@ -318,6 +318,38 @@ test_expect_success 'rejects hooks with no commands configured' '
|
||||
test_grep "hook.broken.command" actual
|
||||
'
|
||||
|
||||
test_expect_success 'disabled hook is not run' '
|
||||
test_config hook.skipped.event "test-hook" &&
|
||||
test_config hook.skipped.command "echo \"Should not run\"" &&
|
||||
test_config hook.skipped.enabled false &&
|
||||
|
||||
git hook run --ignore-missing test-hook 2>actual &&
|
||||
test_must_be_empty actual
|
||||
'
|
||||
|
||||
test_expect_success 'disabled hook does not appear in git hook list' '
|
||||
test_config hook.active.event "pre-commit" &&
|
||||
test_config hook.active.command "echo active" &&
|
||||
test_config hook.inactive.event "pre-commit" &&
|
||||
test_config hook.inactive.command "echo inactive" &&
|
||||
test_config hook.inactive.enabled false &&
|
||||
|
||||
git hook list pre-commit >actual &&
|
||||
test_grep "active" actual &&
|
||||
test_grep ! "inactive" actual
|
||||
'
|
||||
|
||||
test_expect_success 'globally disabled hook can be re-enabled locally' '
|
||||
test_config_global hook.global-hook.event "test-hook" &&
|
||||
test_config_global hook.global-hook.command "echo \"global-hook ran\"" &&
|
||||
test_config_global hook.global-hook.enabled false &&
|
||||
test_config hook.global-hook.enabled true &&
|
||||
|
||||
echo "global-hook ran" >expected &&
|
||||
git hook run test-hook 2>actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'git hook run a hook with a bad shebang' '
|
||||
test_when_finished "rm -rf bad-hooks" &&
|
||||
mkdir bad-hooks &&
|
||||
|
||||
Reference in New Issue
Block a user