diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2022-01-05 12:01:59 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2022-01-07 10:52:51 +1100 |
commit | 91fe68576cde3e4582373b255c5eb97cd3065c71 (patch) | |
tree | dce5212c30f0a1b01cc96e7ee10307c80578e7f4 /pkg | |
parent | bbb5eee23a62162d2695a27f923e1a543852742a (diff) |
refactor
Diffstat (limited to 'pkg')
37 files changed, 226 insertions, 253 deletions
diff --git a/pkg/commands/oscommands/cmd_obj.go b/pkg/commands/oscommands/cmd_obj.go index 192871af0..8fb7fa313 100644 --- a/pkg/commands/oscommands/cmd_obj.go +++ b/pkg/commands/oscommands/cmd_obj.go @@ -12,6 +12,7 @@ type ICmdObj interface { // using NewFromArgs, the output won't be quite the same as what you would type // into a terminal e.g. 'sh -c git commit' as opposed to 'sh -c "git commit"' ToString() string + AddEnvVars(...string) ICmdObj GetEnvVars() []string @@ -22,9 +23,16 @@ type ICmdObj interface { // runs the command and runs a callback function on each line of the output. If the callback returns true for the boolean value, we kill the process and return. RunAndProcessLines(onLine func(line string) (bool, error)) error - // Marks the command object as readonly, so that when it is run, we don't log it to the user. - // We only want to log commands to the user which change state in some way. + // Be calling DontLog(), we're saying that once we call Run(), we don't want to + // log the command in the UI (it'll still be logged in the log file). The general rule + // is that if a command doesn't change the git state (e.g. read commands like `git diff`) + // then we don't want to log it. If we are changing something (e.g. `git add .`) then + // we do. The only exception is if we're running a command in the background periodically + // like `git fetch`, which technically does mutate stuff but isn't something we need + // to notify the user about. DontLog() ICmdObj + + // This returns false if DontLog() was called ShouldLog() bool } diff --git a/pkg/commands/oscommands/cmd_obj_builder.go b/pkg/commands/oscommands/cmd_obj_builder.go index 5929d6faf..a493ae651 100644 --- a/pkg/commands/oscommands/cmd_obj_builder.go +++ b/pkg/commands/oscommands/cmd_obj_builder.go @@ -21,9 +21,8 @@ type ICmdObjBuilder interface { } type CmdObjBuilder struct { - runner ICmdObjRunner - logCmdObj func(ICmdObj) - platform *Platform + runner ICmdObjRunner + platform *Platform } // poor man's version of explicitly saying that struct X implements interface Y @@ -76,8 +75,27 @@ func (self *CmdObjBuilder) CloneWithNewRunner(decorate func(ICmdObjRunner) ICmdO decoratedRunner := decorate(self.runner) return &CmdObjBuilder{ - runner: decoratedRunner, - logCmdObj: self.logCmdObj, - platform: self.platform, + runner: decoratedRunner, + platform: self.platform, } } + +func (self *CmdObjBuilder) Quote(message string) string { + var quote string + if self.platform.OS == "windows" { + quote = `\"` + message = strings.NewReplacer( + `"`, `"'"'"`, + `\"`, `\\"`, + ).Replace(message) + } else { + quote = `"` + message = strings.NewReplacer( + `\`, `\\`, + `"`, `\"`, + `$`, `\$`, + "`", "\\`", + ).Replace(message) + } + return quote + message + quote +} diff --git a/pkg/commands/oscommands/cmd_obj_runner.go b/pkg/commands/oscommands/cmd_obj_runner.go index 0c6bf086e..8eb6d437d 100644 --- a/pkg/commands/oscommands/cmd_obj_runner.go +++ b/pkg/commands/oscommands/cmd_obj_runner.go @@ -22,10 +22,6 @@ type cmdObjRunner struct { var _ ICmdObjRunner = &cmdObjRunner{} func (self *cmdObjRunner) Run(cmdObj ICmdObj) error { - if cmdObj.ShouldLog() { - self.logCmdObj(cmdObj) - } - _, err := self.RunWithOutput(cmdObj) return err } diff --git a/pkg/commands/oscommands/dummies.go b/pkg/commands/oscommands/dummies.go index f44cc9b72..8a97589ed 100644 --- a/pkg/commands/oscommands/dummies.go +++ b/pkg/commands/oscommands/dummies.go @@ -13,9 +13,8 @@ func NewDummyOSCommand() *OSCommand { func NewDummyCmdObjBuilder(runner ICmdObjRunner) *CmdObjBuilder { return &CmdObjBuilder{ - runner: runner, - logCmdObj: func(ICmdObj) {}, - platform: dummyPlatform, + runner: runner, + platform: dummyPlatform, } } diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index 0d2a936ef..bf1bb9ac6 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -22,11 +22,11 @@ type OSCommand struct { Platform *Platform Getenv func(string) string - // callback to run before running a command, i.e. for the purposes of logging - onRunCommand func(CmdLogEntry) - - // something like 'Staging File': allows us to group cmd logs under a single title - CmdLogSpan string + // callback to run before running a command, i.e. for the purposes of logging. + // the string argument is the command string e.g. 'git add .' and the bool is + // whether we're dealing with a command line command or something more general + // like 'Opening PR URL', or something handled by Go's standard library. + logCommandFn func(string, bool) removeFile func(string) error @@ -42,36 +42,6 @@ type Platform struct { OpenLinkCommand string } -// TODO: make these fields private -type CmdLogEntry struct { - // e.g. 'git commit -m "haha"' - cmdStr string - // Span is something like 'Staging File'. Multiple commands can be grouped under the same - // span - span string - - // sometimes our command is direct like 'git commit', and sometimes it's a - // command to remove a file but through Go's standard library rather than the - // command line - commandLine bool -} - -func (e CmdLogEntry) GetCmdStr() string { - return e.cmdStr -} - -func (e CmdLogEntry) GetSpan() string { - return e.span -} - -func (e CmdLogEntry) GetCommandLine() bool { - return e.commandLine -} - -func NewCmdLogEntry(cmdStr string, span string, commandLine bool) CmdLogEntry { - return CmdLogEntry{cmdStr: cmdStr, span: span, commandLine: commandLine} -} - // NewOSCommand os command runner func NewOSCommand(common *common.Common, platform *Platform) *OSCommand { c := &OSCommand{ @@ -82,7 +52,7 @@ func NewOSCommand(common *common.Common, platform *Platform) *OSCommand { } runner := &cmdObjRunner{log: common.Log, logCmdObj: c.LogCmdObj} - c.Cmd = &CmdObjBuilder{runner: runner, logCmdObj: c.LogCmdObj, platform: platform} + c.Cmd = &CmdObjBuilder{runner: runner, platform: platform} return c } @@ -94,13 +64,13 @@ func (c *OSCommand) LogCmdObj(cmdObj ICmdObj) { func (c *OSCommand) LogCommand(cmdStr string, commandLine bool) { c.Log.WithField("command", cmdStr).Info("RunCommand") - if c.onRunCommand != nil { - c.onRunCommand(NewCmdLogEntry(cmdStr, c.CmdLogSpan, commandLine)) + if c.logCommandFn != nil { + c.logCommandFn(cmdStr, commandLine) } } -func (c *OSCommand) SetOnRunCommand(f func(CmdLogEntry)) { - c.onRunCommand = f +func (c *OSCommand) SetLogCommandFn(f func(string, bool)) { + c.logCommandFn = f } // To be used for testing only @@ -145,26 +115,6 @@ func (c *OSCommand) Quote(message string) string { return c.Cmd.Quote(message) } -func (self *CmdObjBuilder) Quote(message string) string { - var quote string - if self.platform.OS == "windows" { - quote = `\"` - message = strings.NewReplacer( - `"`, `"'"'"`, - `\"`, `\\"`, - ).Replace(message) - } else { - quote = `"` - message = strings.NewReplacer( - `\`, `\\`, - `"`, `\"`, - `$`, `\$`, - "`", "\\`", - ).Replace(message) - } - return quote + message + quote -} - // AppendLineToFile adds a new line in file func (c *OSCommand) AppendLineToFile(filename, line string) error { c.LogCommand(fmt.Sprintf("Appending '%s' to file '%s'", line, filename), false) @@ -236,15 +186,6 @@ func (c *OSCommand) FileExists(path string) (bool, error) { return true, nil } -// GetLazygitPath returns the path of the currently executed file -func (c *OSCommand) GetLazygitPath() string { - ex, err := os.Executable() // get the executable path for git to use - if err != nil { - ex = os.Args[0] // fallback to the first call argument if needed - } - return `"` + filepath.ToSlash(ex) + `"` -} - // PipeCommands runs a heap of commands and pipes their inputs/outputs together like A | B | C func (c *OSCommand) PipeCommands(commandStrings ...string) error { cmds := make([]*exec.Cmd, len(commandStrings)) @@ -333,3 +274,12 @@ func (c *OSCommand) RemoveFile(path string) error { func GetTempDir() string { return filepath.Join(os.TempDir(), "lazygit") } + +// GetLazygitPath returns the path of the currently executed file +func GetLazygitPath() string { + ex, err := os.Executable() // get the executable path for git to use + if err != nil { + ex = os.Args[0] // fallback to the first call argument if needed + } + return `"` + filepath.ToSlash(ex) + `"` +} diff --git a/pkg/commands/rebasing.go b/pkg/commands/rebasing.go index 8827246ab..b930604ea 100644 --- a/pkg/commands/rebasing.go +++ b/pkg/commands/rebasing.go @@ -59,7 +59,7 @@ func (c *GitCommand) InteractiveRebase(commits []*models.Commit, index int, acti // we tell git to run lazygit to edit the todo list, and we pass the client // lazygit a todo string to write to the todo file func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string, overrideEditor bool) (oscommands.ICmdObj, error) { - ex := c.OSCommand.GetLazygitPath() + ex := oscommands.GetLazygitPath() debug := "FALSE" if c.Debug { @@ -267,8 +267,8 @@ func (c *GitCommand) GenericMergeOrRebaseAction(commandType string, command stri } func (c *GitCommand) runSkipEditorCommand(command string) error { - cmdObj := c.OSCommand.Cmd.New(command) - lazyGitPath := c.OSCommand.GetLazygitPath() + cmdObj := c.Cmd.New(command) + lazyGitPath := oscommands.GetLazygitPath() return cmdObj. AddEnvVars( "LAZYGIT_CLIENT_COMMAND=EXIT_IMMEDIATELY", diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 313186256..7481104cf 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -7,7 +7,6 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -80,7 +79,7 @@ func (gui *Gui) handleBranchPress() error { return gui.createErrorPanel(gui.Tr.AlreadyCheckedOutBranch) } branch := gui.getSelectedBranch() - gui.logSpan(gui.Tr.Spans.CheckoutBranch) + gui.logAction(gui.Tr.Actions.CheckoutBranch) return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{}) } @@ -114,12 +113,11 @@ func (gui *Gui) handleCopyPullRequestURLPress() error { if err != nil { return gui.surfaceError(err) } + gui.logAction(gui.Tr.Actions.CopyPullRequestURL) if err := gui.GitCommand.OSCommand.CopyToClipboard(url); err != nil { return gui.surfaceError(err) } - gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf("Copying to clipboard: '%s'", url), "Copy URL", false)) - gui.raiseToast(gui.Tr.PullRequestURLCopiedToClipboard) return nil @@ -146,7 +144,7 @@ func (gui *Gui) handleForceCheckout() error { title: title, prompt: message, handleConfirm: func() error { - gui.logSpan(gui.Tr.Spans.ForceCheckoutBranch) + gui.logAction(gui.Tr.Actions.ForceCheckoutBranch) if err := gui.GitCommand.Checkout(branch.Name, commands.CheckoutOptions{Force: true}); err != nil { _ = gui.surfaceError(err) } @@ -225,7 +223,7 @@ func (gui *Gui) handleCheckoutByName() error { title: gui.Tr.BranchName + ":", findSuggestionsFunc: gui.getRefsSuggestionsFunc(), handleConfirm: func(response string) error { - gui.logSpan("Checkout branch") + gui.logAction("Checkout branch") return gui.handleCheckoutRef(response, handleCheckoutRefOptions{ onRefNotFound: func(ref string) error { return gui.ask(askOpts{ @@ -298,7 +296,7 @@ func (gui *Gui) deleteNamedBranch(selectedBranch *models.Branch, force bool) err title: title, prompt: message, handleConfirm: func() error { - gui.logSpan(gui.Tr.Spans.DeleteBranch) + gui.logAction(gui.Tr.Actions.DeleteBranch) if err := gui.GitCommand.DeleteBranch(selectedBranch.Name, force); err != nil { errMessage := err.Error() if !force && strings.Contains(errMessage, "git branch -D ") { @@ -335,7 +333,7 @@ func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error { title: gui.Tr.MergingTitle, prompt: prompt, handleConfirm: func() error { - gui.logSpan(gui.Tr.Spans.Merge) + gui.logAction(gui.Tr.Actions.Merge) err := gui.GitCommand.Merge(branchName, commands.MergeOpts{}) return gui.handleGenericMergeCommandResult(err) }, @@ -377,7 +375,7 @@ func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error { title: gui.Tr.RebasingTitle, prompt: prompt, handleConfirm: func() error { - gui.logSpan(gui.Tr.Spans.RebaseBranch) + gui.logAction(gui.Tr.Actions.RebaseBranch) err := gui.GitCommand.RebaseBranch(selectedBranchName) return gui.handleGenericMergeCommandResult(err) }, @@ -402,7 +400,7 @@ func (gui *Gui) handleFastForward() error { return gui.surfaceError(err) } - span := gui.Tr.Spans.FastForwardBranch + action := gui.Tr.Actions.FastForwardBranch split := strings.Split(upstream, "/") remoteName := split[0] @@ -419,9 +417,9 @@ func (gui *Gui) handleFastForward() error { _ = gui.createLoaderPanel(message) if gui.State.Panels.Branches.SelectedLineIdx == 0 { - _ = gui.pullWithLock(PullFilesOptions{span: span, FastForwardOnly: true}) + _ = gui.pullWithLock(PullFilesOptions{action: action, FastForwardOnly: true}) } else { - gui.logSpan(span) + gui.logAction(action) err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName, gui.promptUserForCredential) gui.handleCredentialsPopup(err) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{BRANCHES}}) @@ -450,7 +448,7 @@ func (gui *Gui) handleRenameBranch() error { title: gui.Tr.NewBranchNamePrompt + " " + branch.Name + ":", initialContent: branch.Name, handleConfirm: func(newBranchName string) error { - gui.logSpan(gui.Tr.Spans.RenameBranch) + gui.logAction(gui.Tr.Actions.RenameBranch) if err := gui.GitCommand.RenameBranch(branch.Name, newBranchName); err != nil { return gui.surfaceError(err) } @@ -519,7 +517,7 @@ func (gui *Gui) handleNewBranchOffCurrentItem() error { title: message, initialContent: prefilledName, handleConfirm: func(response string) error { - gui.logSpan(gui.Tr.Spans.CreateBranch) + gui.logAction(gui.Tr.Actions.CreateBranch) if err := gui.GitCommand.NewBranch(sanitizedBranchName(response), item.ID()); err != nil { return err } diff --git a/pkg/gui/cherry_picking.go b/pkg/gui/cherry_picking.go index 5422803cf..8faa55118 100644 --- a/pkg/gui/cherry_picking.go +++ b/pkg/gui/cherry_picking.go @@ -148,7 +148,7 @@ func (gui *Gui) HandlePasteCommits() error { prompt: gui.Tr.SureCherryPick, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.CherryPickingStatus, func() error { - gui.logSpan(gui.Tr.Spans.CherryPick) + gui.logAction(gui.Tr.Actions.CherryPick) err := gui.GitCommand.CherryPickCommits(gui.State.Modes.CherryPicking.CherryPickedCommits) return gui.handleGenericMergeCommandResult(err) }) diff --git a/pkg/gui/command_log_panel.go b/pkg/gui/command_log_panel.go index ad13f6d85..aa46a4d18 100644 --- a/pkg/gui/command_log_panel.go +++ b/pkg/gui/command_log_panel.go @@ -6,38 +6,48 @@ import ( "strings" "time" - "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/constants" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/theme" ) -func (gui *Gui) GetOnRunCommand() func(entry oscommands.CmdLogEntry) { - return func(entry oscommands.CmdLogEntry) { - if gui.Views.Extras == nil { - return - } - - gui.Views.Extras.Autoscroll = true - - textStyle := theme.DefaultTextColor - if !entry.GetCommandLine() { - textStyle = style.FgMagenta - } - gui.CmdLog = append(gui.CmdLog, entry.GetCmdStr()) - indentedCmdStr := " " + strings.Replace(entry.GetCmdStr(), "\n", "\n ", -1) - fmt.Fprint(gui.Views.Extras, "\n"+textStyle.Sprint(indentedCmdStr)) +// our UI command log looks like this: +// Stage File +// git add -- 'filename' +// Unstage File +// git reset HEAD 'filename' +// +// The 'Stage File' and 'Unstage File' lines are actions i.e they group up a set +// of command logs (typically there's only one command under an action but there may be more). +// So we call logAction to log the 'Stage File' part and then we call logCommand to log the command itself. +// We pass logCommand to our OSCommand struct so that it can handle logging commands +// for us. +func (gui *Gui) logAction(action string) { + if gui.Views.Extras == nil { + return } + + gui.Views.Extras.Autoscroll = true + + fmt.Fprint(gui.Views.Extras, "\n"+style.FgYellow.Sprint(action)) } -func (gui *Gui) logSpan(span string) { +func (gui *Gui) logCommand(cmdStr string, commandLine bool) { if gui.Views.Extras == nil { return } gui.Views.Extras.Autoscroll = true - fmt.Fprint(gui.Views.Extras, "\n"+style.FgYellow.Sprint(span)) + textStyle := theme.DefaultTextColor + if !commandLine { + // if we're not dealing with a direct command that could be run on the command line, + // we style it differently to communicate that + textStyle = style.FgMagenta + } + gui.CmdLog = append(gui.CmdLog, cmdStr) + indentedCmdStr := " " + strings.Replace(cmdStr, "\n", "\n ", -1) + fmt.Fprint(gui.Views.Extras, "\n"+textStyle.Sprint(indentedCmdStr)) } func (gui *Gui) printCommandLogHeader() { diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index f5c24adc1..6dd894906 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -63,7 +63,7 @@ func (gui *Gui) handleCheckoutCommitFile() error { return nil } - gui.logSpan(gui.Tr.Spans.CheckoutFile) + gui.logAction(gui.Tr.Actions.CheckoutFile) if err := gui.GitCommand.CheckoutFile(gui.State.CommitFileManager.GetParent(), node.GetPath()); err != nil { return gui.surfaceError(err) } @@ -83,7 +83,7 @@ func (gui *Gui) handleDiscardOldFileChange() error { prompt: gui.Tr.DiscardFileChangesPrompt, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.RebasingStatus, func() error { - gui.logSpan(gui.Tr.Spans.DiscardOldFileChange) + gui.logAction(gui.Tr.Actions.DiscardOldFileChange) if err := gui.GitCommand.DiscardOldFileChanges(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, fileName); err != nil { if err := gui.handleGenericMergeCommandResult(err); err != nil { return err diff --git a/pkg/gui/commit_message_panel.go b/pkg/gui/commit_message_panel.go index f12d0f28f..932c1608a 100644 --- a/pkg/gui/commit_message_panel.go +++ b/pkg/gui/commit_message_panel.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/jesseduffield/gocui" - "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -25,7 +24,7 @@ func (gui *Gui) handleCommitConfirm() error { } cmdObj := gui.GitCommand.CommitCmdObj(message, strings.Join(flags, " ")) - gui.OnRunCommand(oscommands.NewCmdLogEntry(cmdObj.ToString(), gui.Tr.Spans.Commit, true)) + gui.logAction(gui.Tr.Actions.Commit) _ = gui.returnFromContext() return gui.withGpgHandling(cmdObj, gui.Tr.CommittingStatus, func() error { diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 4e67e4a05..76f81022e 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -6,7 +6,6 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands/loaders" "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -173,7 +172,7 @@ func (gui *Gui) handleCommitSquashDown() error { prompt: gui.Tr.SureSquashThisCommit, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.SquashingStatus, func() error { - gui.logSpan(gui.Tr.Spans.SquashCommitDown) + gui.logAction(gui.Tr.Actions.SquashCommitDown) err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "squash") return gui.handleGenericMergeCommandResult(err) }) @@ -203,7 +202,7 @@ func (gui *Gui) handleCommitFixup() error { prompt: gui.Tr.SureFixupThisCommit, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.FixingStatus, func() error { - gui.logSpan(gui.Tr.Spans.FixupCommit) + gui.logAction(gui.Tr.Actions.FixupCommit) err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "fixup") return gui.handleGenericMergeCommandResult(err) }) @@ -242,7 +241,7 @@ func (gui *Gui) handleRenameCommit() error { title: gui.Tr.LcRenameCommit, initialContent: message, handleConfirm: func(response string) error { - gui.logSpan(gui.Tr.Spans.RewordCommit) + gui.logAction(gui.Tr.Actions.RewordCommit) if err := gui.GitCommand.RenameCommit(response); err != nil { return gui.surfaceError(err) } @@ -265,7 +264,7 @@ func (gui *Gui) handleRenameCommitEditor() error { return nil } - gui.logSpan(gui.Tr.Spans.RewordCommit) + gui.logAction(gui.Tr.Actions.RewordCommit) subProcess, err := gui.GitCommand.RewordCommit(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx) if err != nil { return gui.surfaceError(err) @@ -294,11 +293,11 @@ func (gui *Gui) handleMidRebaseCommand(action string) (bool, error) { return true, gui.createErrorPanel(gui.Tr.LcRewordNotSupported) } - gui.OnRunCommand(oscommands.NewCmdLogEntry( + gui.logAction("Update rebase TODO") + gui.logCommand( fmt.Sprintf("Updating rebase action of commit |