Skip to content

Commit cde15d5

Browse files
committed
Fix delay with flicking through files or commits when git diff is very slow
One reason why git diff can be very slow is when "diff.algorithm = histogram" is being used. In this case, showing a very long single-file diff can take seconds to load, and you'll see the "loading..." message in the main view until we got the first lines of the diff to show. There's nothing really we can do about this delay; however, when switching to another, shorter file (or commit) while the "loading..." message is still showing, this switch should be instantaneous. And it was before 0.54.0, but we broke this in 0.54.0 with 8d7740a (#4782); now users have to wait for the slow git diff command to output more text before the switch occurs. Fix this by sending the git process a TERM signal. Unfortunately, this signal is not supported on Windows, so Windows users will still have to live with the delay for now. The recommended workaround is to not use "diff.algorithm = histogram".
1 parent f9ff55a commit cde15d5

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

pkg/commands/oscommands/os_default_platform.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ package oscommands
55

66
import (
77
"os"
8+
"os/exec"
89
"runtime"
910
"strings"
11+
"syscall"
1012
)
1113

1214
func GetPlatform() *Platform {
@@ -38,3 +40,11 @@ func getUserShell() string {
3840
func (c *OSCommand) UpdateWindowTitle() error {
3941
return nil
4042
}
43+
44+
func TerminateProcessGracefully(cmd *exec.Cmd) error {
45+
if cmd.Process == nil {
46+
return nil
47+
}
48+
49+
return cmd.Process.Signal(syscall.SIGTERM)
50+
}

pkg/commands/oscommands/os_windows.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package oscommands
33
import (
44
"fmt"
55
"os"
6+
"os/exec"
67
"path/filepath"
78
)
89

@@ -22,3 +23,8 @@ func (c *OSCommand) UpdateWindowTitle() error {
2223
argString := fmt.Sprint("title ", filepath.Base(path), " - Lazygit")
2324
return c.Cmd.NewShell(argString, c.UserConfig().OS.ShellFunctionsFile).Run()
2425
}
26+
27+
func TerminateProcessGracefully(cmd *exec.Cmd) error {
28+
// Signals other than SIGKILL are not supported on Windows
29+
return nil
30+
}

pkg/tasks/tasks.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"time"
1010

1111
"github.com/jesseduffield/gocui"
12+
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
1213
"github.com/jesseduffield/lazygit/pkg/utils"
1314
"github.com/sasha-s/go-deadlock"
1415
"github.com/sirupsen/logrus"
@@ -165,7 +166,22 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p
165166
// and the user is flicking through a bunch of items.
166167
self.throttle = time.Since(startTime) < THROTTLE_TIME && timeToStart > COMMAND_START_THRESHOLD
167168

168-
// close the task's stdout pipe (or the pty if we're using one) to make the command terminate
169+
// Kill the still-running command. We only need to do this for the case that the git
170+
// command is not yet done producing the initial part of the output; this can happen
171+
// for very long diffs when diff.algorithm = histogram is being used. In this case,
172+
// closing the output pipe will cause the git command to terminate only the next
173+
// time it tries to output something, which might still take a while. But we want to
174+
// kill it immediately, so that we can show the next thing the user selected without
175+
// delay.
176+
//
177+
// Unfortunately this will do nothing on Windows, so we'll have to live with the
178+
// delay there.
179+
if err := oscommands.TerminateProcessGracefully(cmd); err != nil {
180+
self.Log.Errorf("error when trying to terminate cmd task: %v; Command: %v %v", err, cmd.Path, cmd.Args)
181+
}
182+
183+
// close the task's stdout pipe (or the pty if we're using one) to make the command
184+
// terminate on Windows, and so that the Wait call below doesn't block.
169185
onDone()
170186
}
171187
})

0 commit comments

Comments
 (0)