public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: Adrian Ratiu <adrian.ratiu@collabora•com>
To: git@vger•kernel.org, Jeff King <peff@peff•net>
Cc: Emily Shaffer <emilyshaffer@google•com>,
	Junio C Hamano <gitster@pobox•com>,
	Patrick Steinhardt <ps@pks•im>,
	Josh Steadmon <steadmon@google•com>,
	Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail•com>,
	Adrian Ratiu <adrian.ratiu@collabora•com>
Subject: [PATCH v8 10/12] run-command: poll child input in addition to output
Date: Wed, 28 Jan 2026 23:39:25 +0200	[thread overview]
Message-ID: <20260128213927.3026875-11-adrian.ratiu@collabora.com> (raw)
In-Reply-To: <20260128213927.3026875-1-adrian.ratiu@collabora.com>

Child input feeding might hit the 100ms output poll timeout as a
side-effect of the ungroup=0 design when feeding multiple children
in parallel and buffering their outputs.

This throttles the write throughput as reported by Kristoffer.

Peff also noted that the parent might block if the write pipe is full
and cause a deadlock if both parent + child wait for one another.

Thus we refactor the run-command I/O loop so it polls on both child
input and output fds to eliminate the risk of artificial 100ms
latencies and unnecessarily blocking the main process.

This ensures that parallel hooks are fed data ASAP while maintaining
responsiveness for (sideband) output.

It's worth noting that in our current design, sequential execution
is not affected by this because it still uses the ungroup=1 behavior,
so there are no run-command induced buffering delays since the child
sequentially outputs directly to the parent-inherited fds.

Reported-by: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail•com>
Suggested-by: Jeff King <peff@peff•net>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora•com>
---
 run-command.c | 80 +++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 62 insertions(+), 18 deletions(-)

diff --git a/run-command.c b/run-command.c
index aaf0e4ecee..3356463d43 100644
--- a/run-command.c
+++ b/run-command.c
@@ -1499,6 +1499,14 @@ static int child_is_receiving_input(const struct parallel_child *pp_child)
 {
 	return child_is_working(pp_child) && pp_child->process.in > 0;
 }
+static int child_is_sending_output(const struct parallel_child *pp_child)
+{
+	/*
+	 * all pp children which buffer output through run_command via ungroup=0
+	 * redirect stdout to stderr, so we just need to check process.err.
+	 */
+	return child_is_working(pp_child) && pp_child->process.err > 0;
+}
 
 struct parallel_processes {
 	size_t nr_processes;
@@ -1562,7 +1570,7 @@ static void pp_init(struct parallel_processes *pp,
 
 	CALLOC_ARRAY(pp->children, n);
 	if (!opts->ungroup)
-		CALLOC_ARRAY(pp->pfd, n);
+		CALLOC_ARRAY(pp->pfd, n * 2);
 
 	for (size_t i = 0; i < n; i++) {
 		strbuf_init(&pp->children[i].err, 0);
@@ -1707,21 +1715,63 @@ static void pp_buffer_stdin(struct parallel_processes *pp,
 	}
 }
 
-static void pp_buffer_stderr(struct parallel_processes *pp,
-			     const struct run_process_parallel_opts *opts,
-			     int output_timeout)
+static void pp_buffer_io(struct parallel_processes *pp,
+			 const struct run_process_parallel_opts *opts,
+			 int timeout)
 {
-	while (poll(pp->pfd, opts->processes, output_timeout) < 0) {
+	/* for each potential child slot, prepare two pollfd entries */
+	for (size_t i = 0; i < opts->processes; i++) {
+		if (child_is_sending_output(&pp->children[i])) {
+			pp->pfd[2*i].fd = pp->children[i].process.err;
+			pp->pfd[2*i].events = POLLIN | POLLHUP;
+		} else {
+			pp->pfd[2*i].fd = -1;
+		}
+
+		if (child_is_receiving_input(&pp->children[i])) {
+			pp->pfd[2*i+1].fd = pp->children[i].process.in;
+			pp->pfd[2*i+1].events = POLLOUT;
+		} else {
+			pp->pfd[2*i+1].fd = -1;
+		}
+	}
+
+	while (poll(pp->pfd, opts->processes * 2, timeout) < 0) {
 		if (errno == EINTR)
 			continue;
 		pp_cleanup(pp, opts);
 		die_errno("poll");
 	}
 
-	/* Buffer output from all pipes. */
 	for (size_t i = 0; i < opts->processes; i++) {
+		/* Handle input feeding (stdin) */
+		if (pp->pfd[2*i+1].revents & (POLLOUT | POLLHUP | POLLERR)) {
+			if (opts->feed_pipe) {
+				int ret = opts->feed_pipe(pp->children[i].process.in,
+							  opts->data,
+							  pp->children[i].data);
+				if (ret < 0)
+					die_errno("feed_pipe");
+				if (ret) {
+					/* done feeding */
+					close(pp->children[i].process.in);
+					pp->children[i].process.in = 0;
+				}
+			} else {
+				/*
+				 * No feed_pipe means there is nothing to do, so
+				 * close the fd. Child input can be fed by other
+				 * methods, such as opts->path_to_stdin which
+				 * slurps a file via dup2, so clean up here.
+				 */
+				close(pp->children[i].process.in);
+				pp->children[i].process.in = 0;
+			}
+		}
+
+		/* Handle output reading (stderr) */
 		if (child_is_working(&pp->children[i]) &&
-		    pp->pfd[i].revents & (POLLIN | POLLHUP)) {
+		    pp->pfd[2*i].revents & (POLLIN | POLLHUP)) {
 			int n = strbuf_read_once(&pp->children[i].err,
 						 pp->children[i].process.err, 0);
 			if (n == 0) {
@@ -1814,21 +1864,15 @@ static int pp_collect_finished(struct parallel_processes *pp,
 
 static void pp_handle_child_IO(struct parallel_processes *pp,
 				const struct run_process_parallel_opts *opts,
-				int output_timeout)
+				int timeout)
 {
-	/*
-	 * First push input, if any (it might no-op), to child tasks to avoid them blocking
-	 * after input. This also prevents deadlocks when ungrouping below, if a child blocks
-	 * while the parent also waits for them to finish.
-	 */
-	pp_buffer_stdin(pp, opts);
-
 	if (opts->ungroup) {
+		pp_buffer_stdin(pp, opts);
 		for (size_t i = 0; i < opts->processes; i++)
 			if (child_is_ready_for_cleanup(&pp->children[i]))
 				pp->children[i].state = GIT_CP_WAIT_CLEANUP;
 	} else {
-		pp_buffer_stderr(pp, opts, output_timeout);
+		pp_buffer_io(pp, opts, timeout);
 		pp_output(pp);
 	}
 }
@@ -1836,7 +1880,7 @@ static void pp_handle_child_IO(struct parallel_processes *pp,
 void run_processes_parallel(const struct run_process_parallel_opts *opts)
 {
 	int i, code;
-	int output_timeout = 100;
+	int timeout = 100;
 	int spawn_cap = 4;
 	struct parallel_processes_for_signal pp_sig;
 	struct parallel_processes pp = {
@@ -1876,7 +1920,7 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)
 		}
 		if (!pp.nr_processes)
 			break;
-		pp_handle_child_IO(&pp, opts, output_timeout);
+		pp_handle_child_IO(&pp, opts, timeout);
 		code = pp_collect_finished(&pp, opts);
 		if (code) {
 			pp.shutdown = 1;
-- 
2.52.0.732.gb351b5166d.dirty


  parent reply	other threads:[~2026-01-28 21:40 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
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   ` Adrian Ratiu [this message]
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=20260128213927.3026875-11-adrian.ratiu@collabora.com \
    --to=adrian.ratiu@collabora$(echo .)com \
    --cc=emilyshaffer@google$(echo .)com \
    --cc=git@vger$(echo .)kernel.org \
    --cc=gitster@pobox$(echo .)com \
    --cc=kristofferhaugsbakk@fastmail$(echo .)com \
    --cc=peff@peff$(echo .)net \
    --cc=ps@pks$(echo .)im \
    --cc=steadmon@google$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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