Skip to content

Commit 2a1fb18

Browse files
committed
Improve CPU usage when flicking through large diffs
The previous commit already fixed the user-visible lag, but there's still a problem with multiple background git processes consuming resources calculating diffs that we are never going to show. Improve this by terminating those processes (by sending them a TERM signal). Unfortunately this is only possible on Linux and Mac, so Windows users will have to live with the higher CPU usage. The recommended workaround is to not use "diff.algorithm = histogram".
1 parent c2f95be commit 2a1fb18

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
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: 12 additions & 0 deletions
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,6 +166,17 @@ 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

169+
// Kill the still-running command. The only reason to do this is to save CPU usage
170+
// when flicking through several very long diffs when diff.algorithm = histogram is
171+
// being used, in which case multiple git processes continue to calculate expensive
172+
// diffs in the background even though they have been stopped already.
173+
//
174+
// Unfortunately this will do nothing on Windows, so Windows users will have to live
175+
// with the higher CPU usage.
176+
if err := oscommands.TerminateProcessGracefully(cmd); err != nil {
177+
self.Log.Errorf("error when trying to terminate cmd task: %v; Command: %v %v", err, cmd.Path, cmd.Args)
178+
}
179+
168180
// close the task's stdout pipe (or the pty if we're using one) to make the command terminate
169181
onDone()
170182
}

0 commit comments

Comments
 (0)