diff --git a/pkg/commands/branches.go b/pkg/commands/branches.go index 62a243247..9d4bf4512 100644 --- a/pkg/commands/branches.go +++ b/pkg/commands/branches.go @@ -59,9 +59,9 @@ type CheckoutOptions struct { func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error { forceArg := "" if options.Force { - forceArg = "--force " + forceArg = " --force" } - return c.OSCommand.RunCommandWithOptions(fmt.Sprintf("git checkout %s %s", forceArg, branch), oscommands.RunCommandOptions{EnvVars: options.EnvVars}) + return c.OSCommand.RunCommandWithOptions(fmt.Sprintf("git checkout%s %s", forceArg, branch), oscommands.RunCommandOptions{EnvVars: options.EnvVars}) } // GetBranchGraph gets the color-formatted graph of the log for the given branch diff --git a/pkg/commands/pull_request.go b/pkg/commands/pull_request.go index 8bddbec50..575027229 100644 --- a/pkg/commands/pull_request.go +++ b/pkg/commands/pull_request.go @@ -90,23 +90,23 @@ func NewPullRequest(gitCommand *GitCommand) *PullRequest { } // Create opens link to new pull request in browser -func (pr *PullRequest) Create(branch *models.Branch) error { +func (pr *PullRequest) Create(branch *models.Branch) (string, error) { pullRequestURL, err := pr.getPullRequestURL(branch) if err != nil { - return err + return "", err } - return pr.GitCommand.OSCommand.OpenLink(pullRequestURL) + return pullRequestURL, pr.GitCommand.OSCommand.OpenLink(pullRequestURL) } // CopyURL copies the pull request URL to the clipboard -func (pr *PullRequest) CopyURL(branch *models.Branch) error { +func (pr *PullRequest) CopyURL(branch *models.Branch) (string, error) { pullRequestURL, err := pr.getPullRequestURL(branch) if err != nil { - return err + return "", err } - return pr.GitCommand.OSCommand.CopyToClipboard(pullRequestURL) + return pullRequestURL, pr.GitCommand.OSCommand.CopyToClipboard(pullRequestURL) } func (pr *PullRequest) getPullRequestURL(branch *models.Branch) (string, error) { diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 99923a91e..88ba2d3fd 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -6,6 +6,7 @@ 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/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" @@ -86,16 +87,18 @@ func (gui *Gui) handleBranchPress() error { return gui.createErrorPanel(gui.Tr.AlreadyCheckedOutBranch) } branch := gui.getSelectedBranch() - return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{}) + return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{span: "Checkout branch"}) } func (gui *Gui) handleCreatePullRequestPress() error { pullRequest := commands.NewPullRequest(gui.GitCommand) branch := gui.getSelectedBranch() - if err := pullRequest.Create(branch); err != nil { + url, err := pullRequest.Create(branch) + if err != nil { return gui.surfaceError(err) } + gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf("Creating pull request at URL: %s", url), "Create pull request", false)) return nil } @@ -104,9 +107,11 @@ func (gui *Gui) handleCopyPullRequestURLPress() error { pullRequest := commands.NewPullRequest(gui.GitCommand) branch := gui.getSelectedBranch() - if err := pullRequest.CopyURL(branch); err != nil { + url, err := pullRequest.CopyURL(branch) + if 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) @@ -118,7 +123,7 @@ func (gui *Gui) handleGitFetch() error { return err } go utils.Safe(func() { - err := gui.fetch(true) + err := gui.fetch(true, "Fetch") gui.handleCredentialsPopup(err) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC}) }) @@ -134,7 +139,7 @@ func (gui *Gui) handleForceCheckout() error { title: title, prompt: message, handleConfirm: func() error { - if err := gui.GitCommand.Checkout(branch.Name, commands.CheckoutOptions{Force: true}); err != nil { + if err := gui.GitCommand.WithSpan("Force checkout branch").Checkout(branch.Name, commands.CheckoutOptions{Force: true}); err != nil { _ = gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) @@ -216,6 +221,7 @@ func (gui *Gui) handleCheckoutByName() error { findSuggestionsFunc: gui.findBranchNameSuggestions, handleConfirm: func(response string) error { return gui.handleCheckoutRef(response, handleCheckoutRefOptions{ + span: "Checkout branch", onRefNotFound: func(ref string) error { return gui.ask(askOpts{ @@ -288,7 +294,7 @@ func (gui *Gui) deleteNamedBranch(selectedBranch *models.Branch, force bool) err title: title, prompt: message, handleConfirm: func() error { - if err := gui.GitCommand.DeleteBranch(selectedBranch.Name, force); err != nil { + if err := gui.GitCommand.WithSpan("Delete branch").DeleteBranch(selectedBranch.Name, force); err != nil { errMessage := err.Error() if !force && strings.Contains(errMessage, "is not fully merged") { return gui.deleteNamedBranch(selectedBranch, true) @@ -324,7 +330,7 @@ func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error { title: gui.Tr.MergingTitle, prompt: prompt, handleConfirm: func() error { - err := gui.GitCommand.Merge(branchName, commands.MergeOpts{}) + err := gui.GitCommand.WithSpan("Merge").Merge(branchName, commands.MergeOpts{}) return gui.handleGenericMergeCommandResult(err) }, }) @@ -365,7 +371,7 @@ func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error { title: gui.Tr.RebasingTitle, prompt: prompt, handleConfirm: func() error { - err := gui.GitCommand.RebaseBranch(selectedBranchName) + err := gui.GitCommand.WithSpan("Rebase branch").RebaseBranch(selectedBranchName) return gui.handleGenericMergeCommandResult(err) }, }) @@ -391,6 +397,8 @@ func (gui *Gui) handleFastForward() error { return gui.surfaceError(err) } + span := "Fast forward branch" + split := strings.Split(upstream, "/") remoteName := split[0] remoteBranchName := strings.Join(split[1:], "/") @@ -406,9 +414,9 @@ func (gui *Gui) handleFastForward() error { _ = gui.createLoaderPanel(message) if gui.State.Panels.Branches.SelectedLineIdx == 0 { - _ = gui.pullWithMode("ff-only", PullFilesOptions{}) + _ = gui.pullWithMode("ff-only", PullFilesOptions{span: span}) } else { - err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName, gui.promptUserForCredential) + err := gui.GitCommand.WithSpan(span).FastForward(branch.Name, remoteName, remoteBranchName, gui.promptUserForCredential) gui.handleCredentialsPopup(err) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{BRANCHES}}) } @@ -436,7 +444,7 @@ func (gui *Gui) handleRenameBranch() error { title: gui.Tr.NewBranchNamePrompt + " " + branch.Name + ":", initialContent: branch.Name, handleConfirm: func(newBranchName string) error { - if err := gui.GitCommand.RenameBranch(branch.Name, newBranchName); err != nil { + if err := gui.GitCommand.WithSpan("Rename branch").RenameBranch(branch.Name, newBranchName); err != nil { return gui.surfaceError(err) } @@ -505,7 +513,7 @@ func (gui *Gui) handleNewBranchOffCurrentItem() error { title: message, initialContent: prefilledName, handleConfirm: func(response string) error { - if err := gui.GitCommand.NewBranch(sanitizedBranchName(response), item.ID()); err != nil { + if err := gui.GitCommand.WithSpan("Create branch").NewBranch(sanitizedBranchName(response), item.ID()); err != nil { return err } diff --git a/pkg/gui/cherry_picking.go b/pkg/gui/cherry_picking.go index 3ad52a73c..b7784997e 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 { - err := gui.GitCommand.CherryPickCommits(gui.State.Modes.CherryPicking.CherryPickedCommits) + err := gui.GitCommand.WithSpan("(Cherry-pick) Paste commits").CherryPickCommits(gui.State.Modes.CherryPicking.CherryPickedCommits) return gui.handleGenericMergeCommandResult(err) }) }, diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index 4b9833c44..4679a462e 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -62,7 +62,7 @@ func (gui *Gui) handleCheckoutCommitFile() error { return nil } - if err := gui.GitCommand.CheckoutFile(gui.State.CommitFileManager.GetParent(), node.GetPath()); err != nil { + if err := gui.GitCommand.WithSpan("Checkout file").CheckoutFile(gui.State.CommitFileManager.GetParent(), node.GetPath()); err != nil { return gui.surfaceError(err) } @@ -81,7 +81,7 @@ func (gui *Gui) handleDiscardOldFileChange() error { prompt: gui.Tr.DiscardFileChangesPrompt, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.RebasingStatus, func() error { - if err := gui.GitCommand.DiscardOldFileChanges(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, fileName); err != nil { + if err := gui.GitCommand.WithSpan("Discard old file change").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/commits_panel.go b/pkg/gui/commits_panel.go index 4e360f290..a9294d66e 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -1,10 +1,12 @@ package gui import ( + "fmt" "sync" "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" ) @@ -169,7 +171,7 @@ func (gui *Gui) handleCommitSquashDown() error { prompt: gui.Tr.SureSquashThisCommit, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.SquashingStatus, func() error { - err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "squash") + err := gui.GitCommand.WithSpan("Squash commit down").InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "squash") return gui.handleGenericMergeCommandResult(err) }) }, @@ -198,7 +200,7 @@ func (gui *Gui) handleCommitFixup() error { prompt: gui.Tr.SureFixupThisCommit, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.FixingStatus, func() error { - err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "fixup") + err := gui.GitCommand.WithSpan("Fixup commit").InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "fixup") return gui.handleGenericMergeCommandResult(err) }) }, @@ -236,7 +238,7 @@ func (gui *Gui) handleRenameCommit() error { title: gui.Tr.LcRenameCommit, initialContent: message, handleConfirm: func(response string) error { - if err := gui.GitCommand.RenameCommit(response); err != nil { + if err := gui.GitCommand.WithSpan("Reword commit").RenameCommit(response); err != nil { return gui.surfaceError(err) } @@ -258,7 +260,7 @@ func (gui *Gui) handleRenameCommitEditor() error { return nil } - subProcess, err := gui.GitCommand.RewordCommit(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx) + subProcess, err := gui.GitCommand.WithSpan("Reword commit").RewordCommit(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx) if err != nil { return gui.surfaceError(err) } @@ -286,6 +288,12 @@ func (gui *Gui) handleMidRebaseCommand(action string) (bool, error) { return true, gui.createErrorPanel(gui.Tr.LcRewordNotSupported) } + gui.OnRunCommand(oscommands.NewCmdLogEntry( + fmt.Sprintf("Updating rebase action of commit %s to '%s'", selectedCommit.ShortSha(), action), + "Update rebase TODO", + false, + )) + if err := gui.GitCommand.EditRebaseTodo(gui.State.Panels.Commits.SelectedLineIdx, action); err != nil { return false, gui.surfaceError(err) } @@ -311,7 +319,7 @@ func (gui *Gui) handleCommitDelete() error { prompt: gui.Tr.DeleteCommitPrompt, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.DeletingStatus, func() error { - err := gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "drop") + err := gui.GitCommand.WithSpan("Drop commit").InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "drop") return gui.handleGenericMergeCommandResult(err) }) }, @@ -323,12 +331,23 @@ func (gui *Gui) handleCommitMoveDown() error { return err } + span := "Move commit down" + index := gui.State.Panels.Commits.SelectedLineIdx selectedCommit := gui.State.Commits[index] if selectedCommit.Status == "rebasing" { if gui.State.Commits[index+1].Status != "rebasing" { return nil } + + // logging directly here because MoveTodoDown doesn't have enough information + // to provide a useful log + gui.OnRunCommand(oscommands.NewCmdLogEntry( + fmt.Sprintf("Moving commit %s down", selectedCommit.ShortSha()), + span, + false, + )) + if err := gui.GitCommand.MoveTodoDown(index); err != nil { return gui.surfaceError(err) } @@ -337,7 +356,7 @@ func (gui *Gui) handleCommitMoveDown() error { } return gui.WithWaitingStatus(gui.Tr.MovingStatus, func() error { - err := gui.GitCommand.MoveCommitDown(gui.State.Commits, index) + err := gui.GitCommand.WithSpan(span).MoveCommitDown(gui.State.Commits, index) if err == nil { gui.State.Panels.Commits.SelectedLineIdx++ } @@ -354,8 +373,19 @@ func (gui *Gui) handleCommitMoveUp() error { if index == 0 { return nil } + + span := "Move commit up" + selectedCommit := gui.State.Commits[index] if selectedCommit.Status == "rebasing" { + // logging directly here because MoveTodoDown doesn't have enough information + // to provide a useful log + gui.OnRunCommand(oscommands.NewCmdLogEntry( + fmt.Sprintf("Moving commit %s up", selectedCommit.ShortSha()), + span, + false, + )) + if err := gui.GitCommand.MoveTodoDown(index - 1); err != nil { return gui.surfaceError(err) } @@ -364,7 +394,7 @@ func (gui *Gui) handleCommitMoveUp() error { } return gui.WithWaitingStatus(gui.Tr.MovingStatus, func() error { - err := gui.GitCommand.MoveCommitDown(gui.State.Commits, index-1) + err := gui.GitCommand.WithSpan(span).MoveCommitDown(gui.State.Commits, index-1) if err == nil { gui.State.Panels.Commits.SelectedLineIdx-- } @@ -386,7 +416,7 @@ func (gui *Gui) handleCommitEdit() error { } return gui.WithWaitingStatus(gui.Tr.RebasingStatus, func() error { - err = gui.GitCommand.InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "edit") + err = gui.GitCommand.WithSpan("Edit commit").InteractiveRebase(gui.State.Commits, gui.State.Panels.Commits.SelectedLineIdx, "edit") return gui.handleGenericMergeCommandResult(err) }) } @@ -401,7 +431,7 @@ func (gui *Gui) handleCommitAmendTo() error { prompt: gui.Tr.AmendCommitPrompt, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.AmendingStatus, func() error { - err := gui.GitCommand.AmendTo(gui.State.Commits[gui.State.Panels.Commits.SelectedLineIdx].Sha) + err := gui.GitCommand.WithSpan("Amend commit").AmendTo(gui.State.Commits[gui.State.Panels.Commits.SelectedLineIdx].Sha) return gui.handleGenericMergeCommandResult(err) }) }, @@ -431,7 +461,7 @@ func (gui *Gui) handleCommitRevert() error { return err } - if err := gui.GitCommand.Revert(gui.State.Commits[gui.State.Panels.Commits.SelectedLineIdx].Sha); err != nil { + if err := gui.GitCommand.WithSpan("Revert commit").Revert(gui.State.Commits[gui.State.Panels.Commits.SelectedLineIdx].Sha); err != nil { return gui.surfaceError(err) } gui.State.Panels.Commits.SelectedLineIdx++ @@ -468,7 +498,7 @@ func (gui *Gui) handleCreateFixupCommit() error { title: gui.Tr.CreateFixupCommit, prompt: prompt, handleConfirm: func() error { - if err := gui.GitCommand.CreateFixupCommit(commit.Sha); err != nil { + if err := gui.GitCommand.WithSpan("Create fixup commit").CreateFixupCommit(commit.Sha); err != nil { return gui.surfaceError(err) } @@ -499,7 +529,7 @@ func (gui *Gui) handleSquashAllAboveFixupCommits() error { prompt: prompt, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.SquashingStatus, func() error { - err := gui.GitCommand.SquashAllAboveFixupCommits(commit.Sha) + err := gui.GitCommand.WithSpan("Squash all above fixup commits").SquashAllAboveFixupCommits(commit.Sha) return gui.handleGenericMergeCommandResult(err) }) }, @@ -522,7 +552,7 @@ func (gui *Gui) handleCreateLightweightTag(commitSha string) error { return gui.prompt(promptOpts{ title: gui.Tr.TagNameTitle, handleConfirm: func(response string) error { - if err := gui.GitCommand.CreateLightweightTag(response, commitSha); err != nil { + if err := gui.GitCommand.WithSpan("Create lightweight tag").CreateLightweightTag(response, commitSha); err != nil { return gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{COMMITS, TAGS}}) @@ -540,7 +570,7 @@ func (gui *Gui) handleCheckoutCommit() error { title: gui.Tr.LcCheckoutCommit, prompt: gui.Tr.SureCheckoutThisCommit, handleConfirm: func() error { - return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{}) + return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{span: "Checkout commit"}) }, }) } @@ -595,7 +625,7 @@ func (gui *Gui) handleCopySelectedCommitMessageToClipboard() error { return gui.surfaceError(err) } - if err := gui.OSCommand.CopyToClipboard(message); err != nil { + if err := gui.OSCommand.WithSpan("Copy commit message to clipboard").CopyToClipboard(message); err != nil { return gui.surfaceError(err) } diff --git a/pkg/gui/custom_commands.go b/pkg/gui/custom_commands.go index c365f4516..881c53502 100644 --- a/pkg/gui/custom_commands.go +++ b/pkg/gui/custom_commands.go @@ -68,7 +68,7 @@ func (gui *Gui) handleCustomCommandKeybinding(customCommand config.CustomCommand loadingText = gui.Tr.LcRunningCustomCommandStatus } return gui.WithWaitingStatus(loadingText, func() error { - if err := gui.OSCommand.RunShellCommand(cmdStr); err != nil { + if err := gui.OSCommand.WithSpan("Custom command").RunShellCommand(cmdStr); err != nil { return gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{}) diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index a09e8158f..795152bae 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -609,6 +609,8 @@ func (gui *Gui) handlePullFiles() error { return nil } + span := "Pull" + currentBranch := gui.currentBranch() if currentBranch == nil { // need to wait for branches to refresh @@ -624,7 +626,7 @@ func (gui *Gui) handlePullFiles() error { } for branchName, branch := range conf.Branches { if branchName == currentBranch.Name { - return gui.pullFiles(PullFilesOptions{RemoteName: branch.Remote, BranchName: branch.Name}) + return gui.pullFiles(PullFilesOptions{RemoteName: branch.Remote, BranchName: branch.Name, span: span}) } } @@ -639,17 +641,18 @@ func (gui *Gui) handlePullFiles() error { } return gui.createErrorPanel(errorMessage) } - return gui.pullFiles(PullFilesOptions{}) + return gui.pullFiles(PullFilesOptions{span: span}) }, }) } - return gui.pullFiles(PullFilesOptions{}) + return gui.pullFiles(PullFilesOptions{span: span}) } type PullFilesOptions struct { RemoteName string BranchName string + span string } func (gui *Gui) pullFiles(opts PullFilesOptions) error { @@ -669,7 +672,7 @@ func (gui *Gui) pullWithMode(mode string, opts PullFilesOptions) error { gui.Mutexes.FetchMutex.Lock() defer gui.Mutexes.FetchMutex.Unlock() - gitCommand := gui.GitCommand.WithSpan("Pull") + gitCommand := gui.GitCommand.WithSpan(opts.span) err := gitCommand.Fetch( commands.FetchOptions{ diff --git a/pkg/gui/git_flow.go b/pkg/gui/git_flow.go index 701eda37c..6130118fb 100644 --- a/pkg/gui/git_flow.go +++ b/pkg/gui/git_flow.go @@ -32,7 +32,7 @@ func (gui *Gui) gitFlowFinishBranch(gitFlowConfig string, branchName string) err } return gui.runSubprocessWithSuspenseAndRefresh( - gui.OSCommand.PrepareSubProcess("git", "flow", branchType, "finish", suffix), + gui.OSCommand.WithSpan("Git flow finish").PrepareSubProcess("git", "flow", branchType, "finish", suffix), ) } @@ -56,7 +56,7 @@ func (gui *Gui) handleCreateGitFlowMenu() error { title: title, handleConfirm: func(name string) error { return gui.runSubprocessWithSuspenseAndRefresh( - gui.OSCommand.WithSpan("Git Flow").PrepareSubProcess("git", "flow", branchType, "start", name), + gui.OSCommand.WithSpan("Git Flow start").PrepareSubProcess("git", "flow", branchType, "start", name), ) }, }) diff --git a/pkg/gui/global_handlers.go b/pkg/gui/global_handlers.go index 0f281346b..c8c567fd1 100644 --- a/pkg/gui/global_handlers.go +++ b/pkg/gui/global_handlers.go @@ -200,7 +200,7 @@ func (gui *Gui) handleInfoClick() error { return nil } -func (gui *Gui) fetch(canPromptForCredentials bool) (err error) { +func (gui *Gui) fetch(canPromptForCredentials bool, span string) (err error) { gui.Mutexes.FetchMutex.Lock() defer gui.Mutexes.FetchMutex.Unlock() @@ -209,7 +209,7 @@ func (gui *Gui) fetch(canPromptForCredentials bool) (err error) { fetchOpts.PromptUserForCredential = gui.promptUserForCredential } - err = gui.GitCommand.Fetch(fetchOpts) + err = gui.GitCommand.WithSpan(span).Fetch(fetchOpts) if canPromptForCredentials && err != nil && strings.Contains(err.Error(), "exit status 128") { _ = gui.createErrorPanel(gui.Tr.PassUnameWrong) @@ -228,7 +228,7 @@ func (gui *Gui) handleCopySelectedSideContextItemToClipboard() error { return nil } - if err := gui.OSCommand.CopyToClipboard(itemId); err != nil { + if err := gui.OSCommand.WithSpan("Copy to clipboard").CopyToClipboard(itemId); err != nil { return gui.surfaceError(err) } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index dbbb25b8a..d152200cb 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -744,7 +744,7 @@ func (gui *Gui) startBackgroundFetch() { if !isNew { time.After(time.Duration(userConfig.Refresher.FetchInterval) * time.Second) } - err := gui.fetch(false) + err := gui.fetch(false, "") if err != nil && strings.Contains(err.Error(), "exit status 128") && isNew { _ = gui.ask(askOpts{ title: gui.Tr.NoAutomaticGitFetchTitle, @@ -752,7 +752,7 @@ func (gui *Gui) startBackgroundFetch() { }) } else { gui.goEvery(time.Second*time.Duration(userConfig.Refresher.FetchInterval), gui.stopChan, func() error { - err := gui.fetch(false) + err := gui.fetch(false, "") return err }) } diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go index 556f20cc0..0b4e30903 100644 --- a/pkg/gui/merge_panel.go +++ b/pkg/gui/merge_panel.go @@ -13,6 +13,7 @@ import ( "github.com/golang-collections/collections/stack" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts" ) @@ -76,6 +77,7 @@ func (gui *Gui) handlePopFileSnapshot() error { if gitFile == nil { return nil } + gui.OnRunCommand(oscommands.NewCmdLogEntry("Undoing last conflict resolution", "Undo merge conflict resolution", false)) if err := ioutil.WriteFile(gitFile.Name, []byte(prevContent), 0644); err != nil { return err } @@ -165,6 +167,17 @@ func (gui *Gui) resolveConflict(conflict commands.Conflict, selection mergeconfl output += line } } + + var logStr string + switch selection { + case mergeconflicts.TOP: + logStr = "Picking top hunk" + case mergeconflicts.BOTTOM: + logStr = "Picking bottom hunk" + case mergeconflicts.BOTH: + logStr = "Picking both hunks" + } + gui.OnRunCommand(oscommands.NewCmdLogEntry(logStr, "Resolve merge conflict", false)) return ioutil.WriteFile(gitFile.Name, []byte(output), 0644) } diff --git a/pkg/gui/rebase_options_panel.go b/pkg/gui/rebase_options_panel.go index c49b4f38f..a50608b67 100644 --- a/pkg/gui/rebase_options_panel.go +++ b/pkg/gui/rebase_options_panel.go @@ -43,7 +43,7 @@ func (gui *Gui) genericMergeCommand(command string) error { return gui.createErrorPanel(gui.Tr.NotMergingOrRebasing) } - gitCommand := gui.GitCommand.WithSpan(fmt.Sprintf("Merge: %s", command)) + gitCommand := gui.GitCommand.WithSpan(fmt.Sprintf("Merge/Rebase: %s", command)) commandType := strings.Replace(status, "ing", "e", 1) // we should end up with a command like 'git merge --continue' diff --git a/pkg/gui/reflog_panel.go b/pkg/gui/reflog_panel.go index 19237d429..4b5ac1b76 100644 --- a/pkg/gui/reflog_panel.go +++ b/pkg/gui/reflog_panel.go @@ -92,7 +92,7 @@ func (gui *Gui) handleCheckoutReflogCommit() error { title: gui.Tr.LcCheckoutCommit, prompt: gui.Tr.SureCheckoutThisCommit, handleConfirm: func() error { - return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{}) + return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{span: "Checkout reflog commit"}) }, }) if err != nil { diff --git a/pkg/gui/remote_branches_panel.go b/pkg/gui/remote_branches_panel.go index c462160cf..6f87d8747 100644 --- a/pkg/gui/remote_branches_panel.go +++ b/pkg/gui/remote_branches_panel.go @@ -59,7 +59,7 @@ func (gui *Gui) handleDeleteRemoteBranch() error { prompt: message, handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.DeletingStatus, func() error { - err := gui.GitCommand.DeleteRemoteBranch(remoteBranch.RemoteName, remoteBranch.Name, gui.promptUserForCredential) + err := gui.GitCommand.WithSpan("Delete remote branch").DeleteRemoteBranch(remoteBranch.RemoteName, remoteBranch.Name, gui.promptUserForCredential) gui.handleCredentialsPopup(err) return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{BRANCHES, REMOTES}}) @@ -89,7 +89,7 @@ func (gui *Gui) handleSetBranchUpstream() error { title: gui.Tr.SetUpstreamTitle, prompt: message, handleConfirm: func() error { - if err := gui.GitCommand.SetBranchUpstream(selectedBranch.RemoteName, selectedBranch.Name, checkedOutBranch.Name); err != nil { + if err := gui.GitCommand.WithSpan("Set branch upstream").SetBranchUpstream(selectedBranch.RemoteName, selectedBranch.Name, checkedOutBranch.Name); err != nil { return err } diff --git a/pkg/gui/remotes_panel.go b/pkg/gui/remotes_panel.go index 5ba52c2ac..00feb5680 100644 --- a/pkg/gui/remotes_panel.go +++ b/pkg/gui/remotes_panel.go @@ -85,7 +85,7 @@ func (gui *Gui) handleAddRemote() error { return gui.prompt(promptOpts{ title: gui.Tr.LcNewRemoteUrl, handleConfirm: func(remoteUrl string) error { - if err := gui.GitCommand.AddRemote(remoteName, remoteUrl); err != nil { + if err := gui.GitCommand.WithSpan("Add remote").AddRemote(remoteName, remoteUrl); err != nil { return err } return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{REMOTES}}) @@ -106,7 +106,7 @@ func (gui *Gui) handleRemoveRemote() error { title: gui.Tr.LcRemoveRemote, prompt: gui.Tr.LcRemoveRemotePrompt + " '" + remote.Name + "'?", handleConfirm: func() error { - if err := gui.GitCommand.RemoveRemote(remote.Name); err != nil { + if err := gui.GitCommand.WithSpan("Remove remote").RemoveRemote(remote.Name); err != nil { return gui.surfaceError(err) } @@ -128,12 +128,14 @@ func (gui *Gui) handleEditRemote() error { }, ) + gitCommand := gui.GitCommand.WithSpan("Update remote") + return gui.prompt(promptOpts{ title: editNameMessage, initialContent: remote.Name, handleConfirm: func(updatedRemoteName string) error { if updatedRemoteName != remote.Name { - if err := gui.GitCommand.RenameRemote(remote.Name, updatedRemoteName); err != nil { + if err := gitCommand.RenameRemote(remote.Name, updatedRemoteName); err != nil { return gui.surfaceError(err) } } @@ -155,7 +157,7 @@ func (gui *Gui) handleEditRemote() error { title: editUrlMessage, initialContent: url, handleConfirm: func(updatedRemoteUrl string) error { - if err := gui.GitCommand.UpdateRemoteUrl(updatedRemoteName, updatedRemoteUrl); err != nil { + if err := gitCommand.UpdateRemoteUrl(updatedRemoteName, updatedRemoteUrl); err != nil { return gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{BRANCHES, REMOTES}}) diff --git a/pkg/gui/sub_commits_panel.go b/pkg/gui/sub_commits_panel.go index 41859143b..24ea834d4 100644 --- a/pkg/gui/sub_commits_panel.go +++ b/pkg/gui/sub_commits_panel.go @@ -48,7 +48,7 @@ func (gui *Gui) handleCheckoutSubCommit() error { title: gui.Tr.LcCheckoutCommit, prompt: gui.Tr.SureCheckoutThisCommit, handleConfirm: func() error { - return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{}) + return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{span: "Checkout commit"}) }, }) if err != nil { diff --git a/pkg/gui/tags_panel.go b/pkg/gui/tags_panel.go index 7be7c1f8b..670ca0bee 100644 --- a/pkg/gui/tags_panel.go +++ b/pkg/gui/tags_panel.go @@ -19,7 +19,7 @@ func (gui *Gui) handleCreateTag() error { title: gui.Tr.CreateTagTitle, handleConfirm: func(tagName string) error { // leaving commit SHA blank so that we're just creating the tag for the current commit - if err := gui.GitCommand.CreateLightweightTag(tagName, ""); err != nil { + if err := gui.GitCommand.WithSpan("Create lightweight tag").CreateLightweightTag(tagName, ""); err != nil { return gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{COMMITS, TAGS}, then: func() { @@ -86,7 +86,7 @@ func (gui *Gui) withSelectedTag(f func(tag *models.Tag) error) func() error { } func (gui *Gui) handleCheckoutTag(tag *models.Tag) error { - if err := gui.handleCheckoutRef(tag.Name, handleCheckoutRefOptions{}); err != nil { + if err := gui.handleCheckoutRef(tag.Name, handleCheckoutRefOptions{span: "Checkout tag"}); err != nil { return err } return gui.pushContext(gui.State.Contexts.Branches) @@ -104,7 +104,7 @@ func (gui *Gui) handleDeleteTag(tag *models.Tag) error { title: gui.Tr.DeleteTagTitle, prompt: prompt, handleConfirm: func() error { - if err := gui.GitCommand.DeleteTag(tag.Name); err != nil { + if err := gui.GitCommand.WithSpan("Delete tag").DeleteTag(tag.Name); err != nil { return gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{COMMITS, TAGS}}) @@ -125,7 +125,7 @@ func (gui *Gui) handlePushTag(tag *models.Tag) error { initialContent: "origin", handleConfirm: func(response string) error { return gui.WithWaitingStatus(gui.Tr.PushingTagStatus, func() error { - err := gui.GitCommand.PushTag(response, tag.Name, gui.promptUserForCredential) + err := gui.GitCommand.WithSpan("Push tag").PushTag(response, tag.Name, gui.promptUserForCredential) gui.handleCredentialsPopup(err) return nil