From: Adrian Ratiu <adrian.ratiu@collabora.com>
To: Emily Shaffer <nasamuffin@google.com>
Cc: git@vger.kernel.org, "Jeff King" <peff@peff.net>,
"Junio C Hamano" <gitster@pobox.com>,
"Patrick Steinhardt" <ps@pks.im>,
"Josh Steadmon" <steadmon@google.com>,
"Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: Re: [PATCH v7 11/12] receive-pack: convert update hooks to new API
Date: Tue, 27 Jan 2026 15:05:49 +0200 [thread overview]
Message-ID: <87bjifmcia.fsf@collabora.com> (raw)
In-Reply-To: <CAJoAoZkBRr+CF9VHMaq15eS6o8Vgux1q88an5L6-eDLrP2AgAA@mail.gmail.com>
On Mon, 26 Jan 2026, Emily Shaffer <nasamuffin@google.com> wrote:
> On Wed, Jan 21, 2026 at 1:55 PM Adrian Ratiu <adrian.ratiu@collabora.com> wrote:
<snip>
>> static void run_update_post_hook(struct command *commands)
>> {
>> + struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
>> + struct async muxer;
>> struct command *cmd;
>> - struct child_process proc = CHILD_PROCESS_INIT;
>> - const char *hook;
>> -
>> - hook = find_hook(the_repository, "post-update");
>> - if (!hook)
>> - return;
>> + int saved_stderr = -1;
>> + int muxer_started = 0;
>>
>> for (cmd = commands; cmd; cmd = cmd->next) {
>> if (cmd->error_string || cmd->did_not_exist)
>> continue;
>> - if (!proc.args.nr)
>> - strvec_push(&proc.args, hook);
>> - strvec_push(&proc.args, cmd->ref_name);
>> + strvec_push(&opt.args, cmd->ref_name);
>> }
>> - if (!proc.args.nr)
>> + if (!opt.args.nr)
>> return;
>>
>> - proc.no_stdin = 1;
>> - proc.stdout_to_stderr = 1;
>> - proc.err = use_sideband ? -1 : 0;
>> - proc.trace2_hook_name = "post-update";
>> + if (use_sideband) {
>> + memset(&muxer, 0, sizeof(muxer));
>> + muxer.proc = copy_to_sideband;
>> + muxer.in = -1;
>> + if (!start_async(&muxer)) {
>> + muxer_started = 1;
>> + saved_stderr = dup(STDERR_FILENO);
>> + if (saved_stderr >= 0)
>> + dup2(muxer.in, STDERR_FILENO);
>> + close(muxer.in);
>> + }
>> + }
>>
>> - if (!start_command(&proc)) {
>> - if (use_sideband)
>> - copy_to_sideband(proc.err, -1, NULL);
>> - finish_command(&proc);
>> + run_hooks_opt(the_repository, "post-update", &opt);
>> +
>> + if (saved_stderr >= 0) {
>> + dup2(saved_stderr, STDERR_FILENO);
>> + close(saved_stderr);
>> }
>> + if (muxer_started)
>> + finish_async(&muxer);
>
> I guess I'm confused about how the muxer is working here. I guess I
> would expect an async to get created for each child, then to dump the
> entire output of the child when that child terminates, but it seems
> like you're setting up the async to capture the output of all the
> hooks (that is, it seems like start_async() and finish_async()
> encapsulate run_hooks_opt(), which runs multiple children...?)
Thanks for raising this Emily, your confusion is perfectly justified.
Before sending this patch I actually thought that the word "muxer" can
cause confusion and likely it's the wrong word to describe this thread,
because it doesn't actually mux anything. :)
I kept the "mux" terminology only because it was already used by the
other hooks (eg see the next commit) at this abstraction level.
The role of this thread is just to asynchronously capture the output of
run_hooks_opt's children via stderr without blocking the main process
and to send the output ASAP over the sideband channel to achieve as
close to real-time output performance as possible (this was one of
Peff's complaints about our original API).
The per-process output buffering/de-interlacing or "muxing" happens at a
lower level, in run-command, which gets called via run_hooks_opt, and is
not concerned with higher-level "hook" concepts such as whether
post-update needs to output or not over a sideband, it just prints the
final clean output from all children to stderr.
Hope this all makes sense and clarifies why we only need 1 "muxer"
thread per hook type + sideband combination. I did try to capture the
new design in an ASCII art drawing two commits before this one. :)
For more clarity, in v8 I will also rename "muxer" to something like
"sideband_output_redirect_thread". Suggestions welcome.
Please do let me know if you have any questions or uncertainties, happy
to help clarify things (or identify / fix bugs).
P.S.
I've also experimented with factoring out this sideband_output_redirect
("muxer") thread into a common helper which can be reused by all the
hooks requriing sideband output, to avoid the code duplication, however
I gave up on that because this series was already 12 patches long,
though I do think it's a good follow-up.
P.P.S.
When running sequentially (jobs=1 and ungroup=1), run-command does not
buffer/capture the hook output and the single hook child inherits
stdout/stderr to which it outputs directly. If use_sideband is also 0,
then we achieve the best possible real-time output, like in the current
local client hook sequential execution (another Peff requirement).
next prev parent reply other threads:[~2026-01-27 13:06 UTC|newest]
Thread overview: 187+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-25 12:53 [PATCH 00/10] Convert remaining hooks to hook.h Adrian Ratiu
2025-09-25 12:53 ` [PATCH 01/10] run-command: add stdin callback for parallelization Adrian Ratiu
2025-10-02 6:34 ` Patrick Steinhardt
2025-10-02 15:46 ` Junio C Hamano
2025-10-06 13:01 ` Adrian Ratiu
2025-10-06 12:59 ` Adrian Ratiu
2025-10-14 17:35 ` Adrian Ratiu
2025-09-25 12:53 ` [PATCH 02/10] hook: provide stdin via callback Adrian Ratiu
2025-09-25 20:05 ` Junio C Hamano
2025-09-26 12:03 ` Adrian Ratiu
2025-10-10 19:57 ` Emily Shaffer
2025-10-13 14:47 ` Adrian Ratiu
2025-09-25 12:53 ` [PATCH 03/10] hook: convert 'post-rewrite' hook in sequencer.c to hook.h Adrian Ratiu
2025-09-25 20:15 ` Junio C Hamano
2025-09-26 12:29 ` Adrian Ratiu
2025-09-26 14:12 ` Phillip Wood
2025-09-26 15:53 ` Adrian Ratiu
2025-09-29 10:11 ` Phillip Wood
2025-09-26 17:52 ` Junio C Hamano
2025-09-29 7:33 ` Adrian Ratiu
2025-10-02 6:34 ` Patrick Steinhardt
2025-10-08 7:04 ` Adrian Ratiu
2025-09-25 12:53 ` [PATCH 04/10] transport: convert pre-push hook " Adrian Ratiu
2025-09-25 18:58 ` D. Ben Knoble
2025-09-26 13:02 ` Adrian Ratiu
2025-09-26 14:11 ` Phillip Wood
2025-09-29 11:33 ` Adrian Ratiu
2025-09-25 12:53 ` [PATCH 05/10] reference-transaction: use hook.h to run hooks Adrian Ratiu
2025-09-25 21:45 ` Junio C Hamano
2025-09-26 13:03 ` Adrian Ratiu
2025-10-02 6:34 ` Patrick Steinhardt
2025-10-08 12:26 ` Adrian Ratiu
2025-09-25 12:53 ` [PATCH 06/10] run-command: allow capturing of collated output Adrian Ratiu
2025-09-25 21:52 ` Junio C Hamano
2025-09-26 14:14 ` Adrian Ratiu
2025-09-25 12:53 ` [PATCH 07/10] hooks: allow callers to capture output Adrian Ratiu
2025-09-25 12:53 ` [PATCH 08/10] receive-pack: convert 'update' hook to hook.h Adrian Ratiu
2025-09-25 21:53 ` Junio C Hamano
2025-10-10 19:57 ` Emily Shaffer
2025-10-17 8:27 ` Adrian Ratiu
2025-09-25 12:53 ` [PATCH 09/10] post-update: use hook.h library Adrian Ratiu
2025-09-25 18:02 ` [PATCH 10/10] receive-pack: convert receive hooks to hook.h Adrian Ratiu
2025-10-10 19:57 ` [PATCH 00/10] Convert remaining " Emily Shaffer
2025-10-17 14:15 ` [PATCH v2 " Adrian Ratiu
2025-10-17 14:15 ` [PATCH v2 01/10] run-command: add stdin callback for parallelization Adrian Ratiu
2025-10-21 7:40 ` Patrick Steinhardt
2025-10-17 14:15 ` [PATCH v2 02/10] hook: provide stdin via callback Adrian Ratiu
2025-10-21 7:41 ` Patrick Steinhardt
2025-10-21 7:41 ` Patrick Steinhardt
2025-10-21 14:44 ` Adrian Ratiu
2025-10-17 14:15 ` [PATCH v2 03/10] hook: convert 'post-rewrite' hook in sequencer.c to hook API Adrian Ratiu
2025-10-21 7:41 ` Patrick Steinhardt
2025-10-21 15:44 ` Adrian Ratiu
2025-10-17 14:15 ` [PATCH v2 04/10] transport: convert pre-push " Adrian Ratiu
2025-10-21 7:41 ` Patrick Steinhardt
2025-10-21 16:04 ` Adrian Ratiu
2025-10-17 14:15 ` [PATCH v2 05/10] reference-transaction: use hook API instead of run-command Adrian Ratiu
2025-10-17 14:15 ` [PATCH v2 06/10] hook: allow overriding the ungroup option Adrian Ratiu
2025-10-17 14:15 ` [PATCH v2 07/10] run-command: allow capturing of collated output Adrian Ratiu
2025-10-21 7:41 ` Patrick Steinhardt
2025-10-21 16:25 ` Adrian Ratiu
2025-10-17 14:15 ` [PATCH v2 08/10] hooks: allow callers to capture output Adrian Ratiu
2025-10-17 14:15 ` [PATCH v2 09/10] receive-pack: convert update hooks to new API Adrian Ratiu
2025-10-28 18:39 ` Kristoffer Haugsbakk
2025-10-17 14:15 ` [PATCH v2 10/10] receive-pack: convert receive hooks to hook API Adrian Ratiu
2025-10-21 7:41 ` Patrick Steinhardt
2025-10-28 18:42 ` Kristoffer Haugsbakk
2025-10-29 13:46 ` Adrian Ratiu
2025-10-29 13:50 ` Kristoffer Haugsbakk
2025-11-15 19:48 ` Junio C Hamano
2025-11-17 16:51 ` Adrian Ratiu
2025-10-21 7:40 ` [PATCH v2 00/10] Convert remaining hooks to hook.h Patrick Steinhardt
2025-10-21 16:34 ` Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 " Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 01/10] run-command: add stdin callback for parallelization Adrian Ratiu
2025-11-25 23:15 ` Junio C Hamano
2025-11-27 12:00 ` Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 02/10] hook: provide stdin via callback Adrian Ratiu
2025-11-29 13:03 ` Adrian Ratiu
2025-11-29 22:21 ` Junio C Hamano
2025-12-01 13:26 ` Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 03/10] hook: convert 'post-rewrite' hook in sequencer.c to hook API Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 04/10] transport: convert pre-push " Adrian Ratiu
2025-11-24 22:55 ` Junio C Hamano
2025-11-27 14:24 ` Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 05/10] reference-transaction: use hook API instead of run-command Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 06/10] hook: allow overriding the ungroup option Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 07/10] run-command: allow capturing of collated output Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 08/10] hooks: allow callers to capture output Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 09/10] receive-pack: convert update hooks to new API Adrian Ratiu
2025-11-24 17:20 ` [PATCH v3 10/10] receive-pack: convert receive hooks to hook API Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 00/11] Convert remaining hooks to hook.h Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 01/11] run-command: add first helper for pp child states Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 02/11] run-command: add stdin callback for parallelization Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 03/11] hook: provide stdin via callback Adrian Ratiu
2025-12-16 8:08 ` Patrick Steinhardt
2025-12-04 14:15 ` [PATCH v4 04/11] hook: convert 'post-rewrite' hook in sequencer.c to hook API Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 05/11] transport: convert pre-push " Adrian Ratiu
2025-12-16 8:08 ` Patrick Steinhardt
2025-12-16 9:09 ` Adrian Ratiu
2025-12-16 9:30 ` Patrick Steinhardt
2025-12-17 23:07 ` Junio C Hamano
2025-12-04 14:15 ` [PATCH v4 06/11] reference-transaction: use hook API instead of run-command Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 07/11] hook: allow overriding the ungroup option Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 08/11] run-command: allow capturing of collated output Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 09/11] hooks: allow callers to capture output Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 10/11] receive-pack: convert update hooks to new API Adrian Ratiu
2025-12-16 8:08 ` Patrick Steinhardt
2025-12-16 9:22 ` Adrian Ratiu
2025-12-04 14:15 ` [PATCH v4 11/11] receive-pack: convert receive hooks to hook API Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 00/11] Convert remaining hooks to hook.h Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 01/11] run-command: add first helper for pp child states Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 02/11] run-command: add stdin callback for parallelization Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 03/11] hook: provide stdin via callback Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 04/11] hook: convert 'post-rewrite' hook in sequencer.c to hook API Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 05/11] transport: convert pre-push " Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 06/11] reference-transaction: use hook API instead of run-command Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 07/11] hook: allow overriding the ungroup option Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 08/11] run-command: allow capturing of collated output Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 09/11] hooks: allow callers to capture output Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 10/11] receive-pack: convert update hooks to new API Adrian Ratiu
2025-12-18 17:11 ` [PATCH v5 11/11] receive-pack: convert receive hooks to hook API Adrian Ratiu
2025-12-19 12:38 ` Patrick Steinhardt
2025-12-20 10:40 ` Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 00/11] Convert remaining hooks to hook.h Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 01/11] run-command: add first helper for pp child states Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 02/11] run-command: add stdin callback for parallelization Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 03/11] hook: provide stdin via callback Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 04/11] hook: convert 'post-rewrite' hook in sequencer.c to hook API Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 05/11] transport: convert pre-push " Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 06/11] reference-transaction: use hook API instead of run-command Adrian Ratiu
2026-01-18 12:23 ` SZEDER Gábor
2026-01-18 18:30 ` Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 07/11] hook: allow overriding the ungroup option Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 08/11] run-command: allow capturing of collated output Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 09/11] hooks: allow callers to capture output Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 10/11] receive-pack: convert update hooks to new API Adrian Ratiu
2025-12-26 12:23 ` [PATCH v6 11/11] receive-pack: convert receive hooks to hook API Adrian Ratiu
2025-12-28 11:32 ` [PATCH v6 00/11] Convert remaining hooks to hook.h Junio C Hamano
2026-01-05 10:52 ` Adrian Ratiu
2026-01-05 12:13 ` Patrick Steinhardt
2026-01-21 21:54 ` [PATCH v7 00/12] " Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 01/12] t1800: add hook output stream tests Adrian Ratiu
2026-01-21 22:16 ` Junio C Hamano
2026-01-22 9:19 ` Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 02/12] run-command: add first helper for pp child states Adrian Ratiu
2026-01-21 23:01 ` Junio C Hamano
2026-01-22 9:21 ` Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 03/12] run-command: add stdin callback for parallelization Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 04/12] hook: provide stdin via callback Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 05/12] hook: convert 'post-rewrite' hook in sequencer.c to hook API Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 06/12] hook: allow separate std[out|err] streams Adrian Ratiu
2026-01-23 7:19 ` Patrick Steinhardt
2026-01-23 7:47 ` Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 07/12] transport: convert pre-push to hook API Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 08/12] reference-transaction: use hook API instead of run-command Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 09/12] hook: add jobs option Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 10/12] run-command: poll child stdin in addition to stdout Adrian Ratiu
2026-01-21 22:04 ` Kristoffer Haugsbakk
2026-01-22 9:57 ` Adrian Ratiu
2026-01-21 23:11 ` Junio C Hamano
2026-01-22 10:58 ` Adrian Ratiu
2026-01-22 17:20 ` Junio C Hamano
2026-01-26 23:20 ` Emily Shaffer
2026-01-27 0:11 ` Junio C Hamano
2026-01-27 10:10 ` Adrian Ratiu
2026-01-21 21:54 ` [PATCH v7 11/12] receive-pack: convert update hooks to new API Adrian Ratiu
2026-01-21 22:14 ` Kristoffer Haugsbakk
2026-01-22 9:26 ` Adrian Ratiu
2026-01-27 0:12 ` Emily Shaffer
2026-01-27 13:05 ` Adrian Ratiu [this message]
2026-01-21 21:54 ` [PATCH v7 12/12] receive-pack: convert receive hooks to hook API Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 00/12] Convert remaining hooks to hook.h Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 01/12] t1800: add hook output stream tests Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 02/12] run-command: add helper for pp child states Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 03/12] run-command: add stdin callback for parallelization Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 04/12] hook: provide stdin via callback Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 05/12] hook: convert 'post-rewrite' hook in sequencer.c to hook API Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 06/12] hook: allow separate std[out|err] streams Adrian Ratiu
2026-02-02 3:17 ` Chris Darroch
2026-02-02 16:32 ` Junio C Hamano
2026-01-28 21:39 ` [PATCH v8 07/12] transport: convert pre-push to hook API Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 08/12] reference-transaction: use hook API instead of run-command Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 09/12] hook: add jobs option Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 10/12] run-command: poll child input in addition to output Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 11/12] receive-pack: convert update hooks to new API Adrian Ratiu
2026-01-28 21:39 ` [PATCH v8 12/12] receive-pack: convert receive hooks to hook API Adrian Ratiu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87bjifmcia.fsf@collabora.com \
--to=adrian.ratiu@collabora.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=nasamuffin@google.com \
--cc=peff@peff.net \
--cc=ps@pks.im \
--cc=steadmon@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox