-
Notifications
You must be signed in to change notification settings - Fork 142
docs: document core.hooksPath=/dev/null #1899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
/submit |
Submitted as [email protected] To fetch this version into
To fetch this version to local tag
|
On the Git mailing list, "brian m. carlson" wrote (reply to this): On 2025-04-03 at 22:38:08, Derrick Stolee via GitGitGadget wrote:
> From: Derrick Stolee <[email protected]>
>
> Git has several hooks which are executed during certain events as long
> as those hooks are enabled in the hooks directory (possibly moved from
> .git/hooks via the core.hooksPath config option). These are configured
> by the user, or perhaps by tooling the user has agreed to, and are not
> required to operate a Git repository.
>
> In some situations, these hooks have poor performance and expert users
> may want to skip the hooks as they don't seem to affect the current
> situation. One example is a pre-commit hook that checks for certain
> structures in the local changes, but expert users are likely to have
> done the right thing in advance.
>
> I have come across users who have disabled hooks themselves either by
> deleting hooks (supported, safe) or setting 'core.hooksPath' to some
> bogus path (seems unsafe). The supported process is painful to swap
> between the hook-enabled scenario and the hook-disabled scenario.
>
> To that end, add a new --no-hooks global option to allow users to
> disable hooks quickly. This option is modeled similarly to the
> --no-advice option in b79deeb554 (advice: add --no-advice global option,
> 2024-05-03). This uses a GIT_HOOKS environment variable to communicate
> to subprocesses as well as making this a backwards-compatible way for
> tools to signal that they want to disable hooks.
>
> The critical piece is that all hooks pass through run_hooks_opt() where
> a static int will evaluate the environment variable and store that the
> variable is initialized for faster repeated runs.
>
> Signed-off-by: Derrick Stolee <[email protected]>
> ---
> git: add --no-hooks global option
>
> This is hopefully a helpful feature to more than just the experts I've
> been hearing from.
I think this is functionality that Jenkins wants because they've
configured `core.hooksPath` to `/dev/null`, allegedly for security
reasons. Of course, enabling this feature will also break Git LFS, but
in a less noticeable and detectable way (currently, Git LFS will fail on
attempting to install hooks with that setting of `core.hooksPath`, which
is at least noticeable).
I do think that in general certain types of hooks, such as pre-commit
hooks, should absolutely be optional. There are lots of reasons to
commit WIP data that doesn't meet whatever standard and we shouldn't
impede expert users from expert workflows, even if there are many fewer
reasons to do things like bypass pushing Git LFS objects (which are
important for integrity).
So I can see the utility of this feature but I can also see how it can
break lots of things when handled poorly. Of course, we also have `git
reset --hard` and there's lots of hand-wringing on Stack Overflow about
having deleted important data, so we have some precedent for expert
features that could break things badly.
I don't otherwise have a strong opinion either way, although I'd lean
slightly in favour of this series. I'd of course welcome other people's
thoughts here.
--
brian m. carlson (they/them)
Toronto, Ontario, CA |
User |
On the Git mailing list, Derrick Stolee wrote (reply to this): On 4/3/2025 6:55 PM, brian m. carlson wrote:
> On 2025-04-03 at 22:38:08, Derrick Stolee via GitGitGadget wrote:
>> From: Derrick Stolee <[email protected]>
>> To that end, add a new --no-hooks global option to allow users to
>> disable hooks quickly. This option is modeled similarly to the
>> --no-advice option in b79deeb554 (advice: add --no-advice global option,
>> 2024-05-03). This uses a GIT_HOOKS environment variable to communicate
>> to subprocesses as well as making this a backwards-compatible way for
>> tools to signal that they want to disable hooks.
>>
>> The critical piece is that all hooks pass through run_hooks_opt() where
>> a static int will evaluate the environment variable and store that the
>> variable is initialized for faster repeated runs.
>> This is hopefully a helpful feature to more than just the experts I've
>> been hearing from.
>
> I think this is functionality that Jenkins wants because they've
> configured `core.hooksPath` to `/dev/null`, allegedly for security
> reasons. Of course, enabling this feature will also break Git LFS, but
> in a less noticeable and detectable way (currently, Git LFS will fail on
> attempting to install hooks with that setting of `core.hooksPath`, which
> is at least noticeable).
I agree that some hooks are necessary for certain repositories to keep
their data consistent. Another example is the pre- and post-command hooks
that are in the microsoft/git fork that are necessary to avoid issues with
the virtualization layer of VFS for Git. If a user disables those hooks
during a command that changes the index, then they are going to have a bad
time. But maybe they want to disable hooks because all they need is a
'git rev-parse HEAD' or similarly read-only operation.
> I do think that in general certain types of hooks, such as pre-commit
> hooks, should absolutely be optional. There are lots of reasons to
> commit WIP data that doesn't meet whatever standard and we shouldn't
> impede expert users from expert workflows, even if there are many fewer
> reasons to do things like bypass pushing Git LFS objects (which are
> important for integrity).
My intention is definitely more on the side of these optional hooks.
> So I can see the utility of this feature but I can also see how it can
> break lots of things when handled poorly. Of course, we also have `git
> reset --hard` and there's lots of hand-wringing on Stack Overflow about
> having deleted important data, so we have some precedent for expert
> features that could break things badly.
>
> I don't otherwise have a strong opinion either way, although I'd lean
> slightly in favour of this series. I'd of course welcome other people's
> thoughts here.
Thank you for chiming in! I look forward to other thoughts and whetherthe warning in the docs should be strengthened.
Thanks,
-Stolee
|
On the Git mailing list, Phillip Wood wrote (reply to this): Hi Stolee
On 03/04/2025 23:38, Derrick Stolee via GitGitGadget wrote:
> From: Derrick Stolee <[email protected]>
> > In some situations, these hooks have poor performance and expert users
> may want to skip the hooks as they don't seem to affect the current
> situation. One example is a pre-commit hook that checks for certain
> structures in the local changes, but expert users are likely to have
> done the right thing in advance.
Next they'll be saying that they never make a mistake when writing a one line patch! More seriously I agree there are times when one may want to bypass the pre-commit hook but we already have "git commit --no-verify" to do that. In general hooks that are so slow that the user wants to bypass them are self-defeating and I'd argue that the solution is to fix the performance of the hook rather than make it easier to skip it. One solution for speeding up pre-commit hooks is to process files in parallel. Unfortunately git does not provide support for that but there are hook frameworks that do.
> I have come across users who have disabled hooks themselves either by
> deleting hooks (supported, safe) or setting 'core.hooksPath' to some
> bogus path (seems unsafe).
I thought "git -c core.hooksPath=/dev/null" was a fairly standard way of disabling hooks on a one-off basis - what makes it unsafe?
> The supported process is painful to swap
> between the hook-enabled scenario and the hook-disabled scenario.
> > To that end, add a new --no-hooks global option to allow users to
> disable hooks quickly. This option is modeled similarly to the
> --no-advice option in b79deeb554 (advice: add --no-advice global option,
> 2024-05-03). This uses a GIT_HOOKS environment variable to communicate
> to subprocesses as well as making this a backwards-compatible way for
> tools to signal that they want to disable hooks.
> > The critical piece is that all hooks pass through run_hooks_opt() where
> a static int will evaluate the environment variable and store that the
> variable is initialized for faster repeated runs.
That certainly makes the implementation much more viable. However I'm not really convinced this is a good idea.
Best Wishes
Phillip
> Signed-off-by: Derrick Stolee <[email protected]>
> ---
> git: add --no-hooks global option
> > This is hopefully a helpful feature to more than just the experts I've
> been hearing from.
> > Thanks,
> > * Stolee
> > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1899%2Fderrickstolee%2Fno-hooks-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1899/derrickstolee/no-hooks-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/1899
> > Documentation/git.adoc | 13 ++++++++++++-
> environment.h | 6 ++++++
> git.c | 6 +++++-
> hook.c | 7 +++++++
> t/t1350-config-hooks-path.sh | 34 ++++++++++++++++++++++++++++++++++
> 5 files changed, 64 insertions(+), 2 deletions(-)
> > diff --git a/Documentation/git.adoc b/Documentation/git.adoc
> index 743b7b00e4d..a34c8cfbe78 100644
> --- a/Documentation/git.adoc
> +++ b/Documentation/git.adoc
> @@ -14,7 +14,7 @@ SYNOPSIS
> [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-lazy-fetch]
> [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]
> [--work-tree=<path>] [--namespace=<name>] [--config-env=<name>=<envvar>]
> - <command> [<args>]
> + [--no-hooks] <command> [<args>]
> > DESCRIPTION
> -----------
> @@ -230,6 +230,12 @@ If you just want to run git as if it was started in `<path>` then use
> linkgit:gitattributes[5]. This is equivalent to setting the
> `GIT_ATTR_SOURCE` environment variable.
> > +--no-hooks::
> + Skip running local Git hooks, even if configured locally. Hooks
> + are an opt-in feature, so be sure that you know the impact of
> + ignoring hooks when running with this option. This is equivalent
> + to setting `GIT_HOOKS=0` environment variable.
> +
> GIT COMMANDS
> ------------
> > @@ -771,6 +777,11 @@ for further details.
> not set, Git will choose buffered or record-oriented flushing
> based on whether stdout appears to be redirected to a file or not.
> > +`GIT_HOOKS`::
> + If this Boolean environment variable is set to false, then commands
> + will ignore any configured hooks as if the `--no-hooks` option was
> + provided.
> +
> `GIT_TRACE`::
> Enables general trace messages, e.g. alias expansion, built-in
> command execution and external command execution.
> diff --git a/environment.h b/environment.h
> index 45e690f203f..22ddf201144 100644
> --- a/environment.h
> +++ b/environment.h
> @@ -50,6 +50,12 @@
> */
> #define GIT_ADVICE_ENVIRONMENT "GIT_ADVICE"
> > +/*
> + * Environment variable used to propagate the --no-hooks global option to
> + * the hooks layer and to any child processes.
> + */
> +#define GIT_HOOKS "GIT_HOOKS"
> +
> /*
> * Environment variable used in handshaking the wire protocol.
> * Contains a colon ':' separated list of keys with optional values
> diff --git a/git.c b/git.c
> index 77c43595223..d7ebcf60947 100644
> --- a/git.c
> +++ b/git.c
> @@ -41,7 +41,7 @@ const char git_usage_string[] =
> " [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-lazy-fetch]\n"
> " [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
> " [--work-tree=<path>] [--namespace=<name>] [--config-env=<name>=<envvar>]\n"
> - " <command> [<args>]");
> + " [--no-hooks] <command> [<args>]");
> > const char git_more_info_string[] =
> N_("'git help -a' and 'git help -g' list available subcommands and some\n"
> @@ -349,6 +349,10 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
> setenv(GIT_ADVICE_ENVIRONMENT, "0", 1);
> if (envchanged)
> *envchanged = 1;
> + } else if (!strcmp(cmd, "--no-hooks")) {
> + setenv(GIT_HOOKS, "0", 1);
> + if (envchanged)
> + *envchanged = 1;
> } else {
> fprintf(stderr, _("unknown option: %s\n"), cmd);
> usage(git_usage_string);
> diff --git a/hook.c b/hook.c
> index b3de1048bf4..b209553d7a8 100644
> --- a/hook.c
> +++ b/hook.c
> @@ -144,6 +144,13 @@ int run_hooks_opt(struct repository *r, const char *hook_name,
> > .data = &cb_data,
> };
> + static int do_run_hooks = -1;
> +
> + if (do_run_hooks < 0)
> + do_run_hooks = git_env_bool(GIT_HOOKS, 1);
> +
> + if (!do_run_hooks)
> + goto cleanup;
> > if (!options)
> BUG("a struct run_hooks_opt must be provided to run_hooks");
> diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh
> index 45a04929170..4c6a0eafe4e 100755
> --- a/t/t1350-config-hooks-path.sh
> +++ b/t/t1350-config-hooks-path.sh
> @@ -48,4 +48,38 @@ test_expect_success 'core.hooksPath=/dev/null' '
> { test /dev/null = "$value" || test nul = "$value"; }
> '
> > +test_expect_success '--no-hooks' '
> + rm -f actual &&
> + test_might_fail git config --unset core.hooksPath &&
> +
> + write_script .git/hooks/pre-commit <<-\EOF &&
> + echo HOOK >>actual
> + EOF
> +
> + echo HOOK >expect &&
> +
> + git commit --allow-empty -m "A" &&
> + test_cmp expect actual &&
> +
> + git --no-hooks commit --allow-empty -m "B" &&
> + test_cmp expect actual
> +'
> +
> +test_expect_success 'GIT_HOOKS' '
> + rm -f actual &&
> + test_might_fail git config --unset core.hooksPath &&
> +
> + write_script .git/hooks/pre-commit <<-\EOF &&
> + echo HOOK >>actual
> + EOF
> +
> + echo HOOK >expect &&
> +
> + GIT_HOOKS=1 git commit --allow-empty -m "A" &&
> + test_cmp expect actual &&
> +
> + GIT_HOOKS=0 git commit --allow-empty -m "B" &&
> + test_cmp expect actual
> +'
> +
> test_done
> > base-commit: 5b97a56fa0e7d580dc8865b73107407c9b3f0eff
|
User |
On the Git mailing list, "D. Ben Knoble" wrote (reply to this): On Thu, Apr 3, 2025 at 6:38 PM Derrick Stolee via GitGitGadget
<[email protected]> wrote:
>
> From: Derrick Stolee <[email protected]>
>
> Git has several hooks which are executed during certain events as long
> as those hooks are enabled in the hooks directory (possibly moved from
> .git/hooks via the core.hooksPath config option). These are configured
> by the user, or perhaps by tooling the user has agreed to, and are not
> required to operate a Git repository.
>
> In some situations, these hooks have poor performance and expert users
> may want to skip the hooks as they don't seem to affect the current
> situation. One example is a pre-commit hook that checks for certain
> structures in the local changes, but expert users are likely to have
> done the right thing in advance.
Or a pre-push hook that runs tests which, for some reason, are very
slow to execute but which isn't properly shutdown by a normal SIGINT,
messing up my shell.
> I have come across users who have disabled hooks themselves either by
> deleting hooks (supported, safe) or setting 'core.hooksPath' to some
> bogus path (seems unsafe). The supported process is painful to swap
> between the hook-enabled scenario and the hook-disabled scenario.
In my particular case, the tool being used (husky) sets core.hooksPath
to a directory in the repo, so I can go back to using my preferred
hooks simply by unsetting core.hooksPath, which seems safe. But
swapping is still a bit painful, as mentioned.
Worse, every "npm install" in this repo re-enables the hooks, so I
have to remember to reset core.hooksPath :/ When I don't, I spend a
few frustrating minutes getting back to normal. And then I
accidentally train myself to use --no-verify often with this project,
which is IMO a worse state of affairs.
Obviously, this repo's hooks need fixed, but in the interim something
like --no-hooks seems useful to me. Not sure if I count among the
experts or not /shrug.
> To that end, add a new --no-hooks global option to allow users to
> disable hooks quickly. This option is modeled similarly to the
> --no-advice option in b79deeb554 (advice: add --no-advice global option,
> 2024-05-03). This uses a GIT_HOOKS environment variable to communicate
> to subprocesses as well as making this a backwards-compatible way for
> tools to signal that they want to disable hooks.
On a related note: with client-side hooks always being considered
optional, it seems like there ought to be a safe, sane way to turn
them off (rather than remember --no-verify for the various commands,
which is probably the safe, sane way to bypass them on a one-off
basis).
Maybe with this I'll have more ammo to convince folks that their
sanity/security/whatever checks belong in server-side hooks and
optional developer scripts rather than pre-commit hooks.
>
> The critical piece is that all hooks pass through run_hooks_opt() where
> a static int will evaluate the environment variable and store that the
> variable is initialized for faster repeated runs.
>
> Signed-off-by: Derrick Stolee <[email protected]>
> ---
> git: add --no-hooks global option
>
> This is hopefully a helpful feature to more than just the experts I've
> been hearing from.
>
> Thanks,
>
> * Stolee
>
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1899%2Fderrickstolee%2Fno-hooks-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1899/derrickstolee/no-hooks-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/1899
>
> Documentation/git.adoc | 13 ++++++++++++-
> environment.h | 6 ++++++
> git.c | 6 +++++-
> hook.c | 7 +++++++
> t/t1350-config-hooks-path.sh | 34 ++++++++++++++++++++++++++++++++++
> 5 files changed, 64 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/git.adoc b/Documentation/git.adoc
> index 743b7b00e4d..a34c8cfbe78 100644
> --- a/Documentation/git.adoc
> +++ b/Documentation/git.adoc
> @@ -14,7 +14,7 @@ SYNOPSIS
> [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-lazy-fetch]
> [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]
> [--work-tree=<path>] [--namespace=<name>] [--config-env=<name>=<envvar>]
> - <command> [<args>]
> + [--no-hooks] <command> [<args>]
>
> DESCRIPTION
> -----------
> @@ -230,6 +230,12 @@ If you just want to run git as if it was started in `<path>` then use
> linkgit:gitattributes[5]. This is equivalent to setting the
> `GIT_ATTR_SOURCE` environment variable.
>
> +--no-hooks::
> + Skip running local Git hooks, even if configured locally. Hooks
> + are an opt-in feature, so be sure that you know the impact of
> + ignoring hooks when running with this option. This is equivalent
> + to setting `GIT_HOOKS=0` environment variable.
> +
> GIT COMMANDS
> ------------
>
> @@ -771,6 +777,11 @@ for further details.
> not set, Git will choose buffered or record-oriented flushing
> based on whether stdout appears to be redirected to a file or not.
>
> +`GIT_HOOKS`::
> + If this Boolean environment variable is set to false, then commands
> + will ignore any configured hooks as if the `--no-hooks` option was
> + provided.
> +
> `GIT_TRACE`::
> Enables general trace messages, e.g. alias expansion, built-in
> command execution and external command execution.
> diff --git a/environment.h b/environment.h
> index 45e690f203f..22ddf201144 100644
> --- a/environment.h
> +++ b/environment.h
> @@ -50,6 +50,12 @@
> */
> #define GIT_ADVICE_ENVIRONMENT "GIT_ADVICE"
>
> +/*
> + * Environment variable used to propagate the --no-hooks global option to
> + * the hooks layer and to any child processes.
> + */
> +#define GIT_HOOKS "GIT_HOOKS"
> +
> /*
> * Environment variable used in handshaking the wire protocol.
> * Contains a colon ':' separated list of keys with optional values
> diff --git a/git.c b/git.c
> index 77c43595223..d7ebcf60947 100644
> --- a/git.c
> +++ b/git.c
> @@ -41,7 +41,7 @@ const char git_usage_string[] =
> " [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-lazy-fetch]\n"
> " [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n"
> " [--work-tree=<path>] [--namespace=<name>] [--config-env=<name>=<envvar>]\n"
> - " <command> [<args>]");
> + " [--no-hooks] <command> [<args>]");
>
> const char git_more_info_string[] =
> N_("'git help -a' and 'git help -g' list available subcommands and some\n"
> @@ -349,6 +349,10 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
> setenv(GIT_ADVICE_ENVIRONMENT, "0", 1);
> if (envchanged)
> *envchanged = 1;
> + } else if (!strcmp(cmd, "--no-hooks")) {
> + setenv(GIT_HOOKS, "0", 1);
> + if (envchanged)
> + *envchanged = 1;
> } else {
> fprintf(stderr, _("unknown option: %s\n"), cmd);
> usage(git_usage_string);
> diff --git a/hook.c b/hook.c
> index b3de1048bf4..b209553d7a8 100644
> --- a/hook.c
> +++ b/hook.c
> @@ -144,6 +144,13 @@ int run_hooks_opt(struct repository *r, const char *hook_name,
>
> .data = &cb_data,
> };
> + static int do_run_hooks = -1;
> +
> + if (do_run_hooks < 0)
> + do_run_hooks = git_env_bool(GIT_HOOKS, 1);
> +
> + if (!do_run_hooks)
> + goto cleanup;
>
> if (!options)
> BUG("a struct run_hooks_opt must be provided to run_hooks");
> diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh
> index 45a04929170..4c6a0eafe4e 100755
> --- a/t/t1350-config-hooks-path.sh
> +++ b/t/t1350-config-hooks-path.sh
> @@ -48,4 +48,38 @@ test_expect_success 'core.hooksPath=/dev/null' '
> { test /dev/null = "$value" || test nul = "$value"; }
> '
>
> +test_expect_success '--no-hooks' '
> + rm -f actual &&
> + test_might_fail git config --unset core.hooksPath &&
> +
> + write_script .git/hooks/pre-commit <<-\EOF &&
> + echo HOOK >>actual
> + EOF
> +
> + echo HOOK >expect &&
> +
> + git commit --allow-empty -m "A" &&
> + test_cmp expect actual &&
> +
> + git --no-hooks commit --allow-empty -m "B" &&
> + test_cmp expect actual
> +'
> +
> +test_expect_success 'GIT_HOOKS' '
> + rm -f actual &&
> + test_might_fail git config --unset core.hooksPath &&
> +
> + write_script .git/hooks/pre-commit <<-\EOF &&
> + echo HOOK >>actual
> + EOF
> +
> + echo HOOK >expect &&
> +
> + GIT_HOOKS=1 git commit --allow-empty -m "A" &&
> + test_cmp expect actual &&
> +
> + GIT_HOOKS=0 git commit --allow-empty -m "B" &&
> + test_cmp expect actual
> +'
> +
> test_done
>
> base-commit: 5b97a56fa0e7d580dc8865b73107407c9b3f0eff
> --
> gitgitgadget
>
--
D. Ben Knoble |
User |
On the Git mailing list, Derrick Stolee wrote (reply to this): On 4/4/2025 10:15 AM, Phillip Wood wrote:
> Hi Stolee
>
> On 03/04/2025 23:38, Derrick Stolee via GitGitGadget wrote:
>> From: Derrick Stolee <[email protected]>
>>
>> In some situations, these hooks have poor performance and expert users
>> may want to skip the hooks as they don't seem to affect the current
>> situation. One example is a pre-commit hook that checks for certain
>> structures in the local changes, but expert users are likely to have
>> done the right thing in advance.
>
> Next they'll be saying that they never make a mistake when writing a
> one line patch! More seriously I agree there are times when one may
> want to bypass the pre-commit hook but we already have "git commit
> --no-verify" to do that. In general hooks that are so slow that the
> user wants to bypass them are self-defeating and I'd argue that the
> solution is to fix the performance of the hook rather than make it
> easier to skip it.
Both can also be an option.
> One solution for speeding up pre-commit hooks is
> to process files in parallel. Unfortunately git does not provide
> support for that but there are hook frameworks that do.
>> I have come across users who have disabled hooks themselves either by
>> deleting hooks (supported, safe) or setting 'core.hooksPath' to some
>> bogus path (seems unsafe).
>
> I thought "git -c core.hooksPath=/dev/null" was a fairly standard
> way of disabling hooks on a one-off basis - what makes it unsafe?
You're right. I was thinking about setting it to a "directory that
doesn't exist" (but actually could be a path that exists accidentally
like "/bogus") but I forgot that we could use /dev/null.
I'll remove this "(seems unsafe)" wording.
>> The supported process is painful to swap
>> between the hook-enabled scenario and the hook-disabled scenario.
>>
>> To that end, add a new --no-hooks global option to allow users to
>> disable hooks quickly. This option is modeled similarly to the
>> --no-advice option in b79deeb554 (advice: add --no-advice global option,
>> 2024-05-03). This uses a GIT_HOOKS environment variable to communicate
>> to subprocesses as well as making this a backwards-compatible way for
>> tools to signal that they want to disable hooks.
>>
>> The critical piece is that all hooks pass through run_hooks_opt() where
>> a static int will evaluate the environment variable and store that the
>> variable is initialized for faster repeated runs.
>
> That certainly makes the implementation much more viable. However I'm
> not really convinced this is a good idea.
I don't read a strong reason in your message that this is a _bad_
idea either. As in, there's nothing that hints that this will cause
significant harm to users other than providing a new footgun (and we
have plenty of those for folks willing to look, including the
_existence_ of hooks).
Thanks,
-Stolee
|
On the Git mailing list, Lucas Seiki Oshiro wrote (reply to this): Hi!
> I thought "git -c core.hooksPath=/dev/null" was a fairly standard way of disabling hooks
Given that, wouldn't it be a case to turn this into a documentation patch?
I just searched here I found that we even have a test for it (introduced
in c8f6478), but I couldn't find that as a recommendation in our docs. |
User |
On the Git mailing list, "brian m. carlson" wrote (reply to this): On 2025-04-14 at 15:25:42, Lucas Seiki Oshiro wrote:
> Hi!
>
> > I thought "git -c core.hooksPath=/dev/null" was a fairly standard way of disabling hooks
>
> Given that, wouldn't it be a case to turn this into a documentation patch?
>
> I just searched here I found that we even have a test for it (introduced
> in c8f6478), but I couldn't find that as a recommendation in our docs.
I think if we decide to keep this series, then we should probably keep
the documentation in this series, since it will be clearer and more
straightforward as a way to disable hooks, and if we don't, then a new
documentation patch would be a good idea.
--
brian m. carlson (they/them)
Toronto, Ontario, CA |
On the Git mailing list, Phillip Wood wrote (reply to this): Hi Stolee
On 14/04/2025 11:59, Derrick Stolee wrote:
> On 4/4/2025 10:15 AM, Phillip Wood wrote:
>> On 03/04/2025 23:38, Derrick Stolee via GitGitGadget wrote:
>>> From: Derrick Stolee <[email protected]>
>>>
>>> To that end, add a new --no-hooks global option to allow users to
>>> disable hooks quickly. This option is modeled similarly to the
>>> --no-advice option in b79deeb554 (advice: add --no-advice global option,
>>> 2024-05-03). This uses a GIT_HOOKS environment variable to communicate
>>> to subprocesses as well as making this a backwards-compatible way for
>>> tools to signal that they want to disable hooks.
>>>
>>> The critical piece is that all hooks pass through run_hooks_opt() where
>>> a static int will evaluate the environment variable and store that the
>>> variable is initialized for faster repeated runs.
>>
>> That certainly makes the implementation much more viable. However I'm
>> not really convinced this is a good idea.
> > I don't read a strong reason in your message that this is a _bad_
> idea either. As in, there's nothing that hints that this will cause
> significant harm to users other than providing a new footgun (and we
> have plenty of those for folks willing to look, including the
> _existence_ of hooks).
It is certainly not a terrible idea given that it is possible to disable hooks already but I'm not clear what the motivation is. I don't find the example of a skipping a pre-commit hook persuasive as we already provide a convenient way for users to skip that hook. Elsewhere in this thread you mention the "pre-command" and "post-command" hooks but they are not part of git - if a fork is running its own hooks and that is causing problems for users I'm not sure we want to change the upstream project to address that. If there was a clearer motivation it would be easier to understand the benefits of this change.
Best Wishes
Phillip
|
On the Git mailing list, Junio C Hamano wrote (reply to this): Phillip Wood <[email protected]> writes:
>> I don't read a strong reason in your message that this is a _bad_
>> idea either. As in, there's nothing that hints that this will cause
>> significant harm to users other than providing a new footgun (and we
>> have plenty of those for folks willing to look, including the
>> _existence_ of hooks).
>
> It is certainly not a terrible idea given that it is possible to
> disable hooks already but I'm not clear what the motivation is. I
> don't find the example of a skipping a pre-commit hook persuasive as
> we already provide a convenient way for users to skip that
> hook. Elsewhere in this thread you mention the "pre-command" and
> "post-command" hooks but they are not part of git - if a fork is
> running its own hooks and that is causing problems for users I'm not
> sure we want to change the upstream project to address that. If there
> was a clearer motivation it would be easier to understand the benefits
> of this change.
Thanks for pushing back. The default for any new changes is not to
apply unless there is a compelling reason why it is a good idea,
saying that this is not a bad thing does not serve as an effective
justification.
If we want to give scripters a more stable foundation to build on,
the answer should not be to pile more and more "no hooks, no
configurations, just a vanilla mode of operation" options to
end-user facing porcelain commands, but to clean up the internal
implementation of such porcelain commands to refactor into stable
plumbing commands that scripters can rely on. |
If a user wishes to disable hooks, then they can do so using the established pattern of setting 'core.hooksPath' to /dev/null. This is already tested in t1350-config-hooks-path.sh, but has not previously been visible in the documentation. Update the documentation to include this as an option. Signed-off-by: Derrick Stolee <[email protected]>
On the Git mailing list, Derrick Stolee wrote (reply to this): On 4/16/2025 10:28 AM, Junio C Hamano wrote:
> Phillip Wood <[email protected]> writes:
>
>>> I don't read a strong reason in your message that this is a _bad_
>>> idea either. As in, there's nothing that hints that this will cause
>>> significant harm to users other than providing a new footgun (and we
>>> have plenty of those for folks willing to look, including the
>>> _existence_ of hooks).
>>
>> It is certainly not a terrible idea given that it is possible to
>> disable hooks already but I'm not clear what the motivation is. I
>> don't find the example of a skipping a pre-commit hook persuasive as
>> we already provide a convenient way for users to skip that
>> hook. Elsewhere in this thread you mention the "pre-command" and
>> "post-command" hooks but they are not part of git - if a fork is
>> running its own hooks and that is causing problems for users I'm not
>> sure we want to change the upstream project to address that. If there
>> was a clearer motivation it would be easier to understand the benefits
>> of this change.
>
> Thanks for pushing back. The default for any new changes is not to
> apply unless there is a compelling reason why it is a good idea,
> saying that this is not a bad thing does not serve as an effective
> justification.
>
> If we want to give scripters a more stable foundation to build on,
> the answer should not be to pile more and more "no hooks, no
> configurations, just a vanilla mode of operation" options to
> end-user facing porcelain commands, but to clean up the internal
> implementation of such porcelain commands to refactor into stable
> plumbing commands that scripters can rely on.
Thank you for a decisive answer. I'll move forward with a v2 that
is a doc-only change, documenting the /dev/null value as a supported
mechanism for disabling hooks.
Thanks,
-Stolee
|
/submit |
Submitted as [email protected] To fetch this version into
To fetch this version to local tag
|
On the Git mailing list, Lucas Seiki Oshiro wrote (reply to this): Hi!
> +You can also disable all hooks entirely by setting `core.hooksPath`
> +to `/dev/null`.
Personally I think it would be better to focus on the non-expert user,
something like:
"""
You can also use this variable to disable all hooks entirely by setting
it to `/dev/null`. For non-expert users in a per-command basis it is
advisable to use configuration parameters of the form
`git -c core.hooksPath=/dev/null ...`.
"""
|
This patch series was integrated into seen via git@f3ac7e3. |
This patch series was integrated into seen via git@6d2cd77. |
On the Git mailing list, Derrick Stolee wrote (reply to this): On 4/16/2025 12:53 PM, Lucas Seiki Oshiro wrote:
> Hi!
>
>> +You can also disable all hooks entirely by setting `core.hooksPath`
>> +to `/dev/null`.
>
> Personally I think it would be better to focus on the non-expert user,
I absolutely want this to be targeted for expert users, so users self-
select themselves into the risk of what happens when disabling hooks.
This is a "there be dragons here" kind of warning, implying that you
better know what you're doing if you are messing with hook paths.
Thanks,
-Stolee
|
On the Git mailing list, "brian m. carlson" wrote (reply to this): On 2025-04-17 at 00:25:28, Derrick Stolee wrote:
> On 4/16/2025 12:53 PM, Lucas Seiki Oshiro wrote:
> > Hi!
> >
> >> +You can also disable all hooks entirely by setting `core.hooksPath`
> >> +to `/dev/null`.
> >
> > Personally I think it would be better to focus on the non-expert user,
>
> I absolutely want this to be targeted for expert users, so users self-
> select themselves into the risk of what happens when disabling hooks.
> This is a "there be dragons here" kind of warning, implying that you
> better know what you're doing if you are messing with hook paths.
Yes, I think that's the right choice. As we've established elsewhere,
it's easy to break things or cause data loss (e.g., by not pushing Git
LFS objects) by disabling hooks and the user should be confident of what
they're doing before doing so.
That being said, I agree that in the general case we should make our
documentation accessible to non-expert users because nobody is born
knowing how to use Git and that will benefit the most people. This just
happens to be an exception.
I thought the text in the patch looked good to me. I appreciate you
graciously pivoting approaches and documenting this, both for the
benefit of users and as an approach to help make sure we don't break
this functionality.
--
brian m. carlson (they/them)
Toronto, Ontario, CA |
On the Git mailing list, Junio C Hamano wrote (reply to this): "brian m. carlson" <[email protected]> writes:
> I thought the text in the patch looked good to me. I appreciate you
> graciously pivoting approaches and documenting this, both for the
> benefit of users and as an approach to help make sure we don't break
> this functionality.
Thanks, all. I too appreciate that Derrick left no loose ends
untied after changing direction.
|
On the Git mailing list, Lucas Seiki Oshiro wrote (reply to this): > This is a "there be dragons here" kind of warning, implying that you
> better know what you're doing if you are messing with hook paths.
Fair, I understand your point. The paragraph itself looks very
clear to me!
Thanks!
|
This branch is now known as |
This patch series was integrated into seen via git@b513a53. |
This patch series was integrated into seen via git@96117c3. |
This patch series was integrated into seen via git@9f63e57. |
This patch series was integrated into next via git@4b543e5. |
This patch series was integrated into seen via git@1a6b041. |
There was a status update in the "New Topics" section about the branch Document the convention to disable hooks altogether by setting the hooksPath configuration variable to /dev/nulll Will merge to 'master'. source: <[email protected]> |
This patch series was integrated into seen via git@18b90d7. |
This patch series was integrated into seen via git@662354f. |
There was a status update in the "Cooking" section about the branch Document the convention to disable hooks altogether by setting the hooksPath configuration variable to /dev/nulll Will merge to 'master'. source: <[email protected]> |
This patch series was integrated into seen via git@d6ae522. |
This patch series was integrated into seen via git@68e5342. |
This patch series was integrated into master via git@68e5342. |
This patch series was integrated into next via git@68e5342. |
Closed via 68e5342. |
Based on the discussion of the proposed --no-hooks option in v1, that code change is dropped in favor of this documentation of
core.hooksPath=/dev/null
.Thanks,
cc: [email protected]
cc: [email protected]
cc: "brian m. carlson" [email protected]
cc: Phillip Wood [email protected]
cc: "D. Ben Knoble" [email protected]
cc: Lucas Seiki Oshiro [email protected]