mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Run the stash operations with a waiting status
Creating and applying a stash both touch every changed file, so in a large repo they can take long enough to be noticeable — and running them on the UI thread meant the confirmation popup stayed on screen, frozen, for the whole operation. Run them on a worker instead, with a spinner, and keep blocking input for their duration so that the type-ahead guarantee the refresh used to provide still holds. Dropping stays on the UI thread: it only rewrites the stash reflog, so it's fast no matter how big the stashes are. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ed22322ec8
commit
4c39b0b903
|
|
@ -1508,16 +1508,20 @@ func (self *FilesController) handleStashSave(stashFunc func(message string) erro
|
|||
self.c.Prompt(types.PromptOpts{
|
||||
Title: self.c.Tr.StashChanges,
|
||||
HandleConfirm: func(stashComment string) error {
|
||||
self.c.LogAction(action)
|
||||
return self.c.WithWaitingStatusBlockingInput(
|
||||
types.WaitingStatusOpts{Message: self.c.Tr.StashingStatus},
|
||||
func(gocui.Task) error {
|
||||
self.c.LogAction(action)
|
||||
|
||||
if err := stashFunc(stashComment); err != nil {
|
||||
return err
|
||||
}
|
||||
self.c.Refresh(types.RefreshOptions{
|
||||
BatchUIUpdates: true,
|
||||
Scope: []types.RefreshableView{types.STASH, types.FILES},
|
||||
})
|
||||
return nil
|
||||
if err := stashFunc(stashComment); err != nil {
|
||||
return err
|
||||
}
|
||||
self.c.RefreshFromWorker(types.RefreshOptions{
|
||||
BatchUIUpdates: true,
|
||||
Scope: []types.RefreshableView{types.STASH, types.FILES},
|
||||
})
|
||||
return nil
|
||||
})
|
||||
},
|
||||
AllowEmptyInput: true,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
|
|
@ -120,21 +121,29 @@ func (self *StashController) handleStashApply(stashEntry *models.StashEntry) err
|
|||
Title: self.c.Tr.StashApply,
|
||||
Prompt: self.c.Tr.SureApplyStashEntry,
|
||||
HandleConfirm: func() error {
|
||||
self.c.LogAction(self.c.Tr.Actions.ApplyStash)
|
||||
err := self.c.Git().Stash.Apply(stashEntry.Index)
|
||||
self.postStashRefresh(err == nil && self.c.UserConfig().Gui.SwitchToFilesAfterStashApply)
|
||||
return err
|
||||
return self.c.WithWaitingStatusBlockingInput(
|
||||
types.WaitingStatusOpts{Message: self.c.Tr.ApplyingStashStatus},
|
||||
func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.ApplyStash)
|
||||
err := self.c.Git().Stash.Apply(stashEntry.Index)
|
||||
self.postStashRefresh(err == nil && self.c.UserConfig().Gui.SwitchToFilesAfterStashApply)
|
||||
return err
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (self *StashController) handleStashPop(stashEntry *models.StashEntry) error {
|
||||
pop := func() error {
|
||||
self.c.LogAction(self.c.Tr.Actions.PopStash)
|
||||
self.c.LogCommand(fmt.Sprintf(self.c.Tr.Log.PoppingStash, stashEntry.Hash), false)
|
||||
err := self.c.Git().Stash.Pop(stashEntry.Index)
|
||||
self.postStashRefresh(err == nil && self.c.UserConfig().Gui.SwitchToFilesAfterStashPop)
|
||||
return err
|
||||
return self.c.WithWaitingStatusBlockingInput(
|
||||
types.WaitingStatusOpts{Message: self.c.Tr.PoppingStashStatus},
|
||||
func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.PopStash)
|
||||
self.c.LogCommand(fmt.Sprintf(self.c.Tr.Log.PoppingStash, stashEntry.Hash), false)
|
||||
err := self.c.Git().Stash.Pop(stashEntry.Index)
|
||||
self.postStashRefresh(err == nil && self.c.UserConfig().Gui.SwitchToFilesAfterStashPop)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
if self.c.UserConfig().Gui.SkipStashWarning {
|
||||
|
|
@ -198,12 +207,14 @@ func (self *StashController) handleStashDrop(stashEntries []*models.StashEntry)
|
|||
|
||||
// postStashRefresh refreshes the panels that applying or popping a stash
|
||||
// affects, moving the focus to the files panel if switchToFiles is set.
|
||||
//
|
||||
// Call it from the worker that ran the stash command, from inside a
|
||||
// WithWaitingStatusBlockingInput: popping shifts the indices of the remaining
|
||||
// stash entries, so acting on the next entry in quick succession (confirming
|
||||
// the popup and pressing the key again right away) has to be held off until
|
||||
// the refreshed list is in place, or it would target the wrong stash.
|
||||
func (self *StashController) postStashRefresh(switchToFiles bool) {
|
||||
// Block input until the refresh has landed: popping shifts the indices of
|
||||
// the remaining stash entries, and acting on the next entry in quick
|
||||
// succession (confirming the popup and pressing the key again right away)
|
||||
// must see the refreshed list, or it would target the wrong stash.
|
||||
self.c.RefreshBlockingInput(types.RefreshOptions{
|
||||
self.c.RefreshFromWorker(types.RefreshOptions{
|
||||
BatchUIUpdates: true,
|
||||
Scope: []types.RefreshableView{types.STASH, types.FILES},
|
||||
Then: func() error {
|
||||
|
|
|
|||
|
|
@ -443,6 +443,9 @@ type TranslationSet struct {
|
|||
MovingCommitsToNewBranchStatus string
|
||||
ApplyingFilterStatus string
|
||||
RemovingFilterStatus string
|
||||
StashingStatus string
|
||||
ApplyingStashStatus string
|
||||
PoppingStashStatus string
|
||||
CommitFiles string
|
||||
SubCommitsDynamicTitle string
|
||||
CommitFilesDynamicTitle string
|
||||
|
|
@ -1603,6 +1606,9 @@ func EnglishTranslationSet() *TranslationSet {
|
|||
MovingCommitsToNewBranchStatus: "Moving commits to new branch",
|
||||
ApplyingFilterStatus: "Applying filter",
|
||||
RemovingFilterStatus: "Removing filter",
|
||||
StashingStatus: "Stashing",
|
||||
ApplyingStashStatus: "Applying stash",
|
||||
PoppingStashStatus: "Popping stash",
|
||||
CommitFiles: "Commit files",
|
||||
SubCommitsDynamicTitle: "Commits (%s)",
|
||||
CommitFilesDynamicTitle: "Diff files (%s)",
|
||||
|
|
|
|||
Loading…
Reference in a new issue