<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/hook.c, 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:55Z</updated>
<entry>
<title>hook: allow hook.jobs=-1 to use all available CPU cores</title>
<updated>2026-04-10T14:58:55Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-04-10T09:06:07Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=495b7d54dc006556548e2fd3ca15c4f533917329'/>
<id>urn:sha1:495b7d54dc006556548e2fd3ca15c4f533917329</id>
<content type='text'>
Allow -1 as a value for hook.jobs, hook.&lt;event&gt;.jobs, and the -j
CLI flag to mean "use as many jobs as there are CPU cores", matching
the convention used by fetch.parallel and other Git subsystems.

The value is resolved to online_cpus() at parse time so the rest
of the code always works with a positive resolved count.

Other non-positive values (0, -2, etc) are rejected with a warning
(config) or die (CLI).

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: 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: warn when hook.&lt;friendly-name&gt;.jobs is set</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:04Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=5e57b209ff21bf1087dd8539c458737c89b03150'/>
<id>urn:sha1:5e57b209ff21bf1087dd8539c458737c89b03150</id>
<content type='text'>
Issue a warning when the user confuses the hook process and event
namespaces by setting hook.&lt;friendly-name&gt;.jobs.

Detect this by checking whether the name carrying .jobs also has
.command, .event, or .parallel configured.  Extract is_friendly_name()
as a helper for this check, to be reused by future per-event config
handling.

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: add per-event jobs config</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:03Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=084a55b3adf33f70c84091d5957b8bede9b01174'/>
<id>urn:sha1:084a55b3adf33f70c84091d5957b8bede9b01174</id>
<content type='text'>
Add a hook.&lt;event&gt;.jobs count config that allows users to override the
global hook.jobs setting for specific hook events.

This allows finer-grained control over parallelism on a per-event basis.

For example, to run `post-receive` hooks with up to 4 parallel jobs
while keeping other events at their global default:

[hook]
    post-receive.jobs = 4

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: add -j/--jobs option to git hook run</title>
<updated>2026-04-10T14:58:54Z</updated>
<author>
<name>Emily Shaffer</name>
<email>emilyshaffer@google.com</email>
</author>
<published>2026-04-10T09:06:02Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=091d2dbeb452b2c8223c622b54e96ebd273b5a78'/>
<id>urn:sha1:091d2dbeb452b2c8223c622b54e96ebd273b5a78</id>
<content type='text'>
Expose the parallel job count as a command-line flag so callers can
request parallelism without relying only on the hook.jobs config.

Add tests covering serial/parallel execution and TTY behaviour under
-j1 vs -jN.

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: 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: parse the hook.jobs config</title>
<updated>2026-04-10T14:58:53Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-04-10T09:05:58Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=b9a4c9ad247a09602e0e6d0eccec6a43857f62da'/>
<id>urn:sha1:b9a4c9ad247a09602e0e6d0eccec6a43857f62da</id>
<content type='text'>
The hook.jobs config is a global way to set hook parallelization for
all hooks, in the sense that it is not per-event nor per-hook.

Finer-grained configs will be added in later commits which can override
it, for e.g. via a per-event type job options. Next commits will also
add to this item's documentation.

Parse hook.jobs config key in hook_config_lookup_all() and store its
value in hook_all_config_cb.jobs, then transfer it into r-&gt;jobs after
the config pass completes.

This is mostly plumbing and the cached value is not yet used.

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>
</feed>
