You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Possible race when parallel hooks read HookContext input #881
Hi! I ran into a strange pre-push behavior while debugging a custom hook, and I think it comes down to a small race in HookContext::Base#input_string.
Right now it memoizes stdin like this:
definput_string@input_string ||= @input.readend
Since hooks are parallelized by default, two hooks that share the same context can call this at the same time. For hook types that get real data on stdin, like pre-push, that means both threads may try to read the same input stream.
The failure mode is subtle:
one thread reads the actual Git pre-push refs
another thread reads EOF and gets ""
if the empty read is assigned last, @input_string stays cached as ""
So if the empty string wins the race, helpers like pushed_refs can return an empty list even though Git did send refs. In my case this made a pre-push check silently skip the work it was supposed to do.
I think the fix can be pretty small: protect the first read with a mutex, so the stream is only consumed once and every hook gets the same cached input.
I also put together a test that avoids relying on flaky timing: it uses a fake input object that blocks the first read, starts a second thread, and fails if the underlying input gets read more than once.
Focused spec, RuboCop, and bundle exec overcommit --run pass locally. The full spec suite has a few unrelated failures around git alias amendment detection on my machine.
Activity
Make hook context input reads thread-safe
Make hook context input reads thread-safe (#882)
sds commentedon Jun 10, 2026
Thanks for the fix in #882!