<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/run-command.c, branch main</title>
<subtitle>Fork of git SCM with my patches.</subtitle>
<id>http://git.kilabit.info/git/atom?h=main</id>
<link rel='self' href='http://git.kilabit.info/git/atom?h=main'/>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/'/>
<updated>2026-04-08T17:54:32Z</updated>
<entry>
<title>run_processes_parallel(): fix order of sigpipe handling</title>
<updated>2026-04-08T17:54:32Z</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2026-04-08T17:20:55Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=2226ffaacd93d3fe5554687a70d9190d72596f96'/>
<id>urn:sha1:2226ffaacd93d3fe5554687a70d9190d72596f96</id>
<content type='text'>
In commit ec0becacc9 (run-command: add stdin callback for
parallelization, 2026-01-28), we taught run_processes_parallel() to
ignore SIGPIPE, since we wouldn't want a write() to a broken pipe of one
of the children to take down the whole process.

But there's a subtle ordering issue. After we ignore SIGPIPE, we call
pp_init(), which installs its own cleanup handler for multiple signals
using sigchain_push_common(), which includes SIGPIPE. So if we receive
SIGPIPE while writing to a child, we'll trigger that handler first, pop
it off the stack, and then re-raise (which is then ignored because of
the SIG_IGN we pushed first).

But what does that handler do? It tries to clean up all of the child
processes, under the assumption that when we re-raise the signal we'll
be exiting the process!

So a hook that exits without reading all of its input will cause us to
get SIGPIPE, which will put us in a signal handler that then tries to
kill() that same child.

This seems to be mostly harmless on Linux. The process has already
exited by this point, and though kill() does not complain (since the
process has not been reaped with a wait() call), it does not affect the
exit status of the process.

However, this seems not to be true on all platforms. This case is
triggered by t5401.13, "pre-receive hook that forgets to read its
input". This test fails on NonStop since that hook was converted to the
run_processes_parallel() API.

We can fix it by reordering the code a bit. We should run pp_init()
first, and then push our SIG_IGN onto the stack afterwards, so that it
is truly ignored while feeding the sub-processes.

Note that we also reorder the popping at the end of the function, too.
This is not technically necessary, as we are doing two pops either way,
but now the pops will correctly match their pushes.

This also fixes a related case that we can't test yet. If we did have
more than one process to run, then one child causing SIGPIPE would cause
us to kill() all of the children (which might still actually be
running). But the hook API is the only user of the new feed_pipe
feature, and it does not yet support parallel hook execution. So for now
we'll always execute the processes sequentially. Once parallel hook
execution exists, we'll be able to add a test which covers this.

Reported-by: Randall S. Becker &lt;rsbecker@nexbridge.com&gt;
Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'bk/run-command-wo-the-repository'</title>
<updated>2026-03-19T16:54:56Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2026-03-19T16:54:55Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=a7a079c2c4bc7b269229a6ea6c147b6b2d5b2684'/>
<id>urn:sha1:a7a079c2c4bc7b269229a6ea6c147b6b2d5b2684</id>
<content type='text'>
The run_command() API lost its implicit dependencyon the singleton
`the_repository` instance.

* bk/run-command-wo-the-repository:
  run-command: wean auto_maintenance() functions off the_repository
  run-command: wean start_command() off the_repository
</content>
</entry>
<entry>
<title>Merge branch 'ds/for-each-repo-w-worktree'</title>
<updated>2026-03-12T21:09:05Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2026-03-12T21:09:05Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=03161747b412fe739d8a7ef631769b3d8f60d56f'/>
<id>urn:sha1:03161747b412fe739d8a7ef631769b3d8f60d56f</id>
<content type='text'>
"git for-each-repo" started from a secondary worktree did not work
as expected, which has been corrected.

* ds/for-each-repo-w-worktree:
  for-each-repo: simplify passing of parameters
  for-each-repo: work correctly in a worktree
  run-command: extract sanitize_repo_env helper
  for-each-repo: test outside of repo context
</content>
</entry>
<entry>
<title>run-command: wean auto_maintenance() functions off the_repository</title>
<updated>2026-03-12T15:30:57Z</updated>
<author>
<name>Burak Kaan Karaçay</name>
<email>bkkaracay@gmail.com</email>
</author>
<published>2026-03-12T14:44:37Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=9df3be8e2e7e2c9bf200de4bcfbd4e690a57f033'/>
<id>urn:sha1:9df3be8e2e7e2c9bf200de4bcfbd4e690a57f033</id>
<content type='text'>
The prepare_auto_maintenance() relies on the_repository to read
configurations. Since run_auto_maintenance() calls
prepare_auto_maintenance(), it also implicitly depends the_repository.

Add 'struct repository *' as a parameter to both functions and update
all callers to pass the_repository.

With no global repository dependencies left in this file, remove the
USE_THE_REPOSITORY_VARIABLE macro.

Suggested-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Burak Kaan Karaçay &lt;bkkaracay@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>run-command: wean start_command() off the_repository</title>
<updated>2026-03-12T15:30:57Z</updated>
<author>
<name>Burak Kaan Karaçay</name>
<email>bkkaracay@gmail.com</email>
</author>
<published>2026-03-12T14:44:36Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=05c324b92fe723674cbf9ae1b0b1675821b6c275'/>
<id>urn:sha1:05c324b92fe723674cbf9ae1b0b1675821b6c275</id>
<content type='text'>
The start_command() relies on the_repository due to the
close_object_store flag in 'struct child_process'. When this flag is
set, start_command() closes the object store associated with
the_repository before spawning a child process.

To eliminate this dependency, replace the 'close_object_store' with the
new 'struct object_database *odb_to_close' field. This allows callers to
specify the object store that needs to be closed.

Suggested-by: René Scharfe &lt;l.s.r@web.de&gt;
Signed-off-by: Burak Kaan Karaçay &lt;bkkaracay@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'ar/run-command-hook-take-2'</title>
<updated>2026-03-09T21:36:55Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2026-03-09T21:36:55Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=5c56c725f104ce278fe1ec0ea0fce0ccfb245aea'/>
<id>urn:sha1:5c56c725f104ce278fe1ec0ea0fce0ccfb245aea</id>
<content type='text'>
Use the hook API to replace ad-hoc invocation of hook scripts via
the run_command() API.

* ar/run-command-hook-take-2:
  builtin/receive-pack: avoid spinning no-op sideband async threads
  receive-pack: convert receive hooks to hook API
  receive-pack: convert update hooks to new API
  run-command: poll child input in addition to output
  hook: add jobs option
  reference-transaction: use hook API instead of run-command
  transport: convert pre-push to hook API
  hook: allow separate std[out|err] streams
  hook: convert 'post-rewrite' hook in sequencer.c to hook API
  hook: provide stdin via callback
  run-command: add stdin callback for parallelization
  run-command: add helper for pp child states
  t1800: add hook output stream tests
</content>
</entry>
<entry>
<title>run-command: extract sanitize_repo_env helper</title>
<updated>2026-03-03T18:19:59Z</updated>
<author>
<name>Derrick Stolee</name>
<email>stolee@gmail.com</email>
</author>
<published>2026-03-03T17:31:52Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=5f031fe4f14b5cc754daaf24534dbe0c6647fcca'/>
<id>urn:sha1:5f031fe4f14b5cc754daaf24534dbe0c6647fcca</id>
<content type='text'>
The current prepare_other_repo_env() does two distinct things:

 1. Strip certain known environment variables that should be set by a
    child process based on a different repository.

 2. Set the GIT_DIR variable to avoid repository discovery.

The second item is valuable for child processes that operate on
submodules, where the repo discovery could be mistaken for the parent
repository.

In the next change, we will see an important case where only the first
item is required as the GIT_DIR discovery should happen naturally from
the '-C' parameter in the child process.

Helped-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Derrick Stolee &lt;stolee@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>t: fix races caused by background maintenance</title>
<updated>2026-02-24T15:33:19Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2026-02-24T08:45:45Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=09505b11153a20e1c6c572d41db778171dd19cbc'/>
<id>urn:sha1:09505b11153a20e1c6c572d41db778171dd19cbc</id>
<content type='text'>
Many Git commands spawn git-maintenance(1) to optimize the repository in
the background. By default, performing the maintenance is for most of
the part asynchronous: we fork the executable and then continue with the
rest of our business logic.

This is working as expected for our users, but this behaviour is
somewhat problematic for our test suite as this is inherently racy. We
have many tests that verify the on-disk state of repositories, and those
tests may easily race with our background maintenance. In a similar
fashion, we may end up with processes that "leak" out of a current test
case.

Until now this tends to not be much of a problem. Our maintenance uses
git-gc(1) by default, which knows to bail out in case there aren't
either too many packfiles or too many loose objects. So even if other
data structures would need to be optimized, we won't do so unless the
object database also needs optimizations.

This is about to change though, as a subsequent commit will switch to
the "geometric" maintenance strategy as a default. The consequence is
that we will run required optimizations even if the object database is
well-optimized. And this uncovers races between our test suite and
background maintenance all over the place.

Disabling maintenance outright in our test suite is not really an
option, as it would result in significant divergence from the "real
world" and reduce our test coverage. But we've got an alternative up our
sleeves: we can ensure that garbage collection runs synchronously by
overriding the "maintenance.autoDetach" configuration.

Of course that also diverges from the real world, as we now stop testing
that background maintenance interacts in a benign way with normal Git
commands. But on the other hand this ensures that the maintenance itself
does not for example lead to data loss in a more reproducible way.

Another concern is that this would make execution of the test suite much
slower. But a quick benchmark on my machine demonstrates that this does
not seem to be the case:

    Benchmark 1: meson test (revision = HEAD~)
      Time (mean ± σ):     131.182 s ±  1.293 s    [User: 853.737 s, System: 1160.479 s]
      Range (min … max):   130.001 s … 132.563 s    3 runs

    Benchmark 2: meson test (revision = HEAD)
      Time (mean ± σ):     129.554 s ±  0.507 s    [User: 849.040 s, System: 1152.664 s]
      Range (min … max):   129.000 s … 129.994 s    3 runs

    Summary
      meson test (revision = HEAD) ran
        1.01 ± 0.01 times faster than meson test (revision = HEAD~)

Funny enough, it even seems as if this speeds up test execution ever so
slightly, but that may just as well be noise.

Introduce a new `GIT_TEST_MAINT_AUTO_DETACH` environment variable that
allows us to override the auto-detach behaviour and set that variable in
our tests.

Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>run-command: poll child input in addition to output</title>
<updated>2026-01-28T23:47:03Z</updated>
<author>
<name>Adrian Ratiu</name>
<email>adrian.ratiu@collabora.com</email>
</author>
<published>2026-01-28T21:39:25Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=c45a34e12e8699f656ec3613b6ba158c1a57c5e8'/>
<id>urn:sha1:c45a34e12e8699f656ec3613b6ba158c1a57c5e8</id>
<content type='text'>
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 &lt;kristofferhaugsbakk@fastmail.com&gt;
Suggested-by: Jeff King &lt;peff@peff.net&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>run-command: add stdin callback for parallelization</title>
<updated>2026-01-28T23:47:02Z</updated>
<author>
<name>Emily Shaffer</name>
<email>emilyshaffer@google.com</email>
</author>
<published>2026-01-28T21:39:18Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/git/commit/?id=ec0becacc9847406f2b0147a81f62e023b006351'/>
<id>urn:sha1:ec0becacc9847406f2b0147a81f62e023b006351</id>
<content type='text'>
If a user of the run_processes_parallel() API wants to pipe a large
amount of information to the stdin of each parallel command, that
data could exceed the pipe buffer of the process's stdin and can be
too big to store in-memory via strbuf &amp; friends or to slurp to a file.

Generally this is solved by repeatedly writing to child_process.in
between calls to start_command() and finish_command(). For a specific
pre-existing example of this, see transport.c:run_pre_push_hook().

This adds a generic callback API to run_processes_parallel() to do
exactly that in a unified manner, similar to the existing callback APIs,
which can then be used by hooks.h to convert the remaining hooks to the
new, simpler parallel interface.

Signed-off-by: Emily Shaffer &lt;emilyshaffer@google.com&gt;
Signed-off-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>
</feed>
