diff --git a/pkg/commands/oscommands/pty_windows.go b/pkg/commands/oscommands/pty_windows.go index ff707c519..b36342e61 100644 --- a/pkg/commands/oscommands/pty_windows.go +++ b/pkg/commands/oscommands/pty_windows.go @@ -144,9 +144,7 @@ func TerminateLivePtys() { // graceful signal worth waiting on — git and the common diff tools leave it // to the default handler, which calls ExitProcess at whatever instruction // the process happens to execute — so clients that got the event are -// already dying. Killing at an arbitrary point cannot leak a stale -// index.lock, because pty-rendered commands don't take that lock (see -// withPtyGitConfig in pkg/gui/pty.go). +// already dying. // // The pseudoconsole close gets its own goroutine because the kill must not // wait for it: on builds where ClosePseudoConsole blocks until the console diff --git a/pkg/gui/main_view_render.go b/pkg/gui/main_view_render.go index 1a6eb459a..bfeba9b16 100644 --- a/pkg/gui/main_view_render.go +++ b/pkg/gui/main_view_render.go @@ -40,8 +40,6 @@ func (gui *Gui) newRenderTask(view *gocui.View, cmd *exec.Cmd, prefix string) er return gui.newCmdTask(view, cmd, prefix) } - cmd.Args = withPtyGitConfig(cmd.Args, runtime.GOOS) - // Mark the view as loading synchronously now, before the layout pass: the // actual task is created in afterLayout (below), which runs after layout, so // without this the next layout pass would clamp the scroll position to the diff --git a/pkg/gui/pty.go b/pkg/gui/pty.go index 0cb718d8c..c53b77a21 100644 --- a/pkg/gui/pty.go +++ b/pkg/gui/pty.go @@ -4,8 +4,6 @@ import ( "io" "os" "os/exec" - "path/filepath" - "strings" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/gocui" @@ -107,40 +105,3 @@ func (gui *Gui) ptyRender(spec renderSpec) (startRender, onCloseRender) { return start, onClose } - -// withPtyGitConfig returns args with extra git configuration for commands -// that render into a pty. On Windows, such a command is terminated at an -// arbitrary point of its execution when its task stops: tearing down the -// pseudoconsole delivers CTRL_CLOSE_EVENT, which git leaves to the default -// handler, which just calls ExitProcess. git's automatic index refresh -// (diff.autoRefreshIndex, on by default) takes index.lock at the end of a -// diff against the worktree to write back refreshed stat information — -// GIT_OPTIONAL_LOCKS does not cover this lock — and a termination landing -// in that window leaves a stale index.lock behind that the next git command -// chokes on. So don't let pty-rendered commands refresh the index; -// lazygit's foreground `git status` refreshes, which never run in a pty, -// keep the stat cache fresh instead. -// -// On Unix a stopped pty child gets SIGTERM, and git's signal handlers remove -// its lock files, so the refresh can stay enabled there and keep healing -// stale stat info. -func withPtyGitConfig(args []string, goos string) []string { - if goos != "windows" { - return args - } - // Most pty commands are direct git invocations, but the user-configured - // ones can be arbitrary command lines (e.g. a branchLogCmd wrapping git - // in `sh -c`), and injecting git flags into those would corrupt them. - // Only direct git invocations get the config; that loses nothing, since - // the wrapped commands are log commands, which never take the index - // lock. (For direct invocations other than worktree diffs the config is - // simply a no-op.) - base := strings.TrimSuffix(strings.ToLower(filepath.Base(args[0])), ".exe") - if base != "git" { - return args - } - result := make([]string, 0, len(args)+2) - result = append(result, args[0]) - result = append(result, "-c", "diff.autoRefreshIndex=false") - return append(result, args[1:]...) -} diff --git a/pkg/gui/pty_test.go b/pkg/gui/pty_test.go deleted file mode 100644 index 8d7f0e2ca..000000000 --- a/pkg/gui/pty_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package gui - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestWithPtyGitConfig(t *testing.T) { - args := []string{"git", "-C", "/repo", "diff", "--color=always"} - - assert.Equal(t, - []string{"git", "-c", "diff.autoRefreshIndex=false", "-C", "/repo", "diff", "--color=always"}, - withPtyGitConfig(args, "windows")) - - assert.Equal(t, args, withPtyGitConfig(args, "linux")) - assert.Equal(t, args, withPtyGitConfig(args, "darwin")) - - // A user-configured command that wraps git in a shell must not have git - // flags injected into it. - shellArgs := []string{"sh", "-c", "git log --graph {{branchName}} -- | sed -e s/x/y/"} - assert.Equal(t, shellArgs, withPtyGitConfig(shellArgs, "windows")) - - // The guard recognizes git regardless of case and extension. - exeArgs := []string{"GIT.EXE", "diff"} - assert.Equal(t, - []string{"GIT.EXE", "-c", "diff.autoRefreshIndex=false", "diff"}, - withPtyGitConfig(exeArgs, "windows")) -}