mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-11-27 22:38:09 +02:00
fix commit amend
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -9,24 +8,6 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// runSyncOrAsyncCommand takes the output of a command that may have returned
|
||||
// either no error, an error, or a subprocess to execute, and if a subprocess
|
||||
// needs to be run, it runs it
|
||||
func (gui *Gui) runSyncOrAsyncCommand(sub *exec.Cmd, err error) (bool, error) {
|
||||
if err != nil {
|
||||
return false, gui.surfaceError(err)
|
||||
}
|
||||
if sub == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
err = gui.runSubprocessWithSuspense(sub)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCommitConfirm() error {
|
||||
message := gui.trimmedContent(gui.Views.CommitMessage)
|
||||
if message == "" {
|
||||
@@ -37,19 +18,12 @@ func (gui *Gui) handleCommitConfirm() error {
|
||||
if skipHookPrefix != "" && strings.HasPrefix(message, skipHookPrefix) {
|
||||
flags = "--no-verify"
|
||||
}
|
||||
ok, err := gui.runSyncOrAsyncCommand(gui.GitCommand.Commit(message, flags))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_ = gui.returnFromContext()
|
||||
|
||||
if !ok {
|
||||
return gui.withGpgHandling(gui.GitCommand.CommitCmdStr(message, flags), gui.Tr.CommittingStatus, func() error {
|
||||
_ = gui.returnFromContext()
|
||||
gui.clearEditorView(gui.Views.CommitMessage)
|
||||
return nil
|
||||
}
|
||||
|
||||
gui.clearEditorView(gui.Views.CommitMessage)
|
||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCommitClose() error {
|
||||
|
||||
@@ -263,7 +263,7 @@ func (gui *Gui) handleRenameCommitEditor() error {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
if subProcess != nil {
|
||||
return gui.runSubprocessWithSuspense(subProcess)
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(subProcess)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -60,7 +60,7 @@ func (gui *Gui) handleCustomCommandKeybinding(customCommand config.CustomCommand
|
||||
}
|
||||
|
||||
if customCommand.Subprocess {
|
||||
return gui.runSubprocessWithSuspense(gui.OSCommand.PrepareShellSubProcess(cmdStr))
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(gui.OSCommand.PrepareShellSubProcess(cmdStr))
|
||||
}
|
||||
|
||||
loadingText := customCommand.LoadingText
|
||||
|
||||
@@ -448,17 +448,7 @@ func (gui *Gui) handleAmendCommitPress() error {
|
||||
title: strings.Title(gui.Tr.AmendLastCommit),
|
||||
prompt: gui.Tr.SureToAmend,
|
||||
handleConfirm: func() error {
|
||||
return gui.WithWaitingStatus(gui.Tr.AmendingStatus, func() error {
|
||||
ok, err := gui.runSyncOrAsyncCommand(gui.GitCommand.AmendHead())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
|
||||
})
|
||||
return gui.withGpgHandling(gui.GitCommand.AmendHeadCmdStr(), gui.Tr.AmendingStatus, nil)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -474,14 +464,20 @@ func (gui *Gui) handleCommitEditorPress() error {
|
||||
return gui.promptToStageAllAndRetry(gui.handleCommitEditorPress)
|
||||
}
|
||||
|
||||
return gui.runSubprocessWithSuspense(
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.PrepareSubProcess("git", "commit"),
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) editFile(filename string) error {
|
||||
_, err := gui.runSyncOrAsyncCommand(gui.GitCommand.EditFile(filename))
|
||||
return err
|
||||
cmdStr, err := gui.GitCommand.EditFileCmdStr(filename)
|
||||
if err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.PrepareShellSubProcess(cmdStr),
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleFileEdit() error {
|
||||
@@ -808,7 +804,7 @@ func (gui *Gui) handleCustomCommand() error {
|
||||
return gui.prompt(promptOpts{
|
||||
title: gui.Tr.CustomCommand,
|
||||
handleConfirm: func(command string) error {
|
||||
return gui.runSubprocessWithSuspense(
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.PrepareShellSubProcess(command),
|
||||
)
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@ func (gui *Gui) gitFlowFinishBranch(gitFlowConfig string, branchName string) err
|
||||
return gui.createErrorPanel(gui.Tr.NotAGitFlowBranch)
|
||||
}
|
||||
|
||||
return gui.runSubprocessWithSuspense(
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.PrepareSubProcess("git", "flow", branchType, "finish", suffix),
|
||||
)
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func (gui *Gui) handleCreateGitFlowMenu() error {
|
||||
return gui.prompt(promptOpts{
|
||||
title: title,
|
||||
handleConfirm: func(name string) error {
|
||||
return gui.runSubprocessWithSuspense(
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.PrepareSubProcess("git", "flow", branchType, "start", name),
|
||||
)
|
||||
},
|
||||
|
||||
41
pkg/gui/gpg.go
Normal file
41
pkg/gui/gpg.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package gui
|
||||
|
||||
// Currently there is a bug where if we switch to a subprocess from within
|
||||
// WithWaitingStatus we get stuck there and can't return to lazygit. We could
|
||||
// fix this bug, or just stop running subprocesses from within there, given that
|
||||
// we don't need to see a loading status if we're in a subprocess.
|
||||
func (gui *Gui) withGpgHandling(cmdStr string, waitingStatus string, onSuccess func() error) error {
|
||||
useSubprocess := gui.GitCommand.UsingGpg()
|
||||
if useSubprocess {
|
||||
// Need to remember why we use the shell for the subprocess but not in the other case
|
||||
// Maybe there's no good reason
|
||||
success, err := gui.runSubprocessWithSuspense(gui.OSCommand.ShellCommandFromString(cmdStr))
|
||||
if success && onSuccess != nil {
|
||||
if err := onSuccess(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return gui.WithWaitingStatus(waitingStatus, func() error {
|
||||
err := gui.OSCommand.RunCommand(cmdStr)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if onSuccess != nil {
|
||||
if err := onSuccess(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -90,7 +90,7 @@ type Gui struct {
|
||||
// recent repo with the recent repos popup showing
|
||||
showRecentRepos bool
|
||||
|
||||
Mutexes guiStateMutexes
|
||||
Mutexes guiMutexes
|
||||
|
||||
// findSuggestions will take a string that the user has typed into a prompt
|
||||
// and return a slice of suggestions which match that string.
|
||||
@@ -288,12 +288,13 @@ type Modes struct {
|
||||
Diffing Diffing
|
||||
}
|
||||
|
||||
type guiStateMutexes struct {
|
||||
type guiMutexes struct {
|
||||
RefreshingFilesMutex sync.Mutex
|
||||
RefreshingStatusMutex sync.Mutex
|
||||
FetchMutex sync.Mutex
|
||||
BranchCommitsMutex sync.Mutex
|
||||
LineByLinePanelMutex sync.Mutex
|
||||
SubprocessMutex sync.Mutex
|
||||
}
|
||||
|
||||
type guiState struct {
|
||||
@@ -476,6 +477,7 @@ func (gui *Gui) Run() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gui.g = g // TODO: always use gui.g rather than passing g around everywhere
|
||||
defer g.Close()
|
||||
|
||||
@@ -568,7 +570,25 @@ func (gui *Gui) RunAndHandleError() error {
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) runSubprocessWithSuspense(subprocess *exec.Cmd) error {
|
||||
// returns whether command exited without error or not
|
||||
func (gui *Gui) runSubprocessWithSuspenseAndRefresh(subprocess *exec.Cmd) error {
|
||||
_, err := gui.runSubprocessWithSuspense(subprocess)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// returns whether command exited without error or not
|
||||
func (gui *Gui) runSubprocessWithSuspense(subprocess *exec.Cmd) (bool, error) {
|
||||
gui.Mutexes.SubprocessMutex.Lock()
|
||||
defer gui.Mutexes.SubprocessMutex.Unlock()
|
||||
|
||||
if replaying() {
|
||||
// we do not yet support running subprocesses within integration tests. So if
|
||||
// we're replaying an integration test and we're inside this method, something
|
||||
@@ -577,21 +597,17 @@ func (gui *Gui) runSubprocessWithSuspense(subprocess *exec.Cmd) error {
|
||||
log.Fatal("opening subprocesses not yet supported in integration tests. Chances are that this test is running too fast and a subprocess is accidentally opened")
|
||||
}
|
||||
|
||||
if err := gocui.Screen.Suspend(); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
if err := gui.g.Suspend(); err != nil {
|
||||
return false, gui.surfaceError(err)
|
||||
}
|
||||
|
||||
cmdErr := gui.runSubprocess(subprocess)
|
||||
|
||||
if err := gocui.Screen.Resume(); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
if err := gui.g.Resume(); err != nil {
|
||||
return false, gui.surfaceError(err)
|
||||
}
|
||||
|
||||
if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.surfaceError(cmdErr)
|
||||
return cmdErr == nil, gui.surfaceError(cmdErr)
|
||||
}
|
||||
|
||||
func (gui *Gui) runSubprocess(subprocess *exec.Cmd) error {
|
||||
|
||||
@@ -50,7 +50,7 @@ func (gui *Gui) genericMergeCommand(command string) error {
|
||||
if status == commands.REBASE_MODE_MERGING && command != "abort" && gui.Config.GetUserConfig().Git.Merging.ManualCommit {
|
||||
sub := gui.OSCommand.PrepareSubProcess("git", commandType, fmt.Sprintf("--%s", command))
|
||||
if sub != nil {
|
||||
return gui.runSubprocessWithSuspense(sub)
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(sub)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user