[BUG] Windows: timed-out git status leaves orphaned git.exe processes that pile up until memory is exhausted
Summary
On Windows, the git status that Claude Code runs in the working directory is aborted after about 2 seconds, but only the Git for Windows launcher (C:\Program Files\Git\cmd\git.exe) is terminated. The real C:\Program Files\Git\mingw64\bin\git.exe that the launcher started keeps running. In a large repository a new one is started every few seconds, so these orphaned git.exe processes pile up until the machine runs out of memory.
Environment
- Claude Code 2.1.281, launched from the Claude desktop app (Code tab)
- Windows 11 Home 10.0.26200
- Git for Windows 2.54.0.windows.1;
C:\Program Files\Git\cmdis on the system PATH, sogitresolves to the launcher - Repository with about 190,000 tracked files on an HDD
What happens
While a session runs Bash tool calls, Claude Code repeatedly starts:
git -c core.askPass= -c protocol.ext.allow=never -c submodule.recurse=false -c log.showSignature=false -c gc.auto=0 -c maintenance.auto=false -c core.hooksPath=\\.\NUL -c core.fsmonitor= -c safe.bareRepository=explicit -c protocol.file.allow=never --no-optional-locks status --porcelain --ignore-submodules=dirty --untracked-files=normal
The process tree is claude.exe -> C:\Program Files\Git\cmd\git.exe -> C:\Program Files\Git\mingw64\bin\git.exe. When the ~2 s limit is reached, the launcher is terminated, but Windows does not terminate child processes along with their parent, so the real git.exe keeps scanning the working tree.
In this repository git status takes about 2 s with a warm file-system cache and 476 s with a cold one. One claude.exe started 5 of these in about 33 seconds. Each orphan uses 230-280 MB, so they accumulated until memory use reached 98%. That evicts the file-system cache, which makes every following git status slower still: a feedback loop.
Evidence
- Sampling every 250 ms while one
claude.exeran five consecutivegit statusin this repository: each time the launcher disappeared 1.8-1.9 s after it started, while its child was still running 7-16 s later, when the watchdog below terminated it.
start pid parent executable observed alive
12:14:47.52 8400 8532 (claude.exe) cmd\git.exe 1.9 s
12:14:47.56 17744 8400 (launcher) mingw64\bin\git.exe 10.0 s
12:14:51.79 7280 8532 (claude.exe) cmd\git.exe 1.8 s
12:14:51.82 12884 7280 (launcher) mingw64\bin\git.exe 16.0 s
12:15:06.22 20052 8532 (claude.exe) cmd\git.exe 1.9 s
12:15:06.26 13920 20052 (launcher) mingw64\bin\git.exe 13.8 s
12:15:11.69 9128 8532 (claude.exe) cmd\git.exe 1.8 s
12:15:11.72 7228 9128 (launcher) mingw64\bin\git.exe 8.3 s
12:15:21.10 8556 8532 (claude.exe) cmd\git.exe 1.8 s
12:15:21.13 34436 8556 (launcher) mingw64\bin\git.exe 7.3 s
- A watchdog that terminates
git.exeprocesses with the command line above once they are older than 5 seconds terminated 55 of them in one hour. None of their parent process IDs belonged to a runningclaude.exe, i.e. every process still alive after 5 seconds was a child whose launcher had already been terminated.
Expected behavior
- When the time limit is reached, terminate the whole process tree (for example
taskkill /T /F, or start the child inside a Job Object withJOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE), or resolve and startmingw64\bin\git.exedirectly on Windows. - Do not start another
git statusfor the same repository while the previous one is still running, and back off for a while after one has timed out.
Workaround
A background watchdog that terminates git.exe processes with the command line above once they are older than 5 seconds.
Related
#48398 (closed as a duplicate of #41742) mentions zombie git processes on Windows, but neither issue describes this mechanism.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗