Skip to content

ref: Handle SIGPIPE when truncating output from git-for-each-ref(1)

The FindLocalBranches RPC allows the user to specify a limit of how many references should be returned. Ideally, we would be able to pass this limit to git-for-each-ref(1) itself. But because we also support passing an offset that needs to be found at runtime, this is not easily done.

Instead, we're simply aborting the sender loop once we have reached the limit and then wait for git-for-each-ref(1) to exit. Before 065ad266 (command: Reliably propagate read errors on context cancellation, 2023-09-11), this used to be quite inefficient because we would not kill the process, but wait for it to have iterated over all branches while discarding all its output.

With that commit though we have changed the semantics such that the pipe that we pass as stdout to the child process doesn't get drained anymore but closed instead. This has the side effect that we now indeed abort a lot earlier, which should lead to a significant speedup with many local branches. But it has the downside that the process may now die due to it receiving SIGPIPE.

The change in the mentioned commit arguably still makes sense, as it caused us to detect a new case where things don't quite behave the way we thought they do. So instead of reverting the original change, let's simply handle SIGPIPE gracefully in FindLocalBranches.

A quick check for other patterns where we might run into the same issues didn't surface anything.

Merge request reports