diff --git a/pkg/commands/git_commands/branch_loader.go b/pkg/commands/git_commands/branch_loader.go index a4e41b756..a921f1885 100644 --- a/pkg/commands/git_commands/branch_loader.go +++ b/pkg/commands/git_commands/branch_loader.go @@ -176,7 +176,7 @@ func (self *BranchLoader) GetBehindBaseBranchValuesForAllBranches( Arg("--count"). Arg(fmt.Sprintf("%s...%s", branch.FullRefName(), baseBranch)). ToArgv(), - ).DontLog().RunWithOutput() + ).DontLog().SuppressLogHack().RunWithOutput() if err != nil { return err } @@ -220,7 +220,7 @@ func (self *BranchLoader) GetBaseBranch(branch *models.Branch, mainBranches *Mai Arg("--format=%(refname)"). Arg(mainBranches.Get()...). ToArgv(), - ).DontLog().RunWithOutput() + ).DontLog().SuppressLogHack().RunWithOutput() if err != nil { return "", err } diff --git a/pkg/commands/git_commands/main_branches.go b/pkg/commands/git_commands/main_branches.go index 19f809a4f..4f670ff5a 100644 --- a/pkg/commands/git_commands/main_branches.go +++ b/pkg/commands/git_commands/main_branches.go @@ -71,7 +71,7 @@ func (self *MainBranches) GetMergeBase(refName string) string { output, _ := self.cmd.New( NewGitCmd("merge-base").Arg(refName).Arg(mainBranches...). ToArgv(), - ).DontLog().RunWithOutput() + ).DontLog().SuppressLogHack().RunWithOutput() return ignoringWarnings(output) } diff --git a/pkg/commands/oscommands/cmd_obj.go b/pkg/commands/oscommands/cmd_obj.go index 96392dcb4..d1eef673b 100644 --- a/pkg/commands/oscommands/cmd_obj.go +++ b/pkg/commands/oscommands/cmd_obj.go @@ -19,6 +19,8 @@ type CmdObj struct { // see DontLog() dontLog bool + LogHackSuppressed bool + // see StreamOutput() streamOutput bool @@ -111,6 +113,11 @@ func (self *CmdObj) DontLog() *CmdObj { return self } +func (self *CmdObj) SuppressLogHack() *CmdObj { + self.LogHackSuppressed = true + return self +} + // This returns false if DontLog() was called func (self *CmdObj) ShouldLog() bool { return !self.dontLog diff --git a/pkg/commands/oscommands/cmd_obj_runner.go b/pkg/commands/oscommands/cmd_obj_runner.go index 824ce6d52..5930c39aa 100644 --- a/pkg/commands/oscommands/cmd_obj_runner.go +++ b/pkg/commands/oscommands/cmd_obj_runner.go @@ -3,7 +3,9 @@ package oscommands import ( "bufio" "bytes" + "fmt" "io" + "os" "os/exec" "regexp" "strings" @@ -29,6 +31,16 @@ type cmdObjRunner struct { var _ ICmdObjRunner = &cmdObjRunner{} +func LogCmd(message string) { + f, err := os.OpenFile("/tmp/git.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o644) + if err != nil { + return + } + timestamp := time.Now().Format(time.DateTime) + _, _ = f.WriteString(fmt.Sprintf("%s: # lazygit # %s\n", timestamp, message)) + _ = f.Close() +} + func (self *cmdObjRunner) Run(cmdObj *CmdObj) error { if cmdObj.Mutex() != nil { cmdObj.Mutex().Lock() @@ -105,7 +117,13 @@ func (self *cmdObjRunner) RunWithOutputAux(cmdObj *CmdObj) (string, error) { } t := time.Now() + if !cmdObj.LogHackSuppressed { + LogCmd(fmt.Sprintf("Starting cmd: %s", cmdObj.ToString())) + } output, err := sanitisedCommandOutput(cmdObj.GetCmd().CombinedOutput()) + if !cmdObj.LogHackSuppressed { + LogCmd(fmt.Sprintf("Done running cmd: %s, pid: %d", cmdObj.ToString(), cmdObj.GetCmd().Process.Pid)) + } if err != nil { self.log.WithField("command", cmdObj.ToString()).Error(output) } @@ -127,7 +145,13 @@ func (self *cmdObjRunner) RunWithOutputsAux(cmdObj *CmdObj) (string, string, err cmd := cmdObj.GetCmd() cmd.Stdout = &outBuffer cmd.Stderr = &errBuffer + if !cmdObj.LogHackSuppressed { + LogCmd(fmt.Sprintf("Starting cmd: %s", cmdObj.ToString())) + } err := cmd.Run() + if !cmdObj.LogHackSuppressed { + LogCmd(fmt.Sprintf("Done running cmd: %s, pid: %d", cmdObj.ToString(), cmdObj.GetCmd().Process.Pid)) + } self.log.Infof("%s (%s)", cmdObj.ToString(), time.Since(t)) @@ -167,6 +191,10 @@ func (self *cmdObjRunner) RunAndProcessLines(cmdObj *CmdObj, onLine func(line st return err } + if !cmdObj.LogHackSuppressed { + LogCmd(fmt.Sprintf("Started cmd: %s, pid: %d", cmdObj.ToString(), cmdObj.GetCmd().Process.Pid)) + } + for scanner.Scan() { line := scanner.Text() stop, err := onLine(line) @@ -174,18 +202,24 @@ func (self *cmdObjRunner) RunAndProcessLines(cmdObj *CmdObj, onLine func(line st return err } if stop { + LogCmd(fmt.Sprintf("Killing cmd pid: %d", cmdObj.GetCmd().Process.Pid)) _ = Kill(cmd) break } } if scanner.Err() != nil { + LogCmd(fmt.Sprintf("Scanner failed, killing cmd pid: %d", cmdObj.GetCmd().Process.Pid)) _ = Kill(cmd) return scanner.Err() } _ = cmd.Wait() + if !cmdObj.LogHackSuppressed { + LogCmd(fmt.Sprintf("Done running cmd: %s, pid: %d", cmdObj.ToString(), cmdObj.GetCmd().Process.Pid)) + } + self.log.Infof("%s (%s)", cmdObj.ToString(), time.Since(t)) return nil @@ -361,6 +395,8 @@ func (self *cmdObjRunner) processOutput( // Note that we don't break the loop after this, because we // still need to drain the output, otherwise the Wait() call // later might block. + + LogCmd(fmt.Sprintf("Killing cmd pid: %d", cmdObj.GetCmd().Process.Pid)) if err := Kill(cmdObj.GetCmd()); err != nil { self.log.Error(err) } @@ -454,6 +490,8 @@ func (self *cmdObjRunner) getCmdHandlerNonPty(cmd *exec.Cmd) (*cmdHandler, error return nil, err } + LogCmd(fmt.Sprintf("Started cmd: %s, pid: %d", cmd.Args, cmd.Process.Pid)) + return &cmdHandler{ stdoutPipe: stdoutReader, stdinPipe: buf, diff --git a/pkg/commands/oscommands/cmd_obj_runner_default.go b/pkg/commands/oscommands/cmd_obj_runner_default.go index 891b4c4ee..ea227c721 100644 --- a/pkg/commands/oscommands/cmd_obj_runner_default.go +++ b/pkg/commands/oscommands/cmd_obj_runner_default.go @@ -4,6 +4,7 @@ package oscommands import ( + "fmt" "os/exec" "github.com/creack/pty" @@ -17,6 +18,8 @@ func (self *cmdObjRunner) getCmdHandlerPty(cmd *exec.Cmd) (*cmdHandler, error) { return nil, err } + LogCmd(fmt.Sprintf("Started cmd: %s, pid: %d", cmd.Args, cmd.Process.Pid)) + return &cmdHandler{ stdoutPipe: ptmx, stdinPipe: ptmx, diff --git a/pkg/gui/pty.go b/pkg/gui/pty.go index 84c9e6da8..f418fe0ed 100644 --- a/pkg/gui/pty.go +++ b/pkg/gui/pty.go @@ -4,6 +4,7 @@ package gui import ( + "fmt" "io" "os" "os/exec" @@ -11,6 +12,7 @@ import ( "github.com/creack/pty" "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" ) @@ -82,6 +84,8 @@ func (gui *Gui) newPtyTask(view *gocui.View, cmd *exec.Cmd, prefix string) error gui.c.Log.Error(err) } + oscommands.LogCmd(fmt.Sprintf("Started cmd: %s, pid: %d", cmd.Args, cmd.Process.Pid)) + gui.Mutexes.PtyMutex.Lock() gui.viewPtmxMap[view.Name()] = ptmx gui.Mutexes.PtyMutex.Unlock() diff --git a/pkg/gui/tasks_adapter.go b/pkg/gui/tasks_adapter.go index 545c45471..e9f3c3310 100644 --- a/pkg/gui/tasks_adapter.go +++ b/pkg/gui/tasks_adapter.go @@ -1,11 +1,13 @@ package gui import ( + "fmt" "io" "os/exec" "strings" "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/tasks" ) @@ -29,6 +31,8 @@ func (gui *Gui) newCmdTask(view *gocui.View, cmd *exec.Cmd, prefix string) error gui.c.Log.Error(err) } + oscommands.LogCmd(fmt.Sprintf("Started cmd: %s, pid: %d", cmd.Args, cmd.Process.Pid)) + return cmd, r } diff --git a/pkg/tasks/tasks.go b/pkg/tasks/tasks.go index 5de7fb232..390546a62 100644 --- a/pkg/tasks/tasks.go +++ b/pkg/tasks/tasks.go @@ -168,6 +168,7 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p self.throttle = time.Since(startTime) < THROTTLE_TIME && timeToStart > COMMAND_START_THRESHOLD // Kill the still-running command. + oscommands.LogCmd(fmt.Sprintf("Killing cmd pid: %d", cmd.Process.Pid)) if err := oscommands.Kill(cmd); err != nil { if !strings.Contains(err.Error(), "process already finished") { self.Log.Errorf("error when trying to kill cmd task: %v; Command: %v %v", err, cmd.Path, cmd.Args) @@ -307,6 +308,8 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p default: self.Log.Errorf("Unexpected error when running cmd task: %v; Failed command: %v %v", err, cmd.Path, cmd.Args) } + } else { + oscommands.LogCmd(fmt.Sprintf("Done running cmd pid: %d", cmd.Process.Pid)) } // calling this here again in case the program ended on its own accord