1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-06 03:53:59 +02:00

better error handling

This commit is contained in:
Jesse Duffield 2020-03-28 11:47:54 +11:00
parent 7876cddf4a
commit 814ee24c8d
21 changed files with 108 additions and 173 deletions

View File

@ -1097,75 +1097,6 @@ func TestGitCommandUnstageFile(t *testing.T) {
} }
} }
// TestGitCommandIsInMergeState is a function.
func TestGitCommandIsInMergeState(t *testing.T) {
type scenario struct {
testName string
command func(string, ...string) *exec.Cmd
test func(bool, error)
}
scenarios := []scenario{
{
"An error occurred when running status command",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"status", "--untracked-files=all"}, args)
return exec.Command("test")
},
func(isInMergeState bool, err error) {
assert.Error(t, err)
assert.False(t, isInMergeState)
},
},
{
"Is not in merge state",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"status", "--untracked-files=all"}, args)
return exec.Command("echo")
},
func(isInMergeState bool, err error) {
assert.False(t, isInMergeState)
assert.NoError(t, err)
},
},
{
"Command output contains conclude merge",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"status", "--untracked-files=all"}, args)
return exec.Command("echo", "'conclude merge'")
},
func(isInMergeState bool, err error) {
assert.True(t, isInMergeState)
assert.NoError(t, err)
},
},
{
"Command output contains unmerged paths",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"status", "--untracked-files=all"}, args)
return exec.Command("echo", "'unmerged paths'")
},
func(isInMergeState bool, err error) {
assert.True(t, isInMergeState)
assert.NoError(t, err)
},
},
}
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommand()
gitCmd.OSCommand.command = s.command
s.test(gitCmd.IsInMergeState())
})
}
}
// TestGitCommandDiscardAllFileChanges is a function. // TestGitCommandDiscardAllFileChanges is a function.
func TestGitCommandDiscardAllFileChanges(t *testing.T) { func TestGitCommandDiscardAllFileChanges(t *testing.T) {
type scenario struct { type scenario struct {

View File

@ -72,7 +72,7 @@ func (gui *Gui) WithWaitingStatus(name string, f func() error) error {
if err := f(); err != nil { if err := f(); err != nil {
gui.g.Update(func(g *gocui.Gui) error { gui.g.Update(func(g *gocui.Gui) error {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
}) })
} }
}() }()

View File

@ -56,13 +56,13 @@ func (gui *Gui) handleBranchSelect(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) refreshBranches() { func (gui *Gui) refreshBranches() {
builder, err := commands.NewBranchListBuilder(gui.Log, gui.GitCommand, gui.State.ReflogCommits) builder, err := commands.NewBranchListBuilder(gui.Log, gui.GitCommand, gui.State.ReflogCommits)
if err != nil { if err != nil {
_ = gui.createErrorPanel(gui.g, err.Error()) _ = gui.surfaceError(err)
} }
gui.State.Branches = builder.Build() gui.State.Branches = builder.Build()
// TODO: if we're in the remotes view and we've just deleted a remote we need to refresh accordingly // TODO: if we're in the remotes view and we've just deleted a remote we need to refresh accordingly
if gui.getBranchesView().Context == "local-branches" { if gui.getBranchesView().Context == "local-branches" {
gui.renderLocalBranchesWithSelection() _ = gui.renderLocalBranchesWithSelection()
} }
gui.refreshStatus() gui.refreshStatus()
@ -76,7 +76,7 @@ func (gui *Gui) renderLocalBranchesWithSelection() error {
gui.renderDisplayStrings(branchesView, displayStrings) gui.renderDisplayStrings(branchesView, displayStrings)
if gui.g.CurrentView() == branchesView { if gui.g.CurrentView() == branchesView {
if err := gui.handleBranchSelect(gui.g, branchesView); err != nil { if err := gui.handleBranchSelect(gui.g, branchesView); err != nil {
return err return gui.surfaceError(err)
} }
} }
@ -90,7 +90,7 @@ func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
if gui.State.Panels.Branches.SelectedLine == 0 { if gui.State.Panels.Branches.SelectedLine == 0 {
return gui.createErrorPanel(g, gui.Tr.SLocalize("AlreadyCheckedOutBranch")) return gui.createErrorPanel(gui.Tr.SLocalize("AlreadyCheckedOutBranch"))
} }
branch := gui.getSelectedBranch() branch := gui.getSelectedBranch()
return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{}) return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{})
@ -101,7 +101,7 @@ func (gui *Gui) handleCreatePullRequestPress(g *gocui.Gui, v *gocui.View) error
branch := gui.getSelectedBranch() branch := gui.getSelectedBranch()
if err := pullRequest.Create(branch); err != nil { if err := pullRequest.Create(branch); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
return nil return nil
@ -124,7 +124,7 @@ func (gui *Gui) handleForceCheckout(g *gocui.Gui, v *gocui.View) error {
title := gui.Tr.SLocalize("ForceCheckoutBranch") title := gui.Tr.SLocalize("ForceCheckoutBranch")
return gui.createConfirmationPanel(g, v, true, title, message, func(g *gocui.Gui, v *gocui.View) error { return gui.createConfirmationPanel(g, v, true, title, message, func(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.Checkout(branch.Name, commands.CheckoutOptions{Force: true}); err != nil { if err := gui.GitCommand.Checkout(branch.Name, commands.CheckoutOptions{Force: true}); err != nil {
_ = gui.createErrorPanel(g, err.Error()) _ = gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
}, nil) }, nil)
@ -159,10 +159,10 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions)
return gui.createConfirmationPanel(gui.g, gui.getBranchesView(), true, gui.Tr.SLocalize("AutoStashTitle"), gui.Tr.SLocalize("AutoStashPrompt"), func(g *gocui.Gui, v *gocui.View) error { return gui.createConfirmationPanel(gui.g, gui.getBranchesView(), true, gui.Tr.SLocalize("AutoStashTitle"), gui.Tr.SLocalize("AutoStashPrompt"), func(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.StashSave(gui.Tr.SLocalize("StashPrefix") + ref); err != nil { if err := gui.GitCommand.StashSave(gui.Tr.SLocalize("StashPrefix") + ref); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
if err := gui.GitCommand.Checkout(ref, cmdOptions); err != nil { if err := gui.GitCommand.Checkout(ref, cmdOptions); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
onSuccess() onSuccess()
@ -170,13 +170,13 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions)
if err := gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI}); err != nil { if err := gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI}); err != nil {
return err return err
} }
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI}) return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI})
}, nil) }, nil)
} }
if err := gui.createErrorPanel(gui.g, err.Error()); err != nil { if err := gui.surfaceError(err); err != nil {
return err return err
} }
} }
@ -213,7 +213,7 @@ func (gui *Gui) handleNewBranch(g *gocui.Gui, v *gocui.View) error {
) )
return gui.createPromptPanel(g, v, message, "", func(g *gocui.Gui, v *gocui.View) error { return gui.createPromptPanel(g, v, message, "", func(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.NewBranch(gui.trimmedContent(v), branch.Name); err != nil { if err := gui.GitCommand.NewBranch(gui.trimmedContent(v), branch.Name); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
gui.State.Panels.Branches.SelectedLine = 0 gui.State.Panels.Branches.SelectedLine = 0
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
@ -231,7 +231,7 @@ func (gui *Gui) deleteBranch(g *gocui.Gui, v *gocui.View, force bool) error {
} }
checkedOutBranch := gui.getCheckedOutBranch() checkedOutBranch := gui.getCheckedOutBranch()
if checkedOutBranch.Name == selectedBranch.Name { if checkedOutBranch.Name == selectedBranch.Name {
return gui.createErrorPanel(g, gui.Tr.SLocalize("CantDeleteCheckOutBranch")) return gui.createErrorPanel(gui.Tr.SLocalize("CantDeleteCheckOutBranch"))
} }
return gui.deleteNamedBranch(g, v, selectedBranch, force) return gui.deleteNamedBranch(g, v, selectedBranch, force)
} }
@ -256,7 +256,7 @@ func (gui *Gui) deleteNamedBranch(g *gocui.Gui, v *gocui.View, selectedBranch *c
if !force && strings.Contains(errMessage, "is not fully merged") { if !force && strings.Contains(errMessage, "is not fully merged") {
return gui.deleteNamedBranch(g, v, selectedBranch, true) return gui.deleteNamedBranch(g, v, selectedBranch, true)
} }
return gui.createErrorPanel(g, errMessage) return gui.createErrorPanel(errMessage)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{BRANCHES}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{BRANCHES}})
}, nil) }, nil)
@ -264,11 +264,11 @@ func (gui *Gui) deleteNamedBranch(g *gocui.Gui, v *gocui.View, selectedBranch *c
func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error { func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error {
if gui.GitCommand.IsHeadDetached() { if gui.GitCommand.IsHeadDetached() {
return gui.createErrorPanel(gui.g, "Cannot merge branch in detached head state. You might have checked out a commit directly or a remote branch, in which case you should checkout the local branch you want to be on") return gui.createErrorPanel("Cannot merge branch in detached head state. You might have checked out a commit directly or a remote branch, in which case you should checkout the local branch you want to be on")
} }
checkedOutBranchName := gui.getCheckedOutBranch().Name checkedOutBranchName := gui.getCheckedOutBranch().Name
if checkedOutBranchName == branchName { if checkedOutBranchName == branchName {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("CantMergeBranchIntoItself")) return gui.createErrorPanel(gui.Tr.SLocalize("CantMergeBranchIntoItself"))
} }
prompt := gui.Tr.TemplateLocalize( prompt := gui.Tr.TemplateLocalize(
"ConfirmMerge", "ConfirmMerge",
@ -298,7 +298,7 @@ func (gui *Gui) handleRebaseOntoLocalBranch(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error { func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error {
checkedOutBranch := gui.getCheckedOutBranch().Name checkedOutBranch := gui.getCheckedOutBranch().Name
if selectedBranchName == checkedOutBranch { if selectedBranchName == checkedOutBranch {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("CantRebaseOntoSelf")) return gui.createErrorPanel(gui.Tr.SLocalize("CantRebaseOntoSelf"))
} }
prompt := gui.Tr.TemplateLocalize( prompt := gui.Tr.TemplateLocalize(
"ConfirmRebase", "ConfirmRebase",
@ -323,15 +323,15 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
if branch.Pushables == "?" { if branch.Pushables == "?" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("FwdNoUpstream")) return gui.createErrorPanel(gui.Tr.SLocalize("FwdNoUpstream"))
} }
if branch.Pushables != "0" { if branch.Pushables != "0" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("FwdCommitsToPush")) return gui.createErrorPanel(gui.Tr.SLocalize("FwdCommitsToPush"))
} }
upstream, err := gui.GitCommand.GetUpstreamForBranch(branch.Name) upstream, err := gui.GitCommand.GetUpstreamForBranch(branch.Name)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
split := strings.Split(upstream, "/") split := strings.Split(upstream, "/")
@ -350,12 +350,12 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error {
if gui.State.Panels.Branches.SelectedLine == 0 { if gui.State.Panels.Branches.SelectedLine == 0 {
if err := gui.GitCommand.PullWithoutPasswordCheck("--ff-only"); err != nil { if err := gui.GitCommand.PullWithoutPasswordCheck("--ff-only"); err != nil {
_ = gui.createErrorPanel(gui.g, err.Error()) _ = gui.surfaceError(err)
} }
_ = gui.refreshSidePanels(refreshOptions{mode: ASYNC}) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC})
} else { } else {
if err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName); err != nil { if err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName); err != nil {
_ = gui.createErrorPanel(gui.g, err.Error()) _ = gui.surfaceError(err)
} }
_ = gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{BRANCHES}}) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{BRANCHES}})
} }
@ -459,12 +459,12 @@ func (gui *Gui) handleRenameBranch(g *gocui.Gui, v *gocui.View) error {
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("NewBranchNamePrompt")+" "+branch.Name+":", "", func(g *gocui.Gui, v *gocui.View) error { return gui.createPromptPanel(g, v, gui.Tr.SLocalize("NewBranchNamePrompt")+" "+branch.Name+":", "", func(g *gocui.Gui, v *gocui.View) error {
newName := gui.trimmedContent(v) newName := gui.trimmedContent(v)
if err := gui.GitCommand.RenameBranch(branch.Name, newName); err != nil { if err := gui.GitCommand.RenameBranch(branch.Name, newName); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
// need to checkout so that the branch shows up in our reflog and therefore // need to checkout so that the branch shows up in our reflog and therefore
// doesn't get lost among all the other branches when we switch to something else // doesn't get lost among all the other branches when we switch to something else
if err := gui.GitCommand.Checkout(newName, commands.CheckoutOptions{Force: false}); err != nil { if err := gui.GitCommand.Checkout(newName, commands.CheckoutOptions{Force: false}); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})

View File

@ -64,7 +64,7 @@ func (gui *Gui) handleCheckoutCommitFile(g *gocui.Gui, v *gocui.View) error {
file := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine] file := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine]
if err := gui.GitCommand.CheckoutFile(file.Sha, file.Name); err != nil { if err := gui.GitCommand.CheckoutFile(file.Sha, file.Name); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
@ -106,7 +106,7 @@ func (gui *Gui) refreshCommitFilesView() error {
files, err := gui.GitCommand.GetCommitFiles(commit.Sha, gui.GitCommand.PatchManager) files, err := gui.GitCommand.GetCommitFiles(commit.Sha, gui.GitCommand.PatchManager)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
gui.State.CommitFiles = files gui.State.CommitFiles = files

View File

@ -15,7 +15,7 @@ import (
func (gui *Gui) runSyncOrAsyncCommand(sub *exec.Cmd, err error) (bool, error) { func (gui *Gui) runSyncOrAsyncCommand(sub *exec.Cmd, err error) (bool, error) {
if err != nil { if err != nil {
if err != gui.Errors.ErrSubProcess { if err != gui.Errors.ErrSubProcess {
return false, gui.createErrorPanel(gui.g, err.Error()) return false, gui.surfaceError(err)
} }
} }
if sub != nil { if sub != nil {
@ -28,7 +28,7 @@ func (gui *Gui) runSyncOrAsyncCommand(sub *exec.Cmd, err error) (bool, error) {
func (gui *Gui) handleCommitConfirm(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitConfirm(g *gocui.Gui, v *gocui.View) error {
message := gui.trimmedContent(v) message := gui.trimmedContent(v)
if message == "" { if message == "" {
return gui.createErrorPanel(g, gui.Tr.SLocalize("CommitWithoutMessageErr")) return gui.createErrorPanel(gui.Tr.SLocalize("CommitWithoutMessageErr"))
} }
flags := "" flags := ""
skipHookPrefix := gui.Config.GetUserConfig().GetString("git.skipHookPrefix") skipHookPrefix := gui.Config.GetUserConfig().GetString("git.skipHookPrefix")

View File

@ -40,7 +40,7 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
state.LimitCommits = false state.LimitCommits = false
go func() { go func() {
if err := gui.refreshCommitsWithLimit(); err != nil { if err := gui.refreshCommitsWithLimit(); err != nil {
_ = gui.createErrorPanel(gui.g, err.Error()) _ = gui.surfaceError(err)
} }
}() }()
} }
@ -79,13 +79,13 @@ func (gui *Gui) refreshReflogCommitsConsideringStartup() {
switch gui.State.StartupStage { switch gui.State.StartupStage {
case INITIAL: case INITIAL:
go func() { go func() {
gui.refreshReflogCommits() _ = gui.refreshReflogCommits()
gui.refreshBranches() gui.refreshBranches()
gui.State.StartupStage = COMPLETE gui.State.StartupStage = COMPLETE
}() }()
case COMPLETE: case COMPLETE:
gui.refreshReflogCommits() _ = gui.refreshReflogCommits()
} }
} }
@ -104,9 +104,9 @@ func (gui *Gui) refreshCommits() error {
}() }()
go func() { go func() {
gui.refreshCommitsWithLimit() _ = gui.refreshCommitsWithLimit()
if gui.g.CurrentView() == gui.getCommitFilesView() || (gui.g.CurrentView() == gui.getMainView() && gui.State.MainContext == "patch-building") { if gui.g.CurrentView() == gui.getCommitFilesView() || (gui.g.CurrentView() == gui.getMainView() && gui.State.MainContext == "patch-building") {
gui.refreshCommitFilesView() _ = gui.refreshCommitFilesView()
} }
wg.Done() wg.Done()
}() }()
@ -141,7 +141,7 @@ func (gui *Gui) refreshCommitsWithLimit() error {
func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
if len(gui.State.Commits) <= 1 { if len(gui.State.Commits) <= 1 {
return gui.createErrorPanel(g, gui.Tr.SLocalize("YouNoCommitsToSquash")) return gui.createErrorPanel(gui.Tr.SLocalize("YouNoCommitsToSquash"))
} }
applied, err := gui.handleMidRebaseCommand("squash") applied, err := gui.handleMidRebaseCommand("squash")
@ -162,7 +162,7 @@ func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error {
if len(gui.State.Commits) <= 1 { if len(gui.State.Commits) <= 1 {
return gui.createErrorPanel(g, gui.Tr.SLocalize("YouNoCommitsToSquash")) return gui.createErrorPanel(gui.Tr.SLocalize("YouNoCommitsToSquash"))
} }
applied, err := gui.handleMidRebaseCommand("fixup") applied, err := gui.handleMidRebaseCommand("fixup")
@ -191,11 +191,11 @@ func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
} }
if gui.State.Panels.Commits.SelectedLine != 0 { if gui.State.Panels.Commits.SelectedLine != 0 {
return gui.createErrorPanel(g, gui.Tr.SLocalize("OnlyRenameTopCommit")) return gui.createErrorPanel(gui.Tr.SLocalize("OnlyRenameTopCommit"))
} }
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("renameCommit"), "", func(g *gocui.Gui, v *gocui.View) error { return gui.createPromptPanel(g, v, gui.Tr.SLocalize("renameCommit"), "", func(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.RenameCommit(v.Buffer()); err != nil { if err := gui.GitCommand.RenameCommit(v.Buffer()); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
@ -213,7 +213,7 @@ func (gui *Gui) handleRenameCommitEditor(g *gocui.Gui, v *gocui.View) error {
subProcess, err := gui.GitCommand.RewordCommit(gui.State.Commits, gui.State.Panels.Commits.SelectedLine) subProcess, err := gui.GitCommand.RewordCommit(gui.State.Commits, gui.State.Panels.Commits.SelectedLine)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
if subProcess != nil { if subProcess != nil {
gui.SubProcess = subProcess gui.SubProcess = subProcess
@ -237,11 +237,11 @@ func (gui *Gui) handleMidRebaseCommand(action string) (bool, error) {
// our input or we set a lazygit client as the EDITOR env variable and have it // our input or we set a lazygit client as the EDITOR env variable and have it
// request us to edit the commit message when prompted. // request us to edit the commit message when prompted.
if action == "reword" { if action == "reword" {
return true, gui.createErrorPanel(gui.g, gui.Tr.SLocalize("rewordNotSupported")) return true, gui.createErrorPanel(gui.Tr.SLocalize("rewordNotSupported"))
} }
if err := gui.GitCommand.EditRebaseTodo(gui.State.Panels.Commits.SelectedLine, action); err != nil { if err := gui.GitCommand.EditRebaseTodo(gui.State.Panels.Commits.SelectedLine, action); err != nil {
return false, gui.createErrorPanel(gui.g, err.Error()) return false, gui.surfaceError(err)
} }
// TODO: consider doing this in a way that is less expensive. We don't actually // TODO: consider doing this in a way that is less expensive. We don't actually
// need to reload all the commits, just the TODO commits. // need to reload all the commits, just the TODO commits.
@ -273,7 +273,7 @@ func (gui *Gui) handleCommitMoveDown(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
if err := gui.GitCommand.MoveTodoDown(index); err != nil { if err := gui.GitCommand.MoveTodoDown(index); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
gui.State.Panels.Commits.SelectedLine++ gui.State.Panels.Commits.SelectedLine++
return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI, scope: []int{COMMITS, BRANCHES}}) return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI, scope: []int{COMMITS, BRANCHES}})
@ -296,7 +296,7 @@ func (gui *Gui) handleCommitMoveUp(g *gocui.Gui, v *gocui.View) error {
selectedCommit := gui.State.Commits[index] selectedCommit := gui.State.Commits[index]
if selectedCommit.Status == "rebasing" { if selectedCommit.Status == "rebasing" {
if err := gui.GitCommand.MoveTodoDown(index - 1); err != nil { if err := gui.GitCommand.MoveTodoDown(index - 1); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
gui.State.Panels.Commits.SelectedLine-- gui.State.Panels.Commits.SelectedLine--
return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI, scope: []int{COMMITS, BRANCHES}}) return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI, scope: []int{COMMITS, BRANCHES}})
@ -351,7 +351,7 @@ func (gui *Gui) handleCommitPick(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleCommitRevert(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitRevert(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.Revert(gui.State.Commits[gui.State.Panels.Commits.SelectedLine].Sha); err != nil { if err := gui.GitCommand.Revert(gui.State.Commits[gui.State.Panels.Commits.SelectedLine].Sha); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
gui.State.Panels.Commits.SelectedLine++ gui.State.Panels.Commits.SelectedLine++
return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI, scope: []int{COMMITS, BRANCHES}}) return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI, scope: []int{COMMITS, BRANCHES}})
@ -462,7 +462,7 @@ func (gui *Gui) handleToggleDiffCommit(g *gocui.Gui, v *gocui.View) error {
commitText, err := gui.GitCommand.DiffCommits(gui.State.DiffEntries[0].Sha, gui.State.DiffEntries[1].Sha) commitText, err := gui.GitCommand.DiffCommits(gui.State.DiffEntries[0].Sha, gui.State.DiffEntries[1].Sha)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
gui.newStringTask("main", commitText) gui.newStringTask("main", commitText)
@ -507,7 +507,7 @@ func (gui *Gui) handleCreateFixupCommit(g *gocui.Gui, v *gocui.View) error {
}, },
), func(g *gocui.Gui, v *gocui.View) error { ), func(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.CreateFixupCommit(commit.Sha); err != nil { if err := gui.GitCommand.CreateFixupCommit(commit.Sha); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
@ -548,7 +548,7 @@ func (gui *Gui) handleTagCommit(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleCreateLightweightTag(commitSha string) error { func (gui *Gui) handleCreateLightweightTag(commitSha string) error {
return gui.createPromptPanel(gui.g, gui.getCommitsView(), gui.Tr.SLocalize("TagNameTitle"), "", func(g *gocui.Gui, v *gocui.View) error { return gui.createPromptPanel(gui.g, gui.getCommitsView(), gui.Tr.SLocalize("TagNameTitle"), "", func(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.CreateLightweightTag(v.Buffer(), commitSha); err != nil { if err := gui.GitCommand.CreateLightweightTag(v.Buffer(), commitSha); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{COMMITS, TAGS}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{COMMITS, TAGS}})
}) })
@ -633,7 +633,7 @@ func (gui *Gui) handlePrevCommitsTab(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleCreateCommitResetMenu(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCreateCommitResetMenu(g *gocui.Gui, v *gocui.View) error {
commit := gui.getSelectedCommit(g) commit := gui.getSelectedCommit(g)
if commit == nil { if commit == nil {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("NoCommitsThisBranch")) return gui.createErrorPanel(gui.Tr.SLocalize("NoCommitsThisBranch"))
} }
return gui.createResetMenu(commit.Sha) return gui.createResetMenu(commit.Sha)

View File

@ -182,6 +182,10 @@ func (gui *Gui) createSpecificErrorPanel(message string, nextView *gocui.View, w
return gui.createConfirmationPanel(gui.g, nextView, true, gui.Tr.SLocalize("Error"), coloredMessage, nil, nil) return gui.createConfirmationPanel(gui.g, nextView, true, gui.Tr.SLocalize("Error"), coloredMessage, nil, nil)
} }
func (gui *Gui) createErrorPanel(g *gocui.Gui, message string) error { func (gui *Gui) createErrorPanel(message string) error {
return gui.createSpecificErrorPanel(message, g.CurrentView(), true) return gui.createSpecificErrorPanel(message, gui.g.CurrentView(), true)
}
func (gui *Gui) surfaceError(err error) error {
return gui.createErrorPanel(err.Error())
} }

View File

@ -163,7 +163,7 @@ func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error
return gui.handleSwitchToMerge(gui.g, gui.getFilesView()) return gui.handleSwitchToMerge(gui.g, gui.getFilesView())
} }
if file.HasMergeConflicts { if file.HasMergeConflicts {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("FileStagingRequirements")) return gui.createErrorPanel(gui.Tr.SLocalize("FileStagingRequirements"))
} }
gui.changeMainViewsContext("staging") gui.changeMainViewsContext("staging")
if err := gui.switchFocus(gui.g, gui.getFilesView(), gui.getMainView()); err != nil { if err := gui.switchFocus(gui.g, gui.getFilesView(), gui.getMainView()); err != nil {
@ -191,7 +191,7 @@ func (gui *Gui) handleFilePress(g *gocui.Gui, v *gocui.View) error {
err = gui.GitCommand.UnStageFile(file.Name, file.Tracked) err = gui.GitCommand.UnStageFile(file.Name, file.Tracked)
} }
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}); err != nil { if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}); err != nil {
@ -226,7 +226,7 @@ func (gui *Gui) handleStageAll(g *gocui.Gui, v *gocui.View) error {
err = gui.GitCommand.StageAll() err = gui.GitCommand.StageAll()
} }
if err != nil { if err != nil {
_ = gui.createErrorPanel(g, err.Error()) _ = gui.surfaceError(err)
} }
if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}); err != nil { if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}); err != nil {
@ -239,7 +239,7 @@ func (gui *Gui) handleStageAll(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleIgnoreFile(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleIgnoreFile(g *gocui.Gui, v *gocui.View) error {
file, err := gui.getSelectedFile(gui.g) file, err := gui.getSelectedFile(gui.g)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
if file.Tracked { if file.Tracked {
@ -257,7 +257,7 @@ func (gui *Gui) handleIgnoreFile(g *gocui.Gui, v *gocui.View) error {
} }
if err := gui.GitCommand.Ignore(file.Name); err != nil { if err := gui.GitCommand.Ignore(file.Name); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{FILES}})
@ -266,7 +266,7 @@ func (gui *Gui) handleIgnoreFile(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleWIPCommitPress(g *gocui.Gui, filesView *gocui.View) error { func (gui *Gui) handleWIPCommitPress(g *gocui.Gui, filesView *gocui.View) error {
skipHookPreifx := gui.Config.GetUserConfig().GetString("git.skipHookPrefix") skipHookPreifx := gui.Config.GetUserConfig().GetString("git.skipHookPrefix")
if skipHookPreifx == "" { if skipHookPreifx == "" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("SkipHookPrefixNotConfigured")) return gui.createErrorPanel(gui.Tr.SLocalize("SkipHookPrefixNotConfigured"))
} }
gui.renderString(g, "commitMessage", skipHookPreifx) gui.renderString(g, "commitMessage", skipHookPreifx)
@ -279,7 +279,7 @@ func (gui *Gui) handleWIPCommitPress(g *gocui.Gui, filesView *gocui.View) error
func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error { func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" { if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" {
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit")) return gui.createErrorPanel(gui.Tr.SLocalize("NoStagedFilesToCommit"))
} }
commitMessageView := gui.getCommitMessageView() commitMessageView := gui.getCommitMessageView()
g.Update(func(g *gocui.Gui) error { g.Update(func(g *gocui.Gui) error {
@ -299,10 +299,10 @@ func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
func (gui *Gui) handleAmendCommitPress(g *gocui.Gui, filesView *gocui.View) error { func (gui *Gui) handleAmendCommitPress(g *gocui.Gui, filesView *gocui.View) error {
if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" { if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" {
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit")) return gui.createErrorPanel(gui.Tr.SLocalize("NoStagedFilesToCommit"))
} }
if len(gui.State.Commits) == 0 { if len(gui.State.Commits) == 0 {
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoCommitToAmend")) return gui.createErrorPanel(gui.Tr.SLocalize("NoCommitToAmend"))
} }
title := strings.Title(gui.Tr.SLocalize("AmendLastCommit")) title := strings.Title(gui.Tr.SLocalize("AmendLastCommit"))
@ -325,7 +325,7 @@ func (gui *Gui) handleAmendCommitPress(g *gocui.Gui, filesView *gocui.View) erro
// their editor rather than via the popup panel // their editor rather than via the popup panel
func (gui *Gui) handleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) error { func (gui *Gui) handleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) error {
if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" { if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" {
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit")) return gui.createErrorPanel(gui.Tr.SLocalize("NoStagedFilesToCommit"))
} }
gui.PrepareSubProcess(g, "git", "commit") gui.PrepareSubProcess(g, "git", "commit")
return nil return nil
@ -347,7 +347,7 @@ func (gui *Gui) editFile(filename string) error {
func (gui *Gui) handleFileEdit(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleFileEdit(g *gocui.Gui, v *gocui.View) error {
file, err := gui.getSelectedFile(g) file, err := gui.getSelectedFile(g)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.editFile(file.Name) return gui.editFile(file.Name)
@ -356,7 +356,7 @@ func (gui *Gui) handleFileEdit(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error {
file, err := gui.getSelectedFile(g) file, err := gui.getSelectedFile(g)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.openFile(file.Name) return gui.openFile(file.Name)
} }
@ -404,7 +404,7 @@ func (gui *Gui) handlePullFiles(g *gocui.Gui, v *gocui.View) error {
// see if we have this branch in our config with an upstream // see if we have this branch in our config with an upstream
conf, err := gui.GitCommand.Repo.Config() conf, err := gui.GitCommand.Repo.Config()
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
for branchName, branch := range conf.Branches { for branchName, branch := range conf.Branches {
if branchName == currentBranch.Name { if branchName == currentBranch.Name {
@ -419,7 +419,7 @@ func (gui *Gui) handlePullFiles(g *gocui.Gui, v *gocui.View) error {
if strings.Contains(errorMessage, "does not exist") { if strings.Contains(errorMessage, "does not exist") {
errorMessage = fmt.Sprintf("upstream branch %s not found.\nIf you expect it to exist, you should fetch (with 'f').\nOtherwise, you should push (with 'shift+P')", upstream) errorMessage = fmt.Sprintf("upstream branch %s not found.\nIf you expect it to exist, you should fetch (with 'f').\nOtherwise, you should push (with 'shift+P')", upstream)
} }
return gui.createErrorPanel(gui.g, errorMessage) return gui.createErrorPanel(errorMessage)
} }
return gui.pullFiles(v, "") return gui.pullFiles(v, "")
}) })
@ -469,7 +469,7 @@ func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
// see if we have this branch in our config with an upstream // see if we have this branch in our config with an upstream
conf, err := gui.GitCommand.Repo.Config() conf, err := gui.GitCommand.Repo.Config()
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
for branchName, branch := range conf.Branches { for branchName, branch := range conf.Branches {
if branchName == currentBranch.Name { if branchName == currentBranch.Name {
@ -492,12 +492,12 @@ func (gui *Gui) handleSwitchToMerge(g *gocui.Gui, v *gocui.View) error {
file, err := gui.getSelectedFile(g) file, err := gui.getSelectedFile(g)
if err != nil { if err != nil {
if err != gui.Errors.ErrNoFiles { if err != gui.Errors.ErrNoFiles {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return nil return nil
} }
if !file.HasInlineMergeConflicts { if !file.HasInlineMergeConflicts {
return gui.createErrorPanel(g, gui.Tr.SLocalize("FileNoMergeCons")) return gui.createErrorPanel(gui.Tr.SLocalize("FileNoMergeCons"))
} }
gui.changeMainViewsContext("merging") gui.changeMainViewsContext("merging")
if err := gui.switchFocus(g, v, gui.getMainView()); err != nil { if err := gui.switchFocus(g, v, gui.getMainView()); err != nil {
@ -508,7 +508,7 @@ func (gui *Gui) handleSwitchToMerge(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) openFile(filename string) error { func (gui *Gui) openFile(filename string) error {
if err := gui.OSCommand.OpenFile(filename); err != nil { if err := gui.OSCommand.OpenFile(filename); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return nil return nil
} }

View File

@ -28,7 +28,7 @@ func (gui *Gui) gitFlowFinishBranch(gitFlowConfig string, branchName string) err
} }
if branchType == "" { if branchType == "" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("NotAGitFlowBranch")) return gui.createErrorPanel(gui.Tr.SLocalize("NotAGitFlowBranch"))
} }
subProcess := gui.OSCommand.PrepareSubProcess("git", "flow", branchType, "finish", suffix) subProcess := gui.OSCommand.PrepareSubProcess("git", "flow", branchType, "finish", suffix)
@ -45,7 +45,7 @@ func (gui *Gui) handleCreateGitFlowMenu(g *gocui.Gui, v *gocui.View) error {
// get config // get config
gitFlowConfig, err := gui.OSCommand.RunCommandWithOutput("git config --local --get-regexp gitflow") gitFlowConfig, err := gui.OSCommand.RunCommandWithOutput("git config --local --get-regexp gitflow")
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, "You need to install git-flow and enable it in this repo to use git-flow features") return gui.createErrorPanel("You need to install git-flow and enable it in this repo to use git-flow features")
} }
startHandler := func(branchType string) func() error { startHandler := func(branchType string) func() error {

View File

@ -885,7 +885,7 @@ func (gui *Gui) showInitialPopups(tasks []func(chan struct{}) error) {
for _, task := range tasks { for _, task := range tasks {
go func() { go func() {
if err := task(done); err != nil { if err := task(done); err != nil {
_ = gui.createErrorPanel(gui.g, err.Error()) _ = gui.surfaceError(err)
} }
}() }()

View File

@ -8,7 +8,7 @@ import (
func (gui *Gui) handleCreatePatchOptionsMenu(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCreatePatchOptionsMenu(g *gocui.Gui, v *gocui.View) error {
if !gui.GitCommand.PatchManager.CommitSelected() { if !gui.GitCommand.PatchManager.CommitSelected() {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("NoPatchError")) return gui.createErrorPanel(gui.Tr.SLocalize("NoPatchError"))
} }
menuItems := []*menuItem{ menuItems := []*menuItem{
@ -60,7 +60,7 @@ func (gui *Gui) getPatchCommitIndex() int {
func (gui *Gui) validateNormalWorkingTreeState() (bool, error) { func (gui *Gui) validateNormalWorkingTreeState() (bool, error) {
if gui.workingTreeState() != "normal" { if gui.workingTreeState() != "normal" {
return false, gui.createErrorPanel(gui.g, gui.Tr.SLocalize("CantPatchWhileRebasingError")) return false, gui.createErrorPanel(gui.Tr.SLocalize("CantPatchWhileRebasingError"))
} }
return true, nil return true, nil
} }
@ -126,7 +126,7 @@ func (gui *Gui) handleApplyPatch() error {
} }
if err := gui.GitCommand.PatchManager.ApplyPatches(false); err != nil { if err := gui.GitCommand.PatchManager.ApplyPatches(false); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
} }

View File

@ -40,7 +40,7 @@ func (gui *Gui) genericMergeCommand(command string) error {
status := gui.workingTreeState() status := gui.workingTreeState()
if status != "merging" && status != "rebasing" { if status != "merging" && status != "rebasing" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("NotMergingOrRebasing")) return gui.createErrorPanel(gui.Tr.SLocalize("NotMergingOrRebasing"))
} }
commandType := strings.Replace(status, "ing", "e", 1) commandType := strings.Replace(status, "ing", "e", 1)
@ -83,6 +83,6 @@ func (gui *Gui) handleGenericMergeCommandResult(result error) error {
}, },
) )
} else { } else {
return gui.createErrorPanel(gui.g, result.Error()) return gui.createErrorPanel(result.Error())
} }
} }

View File

@ -54,7 +54,7 @@ func (gui *Gui) refreshReflogCommits() error {
commits, onlyObtainedNewReflogCommits, err := gui.GitCommand.GetReflogCommits(lastReflogCommit) commits, onlyObtainedNewReflogCommits, err := gui.GitCommand.GetReflogCommits(lastReflogCommit)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
if onlyObtainedNewReflogCommits { if onlyObtainedNewReflogCommits {

View File

@ -49,7 +49,7 @@ func (gui *Gui) refreshRemotes() error {
remotes, err := gui.GitCommand.GetRemotes() remotes, err := gui.GitCommand.GetRemotes()
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
gui.State.Remotes = remotes gui.State.Remotes = remotes
@ -158,7 +158,7 @@ func (gui *Gui) handleEditRemote(g *gocui.Gui, v *gocui.View) error {
if updatedRemoteName != remote.Name { if updatedRemoteName != remote.Name {
if err := gui.GitCommand.RenameRemote(remote.Name, updatedRemoteName); err != nil { if err := gui.GitCommand.RenameRemote(remote.Name, updatedRemoteName); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
} }
@ -172,7 +172,7 @@ func (gui *Gui) handleEditRemote(g *gocui.Gui, v *gocui.View) error {
return gui.createPromptPanel(g, branchesView, editUrlMessage, "", func(g *gocui.Gui, v *gocui.View) error { return gui.createPromptPanel(g, branchesView, editUrlMessage, "", func(g *gocui.Gui, v *gocui.View) error {
updatedRemoteUrl := gui.trimmedContent(v) updatedRemoteUrl := gui.trimmedContent(v)
if err := gui.GitCommand.UpdateRemoteUrl(updatedRemoteName, updatedRemoteUrl); err != nil { if err := gui.GitCommand.UpdateRemoteUrl(updatedRemoteName, updatedRemoteUrl); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}})
}) })

View File

@ -9,7 +9,7 @@ import (
func (gui *Gui) resetToRef(ref string, strength string, options commands.RunCommandOptions) error { func (gui *Gui) resetToRef(ref string, strength string, options commands.RunCommandOptions) error {
if err := gui.GitCommand.ResetToCommit(ref, strength, options); err != nil { if err := gui.GitCommand.ResetToCommit(ref, strength, options); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
if err := gui.switchCommitsPanelContext("branch-commits"); err != nil { if err := gui.switchCommitsPanelContext("branch-commits"); err != nil {

View File

@ -144,7 +144,7 @@ func (gui *Gui) applySelection(reverse bool) error {
} }
err = gui.GitCommand.ApplyPatch(patch, applyFlags...) err = gui.GitCommand.ApplyPatch(patch, applyFlags...)
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
if state.SelectMode == RANGE { if state.SelectMode == RANGE {

View File

@ -86,21 +86,21 @@ func (gui *Gui) stashDo(g *gocui.Gui, v *gocui.View, method string) error {
"method": method, "method": method,
}, },
) )
return gui.createErrorPanel(g, errorMessage) return gui.createErrorPanel(errorMessage)
} }
if err := gui.GitCommand.StashDo(stashEntry.Index, method); err != nil { if err := gui.GitCommand.StashDo(stashEntry.Index, method); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []int{STASH, FILES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{STASH, FILES}})
} }
func (gui *Gui) handleStashSave(stashFunc func(message string) error) error { func (gui *Gui) handleStashSave(stashFunc func(message string) error) error {
if len(gui.trackedFiles()) == 0 && len(gui.stagedFiles()) == 0 { if len(gui.trackedFiles()) == 0 && len(gui.stagedFiles()) == 0 {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("NoTrackedStagedFilesStash")) return gui.createErrorPanel(gui.Tr.SLocalize("NoTrackedStagedFilesStash"))
} }
return gui.createPromptPanel(gui.g, gui.getFilesView(), gui.Tr.SLocalize("StashChanges"), "", func(g *gocui.Gui, v *gocui.View) error { return gui.createPromptPanel(gui.g, gui.getFilesView(), gui.Tr.SLocalize("StashChanges"), "", func(g *gocui.Gui, v *gocui.View) error {
if err := stashFunc(gui.trimmedContent(v)); err != nil { if err := stashFunc(gui.trimmedContent(v)); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []int{STASH, FILES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{STASH, FILES}})
}) })

View File

@ -49,7 +49,7 @@ func (gui *Gui) handleTagSelect(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) refreshTags() error { func (gui *Gui) refreshTags() error {
tags, err := gui.GitCommand.GetTags() tags, err := gui.GitCommand.GetTags()
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
gui.State.Tags = tags gui.State.Tags = tags
@ -69,7 +69,7 @@ func (gui *Gui) renderTagsWithSelection() error {
gui.renderDisplayStrings(branchesView, displayStrings) gui.renderDisplayStrings(branchesView, displayStrings)
if gui.g.CurrentView() == branchesView && branchesView.Context == "tags" { if gui.g.CurrentView() == branchesView && branchesView.Context == "tags" {
if err := gui.handleTagSelect(gui.g, branchesView); err != nil { if err := gui.handleTagSelect(gui.g, branchesView); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
} }
@ -102,7 +102,7 @@ func (gui *Gui) handleDeleteTag(g *gocui.Gui, v *gocui.View) error {
return gui.createConfirmationPanel(gui.g, v, true, gui.Tr.SLocalize("DeleteTagTitle"), prompt, func(g *gocui.Gui, v *gocui.View) error { return gui.createConfirmationPanel(gui.g, v, true, gui.Tr.SLocalize("DeleteTagTitle"), prompt, func(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.DeleteTag(tag.Name); err != nil { if err := gui.GitCommand.DeleteTag(tag.Name); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{COMMITS, TAGS}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{COMMITS, TAGS}})
}, nil) }, nil)
@ -123,7 +123,7 @@ func (gui *Gui) handlePushTag(g *gocui.Gui, v *gocui.View) error {
return gui.createPromptPanel(gui.g, v, title, "origin", func(g *gocui.Gui, v *gocui.View) error { return gui.createPromptPanel(gui.g, v, title, "origin", func(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.PushTag(v.Buffer(), tag.Name); err != nil { if err := gui.GitCommand.PushTag(v.Buffer(), tag.Name); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return nil return nil
}) })
@ -134,7 +134,7 @@ func (gui *Gui) handleCreateTag(g *gocui.Gui, v *gocui.View) 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
tagName := v.Buffer() tagName := v.Buffer()
if err := gui.GitCommand.CreateLightweightTag(tagName, ""); err != nil { if err := gui.GitCommand.CreateLightweightTag(tagName, ""); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []int{COMMITS, TAGS}, then: func() { return gui.refreshSidePanels(refreshOptions{scope: []int{COMMITS, TAGS}, then: func() {
// find the index of the tag and set that as the currently selected line // find the index of the tag and set that as the currently selected line

View File

@ -88,7 +88,7 @@ func (gui *Gui) reflogUndo(g *gocui.Gui, v *gocui.View) error {
undoingStatus := gui.Tr.SLocalize("UndoingStatus") undoingStatus := gui.Tr.SLocalize("UndoingStatus")
if gui.workingTreeState() == "rebasing" { if gui.workingTreeState() == "rebasing" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("cantUndoWhileRebasing")) return gui.createErrorPanel(gui.Tr.SLocalize("cantUndoWhileRebasing"))
} }
return gui.parseReflogForActions(func(counter int, action reflogAction) (bool, error) { return gui.parseReflogForActions(func(counter int, action reflogAction) (bool, error) {
@ -119,7 +119,7 @@ func (gui *Gui) reflogRedo(g *gocui.Gui, v *gocui.View) error {
redoingStatus := gui.Tr.SLocalize("RedoingStatus") redoingStatus := gui.Tr.SLocalize("RedoingStatus")
if gui.workingTreeState() == "rebasing" { if gui.workingTreeState() == "rebasing" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("cantRedoWhileRebasing")) return gui.createErrorPanel(gui.Tr.SLocalize("cantRedoWhileRebasing"))
} }
return gui.parseReflogForActions(func(counter int, action reflogAction) (bool, error) { return gui.parseReflogForActions(func(counter int, action reflogAction) (bool, error) {
@ -166,7 +166,7 @@ func (gui *Gui) handleHardResetWithAutoStash(commitSha string, options handleHar
reset := func() error { reset := func() error {
if err := gui.resetToRef(commitSha, "hard", commands.RunCommandOptions{EnvVars: options.EnvVars}); err != nil { if err := gui.resetToRef(commitSha, "hard", commands.RunCommandOptions{EnvVars: options.EnvVars}); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return nil return nil
} }
@ -176,7 +176,7 @@ func (gui *Gui) handleHardResetWithAutoStash(commitSha string, options handleHar
return gui.createConfirmationPanel(gui.g, gui.getBranchesView(), true, gui.Tr.SLocalize("AutoStashTitle"), gui.Tr.SLocalize("AutoStashPrompt"), func(g *gocui.Gui, v *gocui.View) error { return gui.createConfirmationPanel(gui.g, gui.getBranchesView(), true, gui.Tr.SLocalize("AutoStashTitle"), gui.Tr.SLocalize("AutoStashPrompt"), func(g *gocui.Gui, v *gocui.View) error {
return gui.WithWaitingStatus(options.WaitingStatus, func() error { return gui.WithWaitingStatus(options.WaitingStatus, func() error {
if err := gui.GitCommand.StashSave(gui.Tr.SLocalize("StashPrefix") + commitSha); err != nil { if err := gui.GitCommand.StashSave(gui.Tr.SLocalize("StashPrefix") + commitSha); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
if err := reset(); err != nil { if err := reset(); err != nil {
return err return err
@ -186,7 +186,7 @@ func (gui *Gui) handleHardResetWithAutoStash(commitSha string, options handleHar
if err := gui.refreshSidePanels(refreshOptions{}); err != nil { if err := gui.refreshSidePanels(refreshOptions{}); err != nil {
return err return err
} }
return gui.createErrorPanel(g, err.Error()) return gui.surfaceError(err)
} }
return nil return nil
}) })

View File

@ -14,10 +14,10 @@ func (gui *Gui) showUpdatePrompt(newVersion string) error {
func (gui *Gui) onUserUpdateCheckFinish(newVersion string, err error) error { func (gui *Gui) onUserUpdateCheckFinish(newVersion string, err error) error {
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
if newVersion == "" { if newVersion == "" {
return gui.createErrorPanel(gui.g, "New version not found") return gui.createErrorPanel("New version not found")
} }
return gui.showUpdatePrompt(newVersion) return gui.showUpdatePrompt(newVersion)
} }
@ -49,7 +49,7 @@ func (gui *Gui) onUpdateFinish(err error) error {
gui.statusManager.removeStatus("updating") gui.statusManager.removeStatus("updating")
gui.renderString(gui.g, "appStatus", "") gui.renderString(gui.g, "appStatus", "")
if err != nil { if err != nil {
return gui.createErrorPanel(gui.g, "Update failed: "+err.Error()) return gui.createErrorPanel("Update failed: " + err.Error())
} }
return nil return nil
} }

View File

@ -16,7 +16,7 @@ func (gui *Gui) handleCreateResetMenu(g *gocui.Gui, v *gocui.View) error {
}, },
onPress: func() error { onPress: func() error {
if err := gui.GitCommand.ResetAndClean(); err != nil { if err := gui.GitCommand.ResetAndClean(); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
@ -29,7 +29,7 @@ func (gui *Gui) handleCreateResetMenu(g *gocui.Gui, v *gocui.View) error {
}, },
onPress: func() error { onPress: func() error {
if err := gui.GitCommand.DiscardAnyUnstagedFileChanges(); err != nil { if err := gui.GitCommand.DiscardAnyUnstagedFileChanges(); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
@ -42,7 +42,7 @@ func (gui *Gui) handleCreateResetMenu(g *gocui.Gui, v *gocui.View) error {
}, },
onPress: func() error { onPress: func() error {
if err := gui.GitCommand.RemoveUntrackedFiles(); err != nil { if err := gui.GitCommand.RemoveUntrackedFiles(); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
@ -55,7 +55,7 @@ func (gui *Gui) handleCreateResetMenu(g *gocui.Gui, v *gocui.View) error {
}, },
onPress: func() error { onPress: func() error {
if err := gui.GitCommand.ResetSoft("HEAD"); err != nil { if err := gui.GitCommand.ResetSoft("HEAD"); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
@ -68,7 +68,7 @@ func (gui *Gui) handleCreateResetMenu(g *gocui.Gui, v *gocui.View) error {
}, },
onPress: func() error { onPress: func() error {
if err := gui.GitCommand.ResetSoft("HEAD"); err != nil { if err := gui.GitCommand.ResetSoft("HEAD"); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
@ -81,7 +81,7 @@ func (gui *Gui) handleCreateResetMenu(g *gocui.Gui, v *gocui.View) error {
}, },
onPress: func() error { onPress: func() error {
if err := gui.GitCommand.ResetHard("HEAD"); err != nil { if err := gui.GitCommand.ResetHard("HEAD"); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})