1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-04 03:48:07 +02:00

full coverage for logging commands

This commit is contained in:
Jesse Duffield 2021-04-10 17:31:23 +10:00
parent 74320f0075
commit 6fbe660f96
18 changed files with 119 additions and 63 deletions

View File

@ -59,9 +59,9 @@ type CheckoutOptions struct {
func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error { func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error {
forceArg := "" forceArg := ""
if options.Force { 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 // GetBranchGraph gets the color-formatted graph of the log for the given branch

View File

@ -90,23 +90,23 @@ func NewPullRequest(gitCommand *GitCommand) *PullRequest {
} }
// Create opens link to new pull request in browser // 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) pullRequestURL, err := pr.getPullRequestURL(branch)
if err != nil { 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 // 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) pullRequestURL, err := pr.getPullRequestURL(branch)
if err != nil { 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) { func (pr *PullRequest) getPullRequestURL(branch *models.Branch) (string, error) {

View File

@ -6,6 +6,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "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/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
@ -86,16 +87,18 @@ func (gui *Gui) handleBranchPress() error {
return gui.createErrorPanel(gui.Tr.AlreadyCheckedOutBranch) return gui.createErrorPanel(gui.Tr.AlreadyCheckedOutBranch)
} }
branch := gui.getSelectedBranch() branch := gui.getSelectedBranch()
return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{}) return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{span: "Checkout branch"})
} }
func (gui *Gui) handleCreatePullRequestPress() error { func (gui *Gui) handleCreatePullRequestPress() error {
pullRequest := commands.NewPullRequest(gui.GitCommand) pullRequest := commands.NewPullRequest(gui.GitCommand)
branch := gui.getSelectedBranch() branch := gui.getSelectedBranch()
if err := pullRequest.Create(branch); err != nil { url, err := pullRequest.Create(branch)
if err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf("Creating pull request at URL: %s", url), "Create pull request", false))
return nil return nil
} }
@ -104,9 +107,11 @@ func (gui *Gui) handleCopyPullRequestURLPress() error {
pullRequest := commands.NewPullRequest(gui.GitCommand) pullRequest := commands.NewPullRequest(gui.GitCommand)
branch := gui.getSelectedBranch() branch := gui.getSelectedBranch()
if err := pullRequest.CopyURL(branch); err != nil { url, err := pullRequest.CopyURL(branch)
if err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf("Copying to clipboard: '%s'", url), "Copy URL", false))
gui.raiseToast(gui.Tr.PullRequestURLCopiedToClipboard) gui.raiseToast(gui.Tr.PullRequestURLCopiedToClipboard)
@ -118,7 +123,7 @@ func (gui *Gui) handleGitFetch() error {
return err return err
} }
go utils.Safe(func() { go utils.Safe(func() {
err := gui.fetch(true) err := gui.fetch(true, "Fetch")
gui.handleCredentialsPopup(err) gui.handleCredentialsPopup(err)
_ = gui.refreshSidePanels(refreshOptions{mode: ASYNC}) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC})
}) })
@ -134,7 +139,7 @@ func (gui *Gui) handleForceCheckout() error {
title: title, title: title,
prompt: message, prompt: message,
handleConfirm: func() error { 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) _ = gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
@ -216,6 +221,7 @@ func (gui *Gui) handleCheckoutByName() error {
findSuggestionsFunc: gui.findBranchNameSuggestions, findSuggestionsFunc: gui.findBranchNameSuggestions,
handleConfirm: func(response string) error { handleConfirm: func(response string) error {
return gui.handleCheckoutRef(response, handleCheckoutRefOptions{ return gui.handleCheckoutRef(response, handleCheckoutRefOptions{
span: "Checkout branch",
onRefNotFound: func(ref string) error { onRefNotFound: func(ref string) error {
return gui.ask(askOpts{ return gui.ask(askOpts{
@ -288,7 +294,7 @@ func (gui *Gui) deleteNamedBranch(selectedBranch *models.Branch, force bool) err
title: title, title: title,
prompt: message, prompt: message,
handleConfirm: func() error { 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() errMessage := err.Error()
if !force && strings.Contains(errMessage, "is not fully merged") { if !force && strings.Contains(errMessage, "is not fully merged") {
return gui.deleteNamedBranch(selectedBranch, true) return gui.deleteNamedBranch(selectedBranch, true)
@ -324,7 +330,7 @@ func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error {
title: gui.Tr.MergingTitle, title: gui.Tr.MergingTitle,
prompt: prompt, prompt: prompt,
handleConfirm: func() error { handleConfirm: func() error {
err := gui.GitCommand.Merge(branchName, commands.MergeOpts{}) err := gui.GitCommand.WithSpan("Merge").Merge(branchName, commands.MergeOpts{})
return gui.handleGenericMergeCommandResult(err) return gui.handleGenericMergeCommandResult(err)
}, },
}) })
@ -365,7 +371,7 @@ func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error {
title: gui.Tr.RebasingTitle, title: gui.Tr.RebasingTitle,
prompt: prompt, prompt: prompt,
handleConfirm: func() error { handleConfirm: func() error {
err := gui.GitCommand.RebaseBranch(selectedBranchName) err := gui.GitCommand.WithSpan("Rebase branch").RebaseBranch(selectedBranchName)
return gui.handleGenericMergeCommandResult(err) return gui.handleGenericMergeCommandResult(err)
}, },
}) })
@ -391,6 +397,8 @@ func (gui *Gui) handleFastForward() error {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
span := "Fast forward branch"
split := strings.Split(upstream, "/") split := strings.Split(upstream, "/")
remoteName := split[0] remoteName := split[0]
remoteBranchName := strings.Join(split[1:], "/") remoteBranchName := strings.Join(split[1:], "/")
@ -406,9 +414,9 @@ func (gui *Gui) handleFastForward() error {
_ = gui.createLoaderPanel(message) _ = gui.createLoaderPanel(message)
if gui.State.Panels.Branches.SelectedLineIdx == 0 { if gui.State.Panels.Branches.SelectedLineIdx == 0 {
_ = gui.pullWithMode("ff-only", PullFilesOptions{}) _ = gui.pullWithMode("ff-only", PullFilesOptions{span: span})
} else { } 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.handleCredentialsPopup(err)
_ = gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{BRANCHES}}) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{BRANCHES}})
} }
@ -436,7 +444,7 @@ func (gui *Gui) handleRenameBranch() error {
title: gui.Tr.NewBranchNamePrompt + " " + branch.Name + ":", title: gui.Tr.NewBranchNamePrompt + " " + branch.Name + ":",
initialContent: branch.Name, initialContent: branch.Name,
handleConfirm: func(newBranchName string) error { 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) return gui.surfaceError(err)
} }
@ -505,7 +513,7 @@ func (gui *Gui) handleNewBranchOffCurrentItem() error {
title: message, title: message,
initialContent: prefilledName, initialContent: prefilledName,
handleConfirm: func(response string) error { 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 return err
} }

View File

@ -148,7 +148,7 @@ func (gui *Gui) HandlePasteCommits() error {
prompt: gui.Tr.SureCherryPick, prompt: gui.Tr.SureCherryPick,
handleConfirm: func() error { handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.CherryPickingStatus, 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) return gui.handleGenericMergeCommandResult(err)
}) })
}, },

View File

@ -62,7 +62,7 @@ func (gui *Gui) handleCheckoutCommitFile() error {
return nil 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) return gui.surfaceError(err)
} }
@ -81,7 +81,7 @@ func (gui *Gui) handleDiscardOldFileChange() error {
prompt: gui.Tr.DiscardFileChangesPrompt, prompt: gui.Tr.DiscardFileChangesPrompt,
handleConfirm: func() error { handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.RebasingStatus, 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 { if err := gui.handleGenericMergeCommandResult(err); err != nil {
return err return err
} }

View File

@ -1,10 +1,12 @@
package gui package gui
import ( import (
"fmt"
"sync" "sync"
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
@ -169,7 +171,7 @@ func (gui *Gui) handleCommitSquashDown() error {
prompt: gui.Tr.SureSquashThisCommit, prompt: gui.Tr.SureSquashThisCommit,
handleConfirm: func() error { handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.SquashingStatus, 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) return gui.handleGenericMergeCommandResult(err)
}) })
}, },
@ -198,7 +200,7 @@ func (gui *Gui) handleCommitFixup() error {
prompt: gui.Tr.SureFixupThisCommit, prompt: gui.Tr.SureFixupThisCommit,
handleConfirm: func() error { handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.FixingStatus, 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) return gui.handleGenericMergeCommandResult(err)
}) })
}, },
@ -236,7 +238,7 @@ func (gui *Gui) handleRenameCommit() error {
title: gui.Tr.LcRenameCommit, title: gui.Tr.LcRenameCommit,
initialContent: message, initialContent: message,
handleConfirm: func(response string) error { 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) return gui.surfaceError(err)
} }
@ -258,7 +260,7 @@ func (gui *Gui) handleRenameCommitEditor() error {
return nil 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 { if err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
@ -286,6 +288,12 @@ func (gui *Gui) handleMidRebaseCommand(action string) (bool, error) {
return true, gui.createErrorPanel(gui.Tr.LcRewordNotSupported) 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 { if err := gui.GitCommand.EditRebaseTodo(gui.State.Panels.Commits.SelectedLineIdx, action); err != nil {
return false, gui.surfaceError(err) return false, gui.surfaceError(err)
} }
@ -311,7 +319,7 @@ func (gui *Gui) handleCommitDelete() error {
prompt: gui.Tr.DeleteCommitPrompt, prompt: gui.Tr.DeleteCommitPrompt,
handleConfirm: func() error { handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.DeletingStatus, 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) return gui.handleGenericMergeCommandResult(err)
}) })
}, },
@ -323,12 +331,23 @@ func (gui *Gui) handleCommitMoveDown() error {
return err return err
} }
span := "Move commit down"
index := gui.State.Panels.Commits.SelectedLineIdx index := gui.State.Panels.Commits.SelectedLineIdx
selectedCommit := gui.State.Commits[index] selectedCommit := gui.State.Commits[index]
if selectedCommit.Status == "rebasing" { if selectedCommit.Status == "rebasing" {
if gui.State.Commits[index+1].Status != "rebasing" { if gui.State.Commits[index+1].Status != "rebasing" {
return nil 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 { if err := gui.GitCommand.MoveTodoDown(index); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
@ -337,7 +356,7 @@ func (gui *Gui) handleCommitMoveDown() error {
} }
return gui.WithWaitingStatus(gui.Tr.MovingStatus, func() 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 { if err == nil {
gui.State.Panels.Commits.SelectedLineIdx++ gui.State.Panels.Commits.SelectedLineIdx++
} }
@ -354,8 +373,19 @@ func (gui *Gui) handleCommitMoveUp() error {
if index == 0 { if index == 0 {
return nil return nil
} }
span := "Move commit up"
selectedCommit := gui.State.Commits[index] selectedCommit := gui.State.Commits[index]
if selectedCommit.Status == "rebasing" { 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 { if err := gui.GitCommand.MoveTodoDown(index - 1); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
@ -364,7 +394,7 @@ func (gui *Gui) handleCommitMoveUp() error {
} }
return gui.WithWaitingStatus(gui.Tr.MovingStatus, func() 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 { if err == nil {
gui.State.Panels.Commits.SelectedLineIdx-- gui.State.Panels.Commits.SelectedLineIdx--
} }
@ -386,7 +416,7 @@ func (gui *Gui) handleCommitEdit() error {
} }
return gui.WithWaitingStatus(gui.Tr.RebasingStatus, func() 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) return gui.handleGenericMergeCommandResult(err)
}) })
} }
@ -401,7 +431,7 @@ func (gui *Gui) handleCommitAmendTo() error {
prompt: gui.Tr.AmendCommitPrompt, prompt: gui.Tr.AmendCommitPrompt,
handleConfirm: func() error { handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.AmendingStatus, 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) return gui.handleGenericMergeCommandResult(err)
}) })
}, },
@ -431,7 +461,7 @@ func (gui *Gui) handleCommitRevert() error {
return err 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) return gui.surfaceError(err)
} }
gui.State.Panels.Commits.SelectedLineIdx++ gui.State.Panels.Commits.SelectedLineIdx++
@ -468,7 +498,7 @@ func (gui *Gui) handleCreateFixupCommit() error {
title: gui.Tr.CreateFixupCommit, title: gui.Tr.CreateFixupCommit,
prompt: prompt, prompt: prompt,
handleConfirm: func() error { 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) return gui.surfaceError(err)
} }
@ -499,7 +529,7 @@ func (gui *Gui) handleSquashAllAboveFixupCommits() error {
prompt: prompt, prompt: prompt,
handleConfirm: func() error { handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.SquashingStatus, 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) return gui.handleGenericMergeCommandResult(err)
}) })
}, },
@ -522,7 +552,7 @@ func (gui *Gui) handleCreateLightweightTag(commitSha string) error {
return gui.prompt(promptOpts{ return gui.prompt(promptOpts{
title: gui.Tr.TagNameTitle, title: gui.Tr.TagNameTitle,
handleConfirm: func(response string) error { 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.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{COMMITS, TAGS}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{COMMITS, TAGS}})
@ -540,7 +570,7 @@ func (gui *Gui) handleCheckoutCommit() error {
title: gui.Tr.LcCheckoutCommit, title: gui.Tr.LcCheckoutCommit,
prompt: gui.Tr.SureCheckoutThisCommit, prompt: gui.Tr.SureCheckoutThisCommit,
handleConfirm: func() error { 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) 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) return gui.surfaceError(err)
} }

View File

@ -68,7 +68,7 @@ func (gui *Gui) handleCustomCommandKeybinding(customCommand config.CustomCommand
loadingText = gui.Tr.LcRunningCustomCommandStatus loadingText = gui.Tr.LcRunningCustomCommandStatus
} }
return gui.WithWaitingStatus(loadingText, func() error { 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.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{}) return gui.refreshSidePanels(refreshOptions{})

View File

@ -609,6 +609,8 @@ func (gui *Gui) handlePullFiles() error {
return nil return nil
} }
span := "Pull"
currentBranch := gui.currentBranch() currentBranch := gui.currentBranch()
if currentBranch == nil { if currentBranch == nil {
// need to wait for branches to refresh // need to wait for branches to refresh
@ -624,7 +626,7 @@ func (gui *Gui) handlePullFiles() error {
} }
for branchName, branch := range conf.Branches { for branchName, branch := range conf.Branches {
if branchName == currentBranch.Name { 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.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 { type PullFilesOptions struct {
RemoteName string RemoteName string
BranchName string BranchName string
span string
} }
func (gui *Gui) pullFiles(opts PullFilesOptions) error { func (gui *Gui) pullFiles(opts PullFilesOptions) error {
@ -669,7 +672,7 @@ func (gui *Gui) pullWithMode(mode string, opts PullFilesOptions) error {
gui.Mutexes.FetchMutex.Lock() gui.Mutexes.FetchMutex.Lock()
defer gui.Mutexes.FetchMutex.Unlock() defer gui.Mutexes.FetchMutex.Unlock()
gitCommand := gui.GitCommand.WithSpan("Pull") gitCommand := gui.GitCommand.WithSpan(opts.span)
err := gitCommand.Fetch( err := gitCommand.Fetch(
commands.FetchOptions{ commands.FetchOptions{

View File

@ -32,7 +32,7 @@ func (gui *Gui) gitFlowFinishBranch(gitFlowConfig string, branchName string) err
} }
return gui.runSubprocessWithSuspenseAndRefresh( 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, title: title,
handleConfirm: func(name string) error { handleConfirm: func(name string) error {
return gui.runSubprocessWithSuspenseAndRefresh( 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),
) )
}, },
}) })

View File

@ -200,7 +200,7 @@ func (gui *Gui) handleInfoClick() error {
return nil return nil
} }
func (gui *Gui) fetch(canPromptForCredentials bool) (err error) { func (gui *Gui) fetch(canPromptForCredentials bool, span string) (err error) {
gui.Mutexes.FetchMutex.Lock() gui.Mutexes.FetchMutex.Lock()
defer gui.Mutexes.FetchMutex.Unlock() defer gui.Mutexes.FetchMutex.Unlock()
@ -209,7 +209,7 @@ func (gui *Gui) fetch(canPromptForCredentials bool) (err error) {
fetchOpts.PromptUserForCredential = gui.promptUserForCredential 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") { if canPromptForCredentials && err != nil && strings.Contains(err.Error(), "exit status 128") {
_ = gui.createErrorPanel(gui.Tr.PassUnameWrong) _ = gui.createErrorPanel(gui.Tr.PassUnameWrong)
@ -228,7 +228,7 @@ func (gui *Gui) handleCopySelectedSideContextItemToClipboard() error {
return nil 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) return gui.surfaceError(err)
} }

View File

@ -744,7 +744,7 @@ func (gui *Gui) startBackgroundFetch() {
if !isNew { if !isNew {
time.After(time.Duration(userConfig.Refresher.FetchInterval) * time.Second) 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 { if err != nil && strings.Contains(err.Error(), "exit status 128") && isNew {
_ = gui.ask(askOpts{ _ = gui.ask(askOpts{
title: gui.Tr.NoAutomaticGitFetchTitle, title: gui.Tr.NoAutomaticGitFetchTitle,
@ -752,7 +752,7 @@ func (gui *Gui) startBackgroundFetch() {
}) })
} else { } else {
gui.goEvery(time.Second*time.Duration(userConfig.Refresher.FetchInterval), gui.stopChan, func() error { gui.goEvery(time.Second*time.Duration(userConfig.Refresher.FetchInterval), gui.stopChan, func() error {
err := gui.fetch(false) err := gui.fetch(false, "")
return err return err
}) })
} }

View File

@ -13,6 +13,7 @@ import (
"github.com/golang-collections/collections/stack" "github.com/golang-collections/collections/stack"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts" "github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts"
) )
@ -76,6 +77,7 @@ func (gui *Gui) handlePopFileSnapshot() error {
if gitFile == nil { if gitFile == nil {
return 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 { if err := ioutil.WriteFile(gitFile.Name, []byte(prevContent), 0644); err != nil {
return err return err
} }
@ -165,6 +167,17 @@ func (gui *Gui) resolveConflict(conflict commands.Conflict, selection mergeconfl
output += line 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) return ioutil.WriteFile(gitFile.Name, []byte(output), 0644)
} }

View File

@ -43,7 +43,7 @@ func (gui *Gui) genericMergeCommand(command string) error {
return gui.createErrorPanel(gui.Tr.NotMergingOrRebasing) 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) commandType := strings.Replace(status, "ing", "e", 1)
// we should end up with a command like 'git merge --continue' // we should end up with a command like 'git merge --continue'

View File

@ -92,7 +92,7 @@ func (gui *Gui) handleCheckoutReflogCommit() error {
title: gui.Tr.LcCheckoutCommit, title: gui.Tr.LcCheckoutCommit,
prompt: gui.Tr.SureCheckoutThisCommit, prompt: gui.Tr.SureCheckoutThisCommit,
handleConfirm: func() error { handleConfirm: func() error {
return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{}) return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{span: "Checkout reflog commit"})
}, },
}) })
if err != nil { if err != nil {

View File

@ -59,7 +59,7 @@ func (gui *Gui) handleDeleteRemoteBranch() error {
prompt: message, prompt: message,
handleConfirm: func() error { handleConfirm: func() error {
return gui.WithWaitingStatus(gui.Tr.DeletingStatus, 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) gui.handleCredentialsPopup(err)
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{BRANCHES, REMOTES}}) return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{BRANCHES, REMOTES}})
@ -89,7 +89,7 @@ func (gui *Gui) handleSetBranchUpstream() error {
title: gui.Tr.SetUpstreamTitle, title: gui.Tr.SetUpstreamTitle,
prompt: message, prompt: message,
handleConfirm: func() error { 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 return err
} }

View File

@ -85,7 +85,7 @@ func (gui *Gui) handleAddRemote() error {
return gui.prompt(promptOpts{ return gui.prompt(promptOpts{
title: gui.Tr.LcNewRemoteUrl, title: gui.Tr.LcNewRemoteUrl,
handleConfirm: func(remoteUrl string) error { 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 err
} }
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{REMOTES}}) return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{REMOTES}})
@ -106,7 +106,7 @@ func (gui *Gui) handleRemoveRemote() error {
title: gui.Tr.LcRemoveRemote, title: gui.Tr.LcRemoveRemote,
prompt: gui.Tr.LcRemoveRemotePrompt + " '" + remote.Name + "'?", prompt: gui.Tr.LcRemoveRemotePrompt + " '" + remote.Name + "'?",
handleConfirm: func() error { 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) return gui.surfaceError(err)
} }
@ -128,12 +128,14 @@ func (gui *Gui) handleEditRemote() error {
}, },
) )
gitCommand := gui.GitCommand.WithSpan("Update remote")
return gui.prompt(promptOpts{ return gui.prompt(promptOpts{
title: editNameMessage, title: editNameMessage,
initialContent: remote.Name, initialContent: remote.Name,
handleConfirm: func(updatedRemoteName string) error { handleConfirm: func(updatedRemoteName string) error {
if updatedRemoteName != remote.Name { 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) return gui.surfaceError(err)
} }
} }
@ -155,7 +157,7 @@ func (gui *Gui) handleEditRemote() error {
title: editUrlMessage, title: editUrlMessage,
initialContent: url, initialContent: url,
handleConfirm: func(updatedRemoteUrl string) error { 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.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{BRANCHES, REMOTES}}) return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{BRANCHES, REMOTES}})

View File

@ -48,7 +48,7 @@ func (gui *Gui) handleCheckoutSubCommit() error {
title: gui.Tr.LcCheckoutCommit, title: gui.Tr.LcCheckoutCommit,
prompt: gui.Tr.SureCheckoutThisCommit, prompt: gui.Tr.SureCheckoutThisCommit,
handleConfirm: func() error { handleConfirm: func() error {
return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{}) return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{span: "Checkout commit"})
}, },
}) })
if err != nil { if err != nil {

View File

@ -19,7 +19,7 @@ func (gui *Gui) handleCreateTag() error {
title: gui.Tr.CreateTagTitle, title: gui.Tr.CreateTagTitle,
handleConfirm: func(tagName string) error { handleConfirm: func(tagName string) error {
// leaving commit SHA blank so that we're just creating the tag for the current commit // 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.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{COMMITS, TAGS}, then: func() { 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 { 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 err
} }
return gui.pushContext(gui.State.Contexts.Branches) return gui.pushContext(gui.State.Contexts.Branches)
@ -104,7 +104,7 @@ func (gui *Gui) handleDeleteTag(tag *models.Tag) error {
title: gui.Tr.DeleteTagTitle, title: gui.Tr.DeleteTagTitle,
prompt: prompt, prompt: prompt,
handleConfirm: func() error { 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.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{COMMITS, TAGS}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{COMMITS, TAGS}})
@ -125,7 +125,7 @@ func (gui *Gui) handlePushTag(tag *models.Tag) error {
initialContent: "origin", initialContent: "origin",
handleConfirm: func(response string) error { handleConfirm: func(response string) error {
return gui.WithWaitingStatus(gui.Tr.PushingTagStatus, func() 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) gui.handleCredentialsPopup(err)
return nil return nil