Volume XXII, number 280Wednesday, October 7, 2026Latest message 51 minutes ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

I discovered a minor issue with `git fetch`.

4 messages between May 22, 2026 and May 27, 2026, from SURA, Ben Knoble, brian m. carlson, Jeff King.

Plain Markdown or JSON for tools and agents.

SURAMay 22, 2026, 07:45 UTC on lore
Hello everyone

The child processes spawned by `git fetch` can become zombie processes. In most scenarios, these zombie processes are reaped by Process 1, so this typically doesn't cause any problems.

However, within a Docker container, the application service itself is sometimes designated as Process 1 (for instance, a service written in Go). Since these application services lack the capability to reap zombie processes, the zombies will gradually exhaust the available PID resources.

Here are the simple steps to reproduce this issue:
1. `git clone https://github.com/SURA907/pid-1.git`
2. `cd pid-1`
3. `docker build -t pid-1 .`
4. `docker run -d --name pid-1 pid-1:latest`
5. `docker exec -it pid-1 /bin/bash`
6. `mkdir repo && cd repo && git init --bare`
7. `ps -ef`
------
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null
root 7 0 0 07:16 pts/0 00:00:00 /bin/bash
root 13 0 0 07:16 pts/1 00:00:00 /bin/bash
root 29 7 0 07:17 pts/0 00:00:00 ps -ef
------
8. `git fetch https://github.com/git/git.git`
9. `ps -ef` (Run this command from a separate terminal session
connected to the container)
------
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null
root 7 0 0 07:16 pts/0 00:00:00 /bin/bash
root 13 0 0 07:16 pts/1 00:00:00 /bin/bash
root 30 13 1 07:17 pts/1 00:00:00 git fetch https://github.com/git/git.git
root 31 30 0 07:17 pts/1 00:00:00 /usr/local/libexec/git-core/git
remote-https https://github.com/git/git.git
https://github.com/git/git.git
root 32 31 2 07:17 pts/1 00:00:00
/usr/local/libexec/git-core/git-remote-https
https://github.com/git/git.git https://github.com/git/git.git
root 36 30 30 07:17 pts/1 00:00:00 /usr/local/libexec/git-core/git
index-pack --stdin -v --fix-thin --keep=fetch-pack 30 on sura-pc
--pack_header=2,399455
root 38 7 0 07:17 pts/0 00:00:00 ps -ef
------
10. ps -ef (after fetch ends)
------
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null
root 7 0 0 07:16 pts/0 00:00:00 /bin/bash
root 13 0 0 07:16 pts/1 00:00:00 /bin/bash
root 52 1 0 07:19 ? 00:00:00 [git] <defunct>
root 53 7 0 07:19 pts/0 00:00:00 ps -ef
------

A zombie process has appeared. It appears to originate from a `fetch` subprocess that terminates very quickly; despite several attempts, I have been unable to successfully capture it.

This issue was discovered within a legacy service. A few days after upgrading to Git 2.53.0, the system's PID resources were exhausted by zombie processes. This is likely the result of recent changes, as this problem did not exist in earlier versions (2.4x).

To be honest, this is not an urgent matter; I have already deployed `tini` as the init process (PID 1) to prevent the service from becoming unavailable.

Ben KnobleMay 22, 2026, 17:46 UTC in reply to SURA on lore

Re: I discovered a minor issue with `git fetch`.

Show 13 quoted lines
> Le 22 mai 2026 à 03:48, SURA <surak8806@gmail.com> a écrit :
> 
> Hello everyone
> 
> The child processes spawned by `git fetch` can become zombie processes.
> In most scenarios, these zombie processes are reaped by Process 1, so
> this typically doesn't cause any problems.
> 
> However, within a Docker container, the application service itself is
> sometimes designated as Process 1 (for instance, a service written in
> Go). Since these application services lack the capability to reap
> zombie processes, the zombies will gradually exhaust the available PID
> resources.
See also lore.kernel.org/git/202602231615147.3294516-1-cshung@gmail.com and subsequent discussion for related material.
Show 61 quoted lines
> 
> Here are the simple steps to reproduce this issue:
> 1. `git clone https://github.com/SURA907/pid-1.git`
> 2. `cd pid-1`
> 3. `docker build -t pid-1 .`
> 4. `docker run -d --name pid-1 pid-1:latest`
> 5. `docker exec -it pid-1 /bin/bash`
> 6. `mkdir repo && cd repo && git init --bare`
> 7. `ps -ef`
> ------
> UID PID PPID C STIME TTY TIME CMD
> root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null
> root 7 0 0 07:16 pts/0 00:00:00 /bin/bash
> root 13 0 0 07:16 pts/1 00:00:00 /bin/bash
> root 29 7 0 07:17 pts/0 00:00:00 ps -ef
> ------
> 
> 8. `git fetch https://github.com/git/git.git`
> 9. `ps -ef` (Run this command from a separate terminal session
> connected to the container)
> ------
> UID PID PPID C STIME TTY TIME CMD
> root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null
> root 7 0 0 07:16 pts/0 00:00:00 /bin/bash
> root 13 0 0 07:16 pts/1 00:00:00 /bin/bash
> root 30 13 1 07:17 pts/1 00:00:00 git fetch https://github.com/git/git.git
> root 31 30 0 07:17 pts/1 00:00:00 /usr/local/libexec/git-core/git
> remote-https https://github.com/git/git.git
> https://github.com/git/git.git
> root 32 31 2 07:17 pts/1 00:00:00
> /usr/local/libexec/git-core/git-remote-https
> https://github.com/git/git.git https://github.com/git/git.git
> root 36 30 30 07:17 pts/1 00:00:00 /usr/local/libexec/git-core/git
> index-pack --stdin -v --fix-thin --keep=fetch-pack 30 on sura-pc
> --pack_header=2,399455
> root 38 7 0 07:17 pts/0 00:00:00 ps -ef
> ------
> 
> 10. ps -ef (after fetch ends)
> ------
> UID PID PPID C STIME TTY TIME CMD
> root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null
> root 7 0 0 07:16 pts/0 00:00:00 /bin/bash
> root 13 0 0 07:16 pts/1 00:00:00 /bin/bash
> root 52 1 0 07:19 ? 00:00:00 [git] <defunct>
> root 53 7 0 07:19 pts/0 00:00:00 ps -ef
> ------
> 
> A zombie process has appeared. It appears to originate from a `fetch`
> subprocess that terminates very quickly; despite several attempts, I
> have been unable to successfully capture it.
> 
> This issue was discovered within a legacy service. A few days after
> upgrading to Git 2.53.0, the system's PID resources were exhausted by
> zombie processes. This is likely the result of recent changes, as this
> problem did not exist in earlier versions (2.4x).
> 
> To be honest, this is not an urgent matter; I have already deployed
> `tini` as the init process (PID 1) to prevent the service from
> becoming unavailable.
> 
brian m. carlsonMay 25, 2026, 00:45 UTC in reply to SURA on lore

Re: I discovered a minor issue with `git fetch`.

On 2026-05-22 at 07:45:25, SURA wrote:
Show 20 quoted lines
> Hello everyone
> 
> The child processes spawned by `git fetch` can become zombie processes.
> In most scenarios, these zombie processes are reaped by Process 1, so
> this typically doesn't cause any problems.
> 
> However, within a Docker container, the application service itself is
> sometimes designated as Process 1 (for instance, a service written in
> Go). Since these application services lack the capability to reap
> zombie processes, the zombies will gradually exhaust the available PID
> resources.
> This issue was discovered within a legacy service. A few days after
>
> upgrading to Git 2.53.0, the system's PID resources were exhausted by
> zombie processes. This is likely the result of recent changes, as this
> problem did not exist in earlier versions (2.4x).
> 
> To be honest, this is not an urgent matter; I have already deployed
> `tini` as the init process (PID 1) to prevent the service from
> becoming unavailable.

While there has been some discussion about this on the list in the recent past, using something like tini is the right move in the general case. There are a variety of programs which might daemonize a background process for whatever reason and those will necessarily require an init process to reap children. It's considered a standard requirement that PID 1 has that ability and Git doesn't provide it.

-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
Jeff KingMay 27, 2026, 10:56 UTC in reply to SURA on lore

git-maintenance detach timing, was Re: I discovered a minor issue with `git fetch`.

On Fri, May 22, 2026 at 03:45:25PM +0800, SURA wrote:
Show 12 quoted lines
> A zombie process has appeared. It appears to originate from a `fetch`
> subprocess that terminates very quickly; despite several attempts, I
> have been unable to successfully capture it.
> 
> This issue was discovered within a legacy service. A few days after
> upgrading to Git 2.53.0, the system's PID resources were exhausted by
> zombie processes. This is likely the result of recent changes, as this
> problem did not exist in earlier versions (2.4x).
> 
> To be honest, this is not an urgent matter; I have already deployed
> `tini` as the init process (PID 1) to prevent the service from
> becoming unavailable.

Yeah, I agree that you need some kind of zombie-reaping init process. But I did wonder if we might have started generating more zombies here.

I did a little poking around with "strace -p 1". I didn't see extra fetch processes, but I did see a lot of zombie git-maintenance processes getting reaped. Which makes sense; by default we run background maintenance with --detach. We can't ever reap that ourselves, since the whole point is that it might outlive the parent fetch.

Once upon a time, we used to run "git gc --auto", and it would check whether gc was needed (using a simple count of objects and packs) before detaching. So in most cases it would realize there was nothing to be done and exit immediately without daemonizing, and would get reaped by git-fetch.

We switched to running "git maintenance" in v2.29. But it didn't yet have a detached mode; it just run "git gc --detach" under the hood, so the behavior was roughly the same (gc was reaped by maintenance which was reaped by fetch).

Later, git-maintenance learned its own --detach flag, as of v2.47. But unlike gc, it detaches immediately, and then each sub-task decides if it needs to be run or not. So every "git fetch" will generate a detached maintenance process that then gets reaped by init.

And if you moved from a pre-v2.47 version, then you'd see an increase in such processes.

I think this is probably OK in practice. It is an extra fork that git-gc never incurred, but as long as you have a functioning init process, they won't accumulate.

I do wonder if git-maintenance could be more like git-gc here. Its notion of tasks is more abstract, but it could in theory ask each task "do you need to run?" and if they all say "no", then it can quit without detaching. That would save an extra fork() for every noop auto-maintenance call. I don't know how measurable that is in practice. Or even how easy it is for each task to do such a check. Something like "prefetch" is kind of all-or-nothing; you find out whether it needs doing by doing it.

-Peff

Back to recent threads