{"thread":{"id":"65674","subject":"I discovered a minor issue with `git fetch`.","startedAt":"2026-05-22T07:45:37Z","lastAt":"2026-05-27T10:56:40Z","messageCount":4,"participants":["SURA","Ben Knoble","brian m. carlson","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"543896","messageId":"CAD6AYr9YmcnkdW=Nx=HUKcuaNbv1ukrAbXRnKyGibCQDy8N3hQ@mail.gmail.com","threadId":"65674","inReplyTo":null,"subject":"I discovered a minor issue with `git fetch`.","fromName":"SURA","fromEmail":"surak8806@gmail.com","sentAt":"2026-05-22T07:45:25Z","receivedAt":"2026-05-22T07:45:37Z","isPatch":false,"body":"Hello everyone\n\nThe child processes spawned by `git fetch` can become zombie processes.\nIn most scenarios, these zombie processes are reaped by Process 1, so\nthis typically doesn't cause any problems.\n\nHowever, within a Docker container, the application service itself is\nsometimes designated as Process 1 (for instance, a service written in\nGo). Since these application services lack the capability to reap\nzombie processes, the zombies will gradually exhaust the available PID\nresources.\n\nHere are the simple steps to reproduce this issue:\n1. `git clone https://github.com/SURA907/pid-1.git`\n2. `cd pid-1`\n3. `docker build -t pid-1 .`\n4. `docker run -d --name pid-1 pid-1:latest`\n5. `docker exec -it pid-1 /bin/bash`\n6. `mkdir repo && cd repo && git init --bare`\n7. `ps -ef`\n------\nUID PID PPID C STIME TTY TIME CMD\nroot 1 0 0 07:16 ? 00:00:00 tail -f /dev/null\nroot 7 0 0 07:16 pts/0 00:00:00 /bin/bash\nroot 13 0 0 07:16 pts/1 00:00:00 /bin/bash\nroot 29 7 0 07:17 pts/0 00:00:00 ps -ef\n------\n\n8. `git fetch https://github.com/git/git.git`\n9. `ps -ef` (Run this command from a separate terminal session\nconnected to the container)\n------\nUID PID PPID C STIME TTY TIME CMD\nroot 1 0 0 07:16 ? 00:00:00 tail -f /dev/null\nroot 7 0 0 07:16 pts/0 00:00:00 /bin/bash\nroot 13 0 0 07:16 pts/1 00:00:00 /bin/bash\nroot 30 13 1 07:17 pts/1 00:00:00 git fetch https://github.com/git/git.git\nroot 31 30 0 07:17 pts/1 00:00:00 /usr/local/libexec/git-core/git\nremote-https https://github.com/git/git.git\nhttps://github.com/git/git.git\nroot 32 31 2 07:17 pts/1 00:00:00\n/usr/local/libexec/git-core/git-remote-https\nhttps://github.com/git/git.git https://github.com/git/git.git\nroot 36 30 30 07:17 pts/1 00:00:00 /usr/local/libexec/git-core/git\nindex-pack --stdin -v --fix-thin --keep=fetch-pack 30 on sura-pc\n--pack_header=2,399455\nroot 38 7 0 07:17 pts/0 00:00:00 ps -ef\n------\n\n10. ps -ef (after fetch ends)\n------\nUID PID PPID C STIME TTY TIME CMD\nroot 1 0 0 07:16 ? 00:00:00 tail -f /dev/null\nroot 7 0 0 07:16 pts/0 00:00:00 /bin/bash\nroot 13 0 0 07:16 pts/1 00:00:00 /bin/bash\nroot 52 1 0 07:19 ? 00:00:00 [git] <defunct>\nroot 53 7 0 07:19 pts/0 00:00:00 ps -ef\n------\n\nA zombie process has appeared. It appears to originate from a `fetch`\nsubprocess that terminates very quickly; despite several attempts, I\nhave been unable to successfully capture it.\n\nThis issue was discovered within a legacy service. A few days after\nupgrading to Git 2.53.0, the system's PID resources were exhausted by\nzombie processes. This is likely the result of recent changes, as this\nproblem did not exist in earlier versions (2.4x).\n\nTo be honest, this is not an urgent matter; I have already deployed\n`tini` as the init process (PID 1) to prevent the service from\nbecoming unavailable.\n"},{"id":"543935","messageId":"65A1122B-D57C-4789-8C2A-E6330B6992AF@gmail.com","threadId":"65674","inReplyTo":"CAD6AYr9YmcnkdW=Nx=HUKcuaNbv1ukrAbXRnKyGibCQDy8N3hQ@mail.gmail.com","subject":"Re: I discovered a minor issue with `git fetch`.","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-05-22T17:46:06Z","receivedAt":"2026-05-22T17:46:18Z","isPatch":false,"body":"\n> Le 22 mai 2026 à 03:48, SURA <surak8806@gmail.com> a écrit :\n> \n> ﻿Hello everyone\n> \n> The child processes spawned by `git fetch` can become zombie processes.\n> In most scenarios, these zombie processes are reaped by Process 1, so\n> this typically doesn't cause any problems.\n> \n> However, within a Docker container, the application service itself is\n> sometimes designated as Process 1 (for instance, a service written in\n> Go). Since these application services lack the capability to reap\n> zombie processes, the zombies will gradually exhaust the available PID\n> resources.\n\nSee also lore.kernel.org/git/202602231615147.3294516-1-cshung@gmail.com and subsequent discussion for related material.\n\n> \n> Here are the simple steps to reproduce this issue:\n> 1. `git clone https://github.com/SURA907/pid-1.git`\n> 2. `cd pid-1`\n> 3. `docker build -t pid-1 .`\n> 4. `docker run -d --name pid-1 pid-1:latest`\n> 5. `docker exec -it pid-1 /bin/bash`\n> 6. `mkdir repo && cd repo && git init --bare`\n> 7. `ps -ef`\n> ------\n> UID PID PPID C STIME TTY TIME CMD\n> root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null\n> root 7 0 0 07:16 pts/0 00:00:00 /bin/bash\n> root 13 0 0 07:16 pts/1 00:00:00 /bin/bash\n> root 29 7 0 07:17 pts/0 00:00:00 ps -ef\n> ------\n> \n> 8. `git fetch https://github.com/git/git.git`\n> 9. `ps -ef` (Run this command from a separate terminal session\n> connected to the container)\n> ------\n> UID PID PPID C STIME TTY TIME CMD\n> root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null\n> root 7 0 0 07:16 pts/0 00:00:00 /bin/bash\n> root 13 0 0 07:16 pts/1 00:00:00 /bin/bash\n> root 30 13 1 07:17 pts/1 00:00:00 git fetch https://github.com/git/git.git\n> root 31 30 0 07:17 pts/1 00:00:00 /usr/local/libexec/git-core/git\n> remote-https https://github.com/git/git.git\n> https://github.com/git/git.git\n> root 32 31 2 07:17 pts/1 00:00:00\n> /usr/local/libexec/git-core/git-remote-https\n> https://github.com/git/git.git https://github.com/git/git.git\n> root 36 30 30 07:17 pts/1 00:00:00 /usr/local/libexec/git-core/git\n> index-pack --stdin -v --fix-thin --keep=fetch-pack 30 on sura-pc\n> --pack_header=2,399455\n> root 38 7 0 07:17 pts/0 00:00:00 ps -ef\n> ------\n> \n> 10. ps -ef (after fetch ends)\n> ------\n> UID PID PPID C STIME TTY TIME CMD\n> root 1 0 0 07:16 ? 00:00:00 tail -f /dev/null\n> root 7 0 0 07:16 pts/0 00:00:00 /bin/bash\n> root 13 0 0 07:16 pts/1 00:00:00 /bin/bash\n> root 52 1 0 07:19 ? 00:00:00 [git] <defunct>\n> root 53 7 0 07:19 pts/0 00:00:00 ps -ef\n> ------\n> \n> A zombie process has appeared. It appears to originate from a `fetch`\n> subprocess that terminates very quickly; despite several attempts, I\n> have been unable to successfully capture it.\n> \n> This issue was discovered within a legacy service. A few days after\n> upgrading to Git 2.53.0, the system's PID resources were exhausted by\n> zombie processes. This is likely the result of recent changes, as this\n> problem did not exist in earlier versions (2.4x).\n> \n> To be honest, this is not an urgent matter; I have already deployed\n> `tini` as the init process (PID 1) to prevent the service from\n> becoming unavailable.\n> \n"},{"id":"544019","messageId":"ahObpiF9WvL-EfsB@fruit.crustytoothpaste.net","threadId":"65674","inReplyTo":"CAD6AYr9YmcnkdW=Nx=HUKcuaNbv1ukrAbXRnKyGibCQDy8N3hQ@mail.gmail.com","subject":"Re: I discovered a minor issue with `git fetch`.","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2026-05-25T00:45:26Z","receivedAt":"2026-05-25T00:45:34Z","isPatch":false,"body":"On 2026-05-22 at 07:45:25, SURA wrote:\n> Hello everyone\n> \n> The child processes spawned by `git fetch` can become zombie processes.\n> In most scenarios, these zombie processes are reaped by Process 1, so\n> this typically doesn't cause any problems.\n> \n> However, within a Docker container, the application service itself is\n> sometimes designated as Process 1 (for instance, a service written in\n> Go). Since these application services lack the capability to reap\n> zombie processes, the zombies will gradually exhaust the available PID\n> resources.\n> This issue was discovered within a legacy service. A few days after\n>\n> upgrading to Git 2.53.0, the system's PID resources were exhausted by\n> zombie processes. This is likely the result of recent changes, as this\n> problem did not exist in earlier versions (2.4x).\n> \n> To be honest, this is not an urgent matter; I have already deployed\n> `tini` as the init process (PID 1) to prevent the service from\n> becoming unavailable.\n\nWhile there has been some discussion about this on the list in the\nrecent past, using something like tini is the right move in the general\ncase.  There are a variety of programs which might daemonize a\nbackground process for whatever reason and those will necessarily\nrequire an init process to reap children.  It's considered a standard\nrequirement that PID 1 has that ability and Git doesn't provide it.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"544152","messageId":"20260527105639.GK981444@coredump.intra.peff.net","threadId":"65674","inReplyTo":"CAD6AYr9YmcnkdW=Nx=HUKcuaNbv1ukrAbXRnKyGibCQDy8N3hQ@mail.gmail.com","subject":"git-maintenance detach timing, was Re: I discovered a minor issue with `git fetch`.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-05-27T10:56:39Z","receivedAt":"2026-05-27T10:56:40Z","isPatch":false,"body":"On Fri, May 22, 2026 at 03:45:25PM +0800, SURA wrote:\n\n> A zombie process has appeared. It appears to originate from a `fetch`\n> subprocess that terminates very quickly; despite several attempts, I\n> have been unable to successfully capture it.\n> \n> This issue was discovered within a legacy service. A few days after\n> upgrading to Git 2.53.0, the system's PID resources were exhausted by\n> zombie processes. This is likely the result of recent changes, as this\n> problem did not exist in earlier versions (2.4x).\n> \n> To be honest, this is not an urgent matter; I have already deployed\n> `tini` as the init process (PID 1) to prevent the service from\n> becoming unavailable.\n\nYeah, I agree that you need some kind of zombie-reaping init process.\nBut I did wonder if we might have started generating more zombies here.\n\nI did a little poking around with \"strace -p 1\". I didn't see extra\nfetch processes, but I did see a lot of zombie git-maintenance processes\ngetting reaped. Which makes sense; by default we run background\nmaintenance with --detach. We can't ever reap that ourselves, since the\nwhole point is that it might outlive the parent fetch.\n\nOnce upon a time, we used to run \"git gc --auto\", and it would check\nwhether gc was needed (using a simple count of objects and packs) before\ndetaching. So in most cases it would realize there was nothing to be\ndone and exit immediately without daemonizing, and would get reaped by\ngit-fetch.\n\nWe switched to running \"git maintenance\" in v2.29. But it didn't yet\nhave a detached mode; it just run \"git gc --detach\" under the hood, so\nthe behavior was roughly the same (gc was reaped by maintenance which\nwas reaped by fetch).\n\nLater, git-maintenance learned its own --detach flag, as of v2.47. But\nunlike gc, it detaches immediately, and then each sub-task decides if it\nneeds to be run or not. So every \"git fetch\" will generate a detached\nmaintenance process that then gets reaped by init.\n\nAnd if you moved from a pre-v2.47 version, then you'd see an increase in\nsuch processes.\n\nI think this is probably OK in practice. It is an extra fork that git-gc\nnever incurred, but as long as you have a functioning init process, they\nwon't accumulate.\n\nI do wonder if git-maintenance could be more like git-gc here. Its\nnotion of tasks is more abstract, but it could in theory ask each task\n\"do you need to run?\" and if they all say \"no\", then it can quit without\ndetaching. That would save an extra fork() for every noop\nauto-maintenance call. I don't know how measurable that is in practice.\nOr even how easy it is for each task to do such a check. Something like\n\"prefetch\" is kind of all-or-nothing; you find out whether it needs\ndoing by doing it.\n\n-Peff\n"}]}