jesseduffield.lazygit/pkg/commands/oscommands
Stefan Haller d2a1a4f2a2 Start all commands of a pipeline before waiting for any of them
PipeCommands ran every command in its own goroutine, each doing
Start/read-stderr/Wait, with nothing ordering one goroutine's Start
against another's Wait. That ordering matters: StdoutPipe registers the
parent's read end in cmd.parentIOPipes, and Cmd.Wait closes those
descriptors when it returns. The next command's Stdin is that very
*os.File, and exec passes a user-supplied *os.File through untouched, so
Start hands the child whatever the fd happens to be at that moment. If
the producer finished and got reaped before the consumer's goroutine
reached Start, that fd was already closed, File.Fd() returned -1, and
the child was started with fd 0 closed -- reading nothing at all.

The only caller is the pre-2.35 fallback in SaveStagedChanges, which
pipes `git stash show -p` into `git apply -R`. Losing that race left
git apply with an empty patch, so it failed with "unrecognized input",
the following `git stash drop` never ran, and the user was left with a
stray stash entry. This turned up as a flaky stash/stash_staged on the
git 2.32.0 CI job; the newer-git jobs take the `git stash push --staged`
path and never reach this code.

Starting every command up front removes the race, and collecting stderr
into buffers lets exec's own copying goroutines do the work. That also
fixes two lesser problems in the same function: finalErrors was appended
to from several goroutines without synchronization, and a failed Start
was only logged, so a pipeline that never ran reported success.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 14:34:47 +02:00
..
cmd_obj.go Use ConPTY on Windows for pty-backed command execution 2026-07-03 18:47:15 +02:00
cmd_obj_builder.go Fix quoting of shell commands on Windows 2026-06-23 14:11:00 +02:00
cmd_obj_runner.go Wait for the streamed command's output goroutine before reading its buffers 2026-07-17 12:19:14 +02:00
cmd_obj_runner_test.go Copy gocui files into lazygit repo under pkg/gocui 2026-04-30 14:29:08 +02:00
cmd_obj_test.go Suppress optional locks by default again, except foreground refresh 2026-07-02 16:05:08 +02:00
copy.go Specify return value where named return value is used 2025-10-20 07:56:56 +02:00
dummies.go Remove empty directories after discarding files 2026-03-30 17:50:28 +02:00
fake_cmd_obj_runner.go Remove ICmdObj interface 2025-05-01 15:21:37 +02:00
gui_io.go Use first class task objects instead of global counter 2023-07-09 21:30:19 +10:00
new_shell_windows_test.go Add end-to-end test for shell command quoting on Windows 2026-06-23 14:11:00 +02:00
os.go Start all commands of a pipeline before waiting for any of them 2026-08-06 14:34:47 +02:00
os_default_platform.go Abstract task command over *exec.Cmd 2026-07-03 18:47:15 +02:00
os_default_test.go Clean up build tags 2025-08-14 20:40:44 +02:00
os_test.go Fix quoting of shell commands on Windows 2026-06-23 14:11:00 +02:00
os_windows.go Abstract task command over *exec.Cmd 2026-07-03 18:47:15 +02:00
os_windows_test.go Fix quoting of shell commands on Windows 2026-06-23 14:11:00 +02:00
pty.go Add pty support on Windows via ConPTY 2026-07-03 18:47:15 +02:00
pty_unix.go Reap pty process trees synchronously when quitting on Windows (#5879) 2026-08-04 07:03:27 +02:00
pty_windows.go Reap pty process trees synchronously when quitting on Windows (#5879) 2026-08-04 07:03:27 +02:00
pty_windows_test.go Reap pty process trees synchronously when quitting on Windows (#5879) 2026-08-04 07:03:27 +02:00