Skip to content

Make git timeouts kill a hung git - #84

Merged
rocketraman merged 2 commits into
masterfrom
claude/gitvantage-git-timeout
Nov 4, 2026
Merged

rocketraman merged 2 commits into
masterfrom
claude/gitvantage-git-timeout

Conversation

@rocketraman

@rocketraman rocketraman commented Nov 4, 2026 •

Copy link
Copy Markdown
Owner

git timeouts never fired. spawnNow read stdout to EOF and only then called waitFor(timeout), so a git that hangs, and never closes stdout, blocks forever. dave08's 1.5.0 log shows a git fetch that ran for 2h 11m against its 90s NETWORK_TIMEOUT. Some of that may be the Mac sleeping, but nothing in the code could have stopped it. Every version is affected.

Change

  • A timeout coroutine starts next to the read, under one runBlocking parent. When the timeout passes, it kills git and all of git's child processes. If the read finishes first, the coroutine is cancelled. It runs on Dispatchers.Default, because runBlocking's own thread is blocked in the read.
  • Child processes are listed and killed before git itself. Once git dies its children are reparented, and they would keep the pipe open with nothing left to find them. A fetch's ssh and the shell behind an alias both hold git's stdout.
  • Reads still happen on the calling thread, and git commands still run in parallel.
  • A timed-out call still returns Result(-1, out, "timed out"), as before.

Testing

  • New GitTimeout suite:
    • a !sleep 60 alias with a 1s timeout now returns failure in about 1s; before the fix it would have blocked for the full 60s;
    • a normal command is unaffected.
  • Unit tests 291/291, Konture 10/10, detekt clean.

The timeout was a waitFor() after reading stdout to EOF, which a hung git
never reaches, so no timeout ever fired. A field report had a fetch
running for 2h 11m against its 90s limit.

A shared reaper thread now kills git and its descendants when time runs
out. The descendants matter: a fetch's ssh, or the shell behind an alias,
holds the same stdout, so killing git alone would leave the read waiting.

Signed-off-by: Raman Gupta <rocketraman@gmail.com>
@rocketraman
rocketraman force-pushed the claude/gitvantage-git-timeout branch from 07a7502 to 248bfa3 Compare November 4, 2026 15:14
A timeout coroutine started next to the read, under one runBlocking
parent, and cancelled when the read finishes, says what the shared
reaper executor did in less code.

Signed-off-by: Raman Gupta <rocketraman@gmail.com>
@rocketraman
rocketraman merged commit 487a747 into master Nov 4, 2026
2 checks passed
@rocketraman
rocketraman deleted the claude/gitvantage-git-timeout branch November 4, 2026 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant