<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/hook.h, branch jch</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/git/git.git/
</subtitle>
<id>https://git.shady.money/git/atom?h=jch</id>
<link rel='self' href='https://git.shady.money/git/atom?h=jch'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/'/>
<updated>2026-04-10T14:58:54Z</updated>
<entry>
<title>hook: add hook.&lt;event&gt;.enabled switch</title>
<updated>2026-04-10T14:58:54Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-04-10T09:06:06Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=dcfb5af67e7d7156c4d1ede66de18088c990356c'/>
<id>urn:sha1:dcfb5af67e7d7156c4d1ede66de18088c990356c</id>
<content type='text'>
Add a hook.&lt;event&gt;.enabled config key that disables all hooks for
a given event, when set to false, acting as a high-level switch
above the existing per-hook hook.&lt;friendly-name&gt;.enabled.

Event-disabled hooks are shown in "git hook list" with an
"event-disabled" tab-separated prefix before the name:

$ git hook list test-hook
event-disabled  hook-1
event-disabled  hook-2

With --show-scope:

$ git hook list --show-scope test-hook
local   event-disabled  hook-1

When a hook is both per-hook disabled and event-disabled, only
"event-disabled" is shown: the event-level switch is the more
relevant piece of information, and the per-hook "disabled" status
will surface once the event is re-enabled.

Using an event name as a friendly-name (e.g. hook.&lt;event&gt;.enabled)
can cause ambiguity, so a fatal error is issued when using a known
event name and a warning is issued for unknown event name, since
a collision cannot be detected with certainty for unknown events.

Suggested-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Suggested-by: Junio C Hamano &lt;gitster@pobox.com&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: move is_known_hook() to hook.c for wider use</title>
<updated>2026-04-10T14:58:54Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-04-10T09:06:05Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=2eb541e8f2a9b0dd923279421c741d0a0c00420d'/>
<id>urn:sha1:2eb541e8f2a9b0dd923279421c741d0a0c00420d</id>
<content type='text'>
Move is_known_hook() from builtin/hook.c (static) into hook.c and
export it via hook.h so it can be reused.

Make it return bool and the iterator `h` for clarity (iterate hooks).

Both meson.build and the Makefile are updated to reflect that the
header is now used by libgit, not the builtin sources.

The next commit will use this to reject hook friendly-names that
collide with known event names.

Co-authored-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: allow pre-push parallel execution</title>
<updated>2026-04-10T14:58:53Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-04-10T09:06:00Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=f776b77f0032fb342d567156626ef3fe9586443f'/>
<id>urn:sha1:f776b77f0032fb342d567156626ef3fe9586443f</id>
<content type='text'>
pre-push is the only hook that keeps stdout and stderr separate (for
backwards compatibility with git-lfs and potentially other users). This
prevents parallelizing it because run-command needs stdout_to_stderr=1
to buffer and de-interleave parallel outputs.

Since we now default to jobs=1, backwards compatibility is maintained
without needing any extension or extra config: when no parallelism is
requested, pre-push behaves exactly as before.

When the user explicitly opts into parallelism via hook.jobs &gt; 1,
hook.&lt;event&gt;.jobs &gt; 1, or -jN, they accept the changed output behavior.

Document this and let get_hook_jobs() set stdout_to_stderr=1 automatically
when jobs &gt; 1, removing the need for any extension infrastructure.

Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: allow parallel hook execution</title>
<updated>2026-04-10T14:58:53Z</updated>
<author>
<name>Emily Shaffer</name>
<email>nasamuffin@google.com</email>
</author>
<published>2026-04-10T09:05:59Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=680e69f60d2b3838bb98938dbd3e8881bdfde7d6'/>
<id>urn:sha1:680e69f60d2b3838bb98938dbd3e8881bdfde7d6</id>
<content type='text'>
Hooks always run in sequential order due to the hardcoded jobs == 1
passed to run_process_parallel(). Remove that hardcoding to allow
users to run hooks in parallel (opt-in).

Users need to decide which hooks to run in parallel, by specifying
"parallel = true" in the config, because Git cannot know if their
specific hooks are safe to run or not in parallel (for e.g. two hooks
might write to the same file or call the same program).

Some hooks are unsafe to run in parallel by design: these will marked
in the next commit using RUN_HOOKS_OPT_INIT_FORCE_SERIAL.

The hook.jobs config specifies the default number of jobs applied to all
hooks which have parallelism enabled.

Signed-off-by: Emily Shaffer &lt;emilyshaffer@google.com&gt;
Helped-by: Ævar Arnfjörð Bjarmason &lt;avarab@gmail.com&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: show disabled hooks in "git hook list"</title>
<updated>2026-03-25T21:00:47Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-03-25T19:55:02Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=e17bd99281ae01a758d717bdfaa759bbeefb6149'/>
<id>urn:sha1:e17bd99281ae01a758d717bdfaa759bbeefb6149</id>
<content type='text'>
Disabled hooks were filtered out of the cache entirely, making them
invisible to "git hook list". Keep them in the cache with a new
"disabled" flag which is propagated to the respective struct hook.

"git hook list" now shows disabled hooks as tab-separated columns,
with the status as a prefix before the name (like scope with
--show-scope). With --show-scope it looks like:

$ git hook list --show-scope pre-commit
global	linter
local	disabled	no-leaks
hook from hookdir

A disabled hook without a command issues a warning instead of the
fatal "hook.X.command must be configured" error. We could also throw
an error, however it seemd a bit excessive to me in this case.

Suggested-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: show config scope in git hook list</title>
<updated>2026-03-25T21:00:47Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-03-25T19:55:01Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=b66efad2b1f53755a80699dc39f94e2b15d6af67'/>
<id>urn:sha1:b66efad2b1f53755a80699dc39f94e2b15d6af67</id>
<content type='text'>
Users running "git hook list" can see which hooks are configured but
have no way to tell at which config scope (local, global, system...)
each hook was defined.

Store the scope from ctx-&gt;kvi-&gt;scope in the single-pass config callback,
then carry it through the cache to the hook structs, so we can expose it
to users via the "git hook list --show-scope" flag, which mirrors the
existing git config --show-scope convention.

Without the flag the output is unchanged.

The scope is printed as a tab-separated prefix (like "git config --show-scope"),
making it unambiguously machine-parseable even when the friendly name
contains spaces.

Example usage:
$ git hook list --show-scope pre-commit
global	linter
local	no-leaks
hook from hookdir

Traditional hooks from the hookdir are unaffected by --show-scope since
the config scope concept does not apply to them.

Suggested-by: Junio C Hamano &lt;gitster@pobox.com&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: make consistent use of friendly-name in docs</title>
<updated>2026-03-25T21:00:46Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-03-25T19:54:58Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=2e5dbaff169dfb28fa8e8c4f992d8252a4ef1312'/>
<id>urn:sha1:2e5dbaff169dfb28fa8e8c4f992d8252a4ef1312</id>
<content type='text'>
Both `name` and `friendly-name` is being used. Standardize on
`friendly-name` for consistency since name is rather generic,
even when used in the hooks namespace.

Suggested-by: Junio C Hamano &lt;gitster@pobox.com&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: replace hook_list_clear() -&gt; string_list_clear_func()</title>
<updated>2026-03-25T21:00:46Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-03-25T19:54:57Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=a8b1ba86d494ea8825292c91c243e5d84fd7ee2c'/>
<id>urn:sha1:a8b1ba86d494ea8825292c91c243e5d84fd7ee2c</id>
<content type='text'>
Replace the custom function with string_list_clear_func() which
is a more common pattern for clearing a string_list.

To be able to do this, rework hook_clear() into hook_free(), so
it can be passed to string_list_clear_func().

A slight complication is the need to keep a copy of the internal
cb data free() pointer, however I think it's worth it since the
API becomes cleaner, e.g. no more calls with NULL function args
like hook_list_clear(hooks, NULL).

In other words, the callers don't need to keep track of hook
internal state to determine when cleanup is necessary or not
(pass NULL) because each `struct hook` now owns its data_free
callback.

Suggested-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: rename cb_data_free/alloc -&gt; hook_data_free/alloc</title>
<updated>2026-03-25T21:00:46Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-03-25T19:54:55Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=8f7db6f8b585a3eef4ba595efd2d098f9abf3606'/>
<id>urn:sha1:8f7db6f8b585a3eef4ba595efd2d098f9abf3606</id>
<content type='text'>
Rename the hook callback function types to use the hook prefix.

This is a style fix with no logic changes.

Suggested-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hook: fix minor style issues</title>
<updated>2026-03-25T21:00:45Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-03-25T19:54:54Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=b06770e5d8948c7cad76d7507423376eacf1e005'/>
<id>urn:sha1:b06770e5d8948c7cad76d7507423376eacf1e005</id>
<content type='text'>
Fix some minor style nits pointed out by Patrick, Junio and Eric:
  * Use CALLOC_ARRAY instead of xcalloc.
  * Init struct members during declaration.
  * Simplify if condition boolean logic.
  * Missing curly braces in if/else stmts.
  * Unnecessary header includes.
  * Capitalization and full-stop in error/warn messages.
  * Curly brace on separate line when defining struct.
  * Comment spelling: free'd -&gt; freed.
  * Sort the included headers.
  * Blank line fixes to improve readability.

These contain no logic changes, the code behaves the same as before.

Suggested-by: Eric Sunshine &lt;sunshine@sunshineco.com&gt;
Suggested-by: Junio C Hamano &lt;gitster@pobox.com&gt;
Suggested-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Adrian Ratiu &lt;adrian.ratiu@collabora.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
</feed>
