mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Show a waiting status while creating a branch
Creating a branch checks it out, and checking out a distant ref (a tag or a commit far from HEAD) can take a noticeable while. NewBranch ran that synchronously in the prompt's confirm handler, on the UI thread, so the UI froze — no spinner, no repaint — until it finished. Move the branch creation (and the autostash path) onto a worker with a waiting status, mirroring CheckoutRef, and refresh from the worker so the UI thread stays live and the spinner keeps animating. Push the branches context from the refresh's Then rather than up front: the refresh already batches its UI updates, so switching panels there lands the switch in the same frame as the refreshed branch list instead of flashing the pre-refresh list while the checkout is still running. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bfd3b7b47e
commit
63bd2d98c0
|
|
@ -364,16 +364,22 @@ func (self *RefsHelper) NewBranch(from string, fromFormattedName string, suggest
|
|||
}
|
||||
|
||||
refresh := func() {
|
||||
if self.c.Context().Current() != self.c.Contexts().Branches {
|
||||
self.c.Context().Push(self.c.Contexts().Branches, types.OnFocusOpts{})
|
||||
}
|
||||
|
||||
self.c.Refresh(types.RefreshOptions{
|
||||
self.c.RefreshFromWorker(types.RefreshOptions{
|
||||
Mode: types.SYNC,
|
||||
BatchUIUpdates: true,
|
||||
BranchSelection: types.SelectCheckedOutBranch,
|
||||
CommitSelection: types.SelectHeadCommit,
|
||||
SelectTopReflogCommit: true,
|
||||
Then: func() error {
|
||||
// Switch to the branches panel only now, in the same batched
|
||||
// frame that applies the refreshed data, so the panel switch
|
||||
// and the new branch appear together rather than flashing the
|
||||
// old branch list while the checkout is still in progress.
|
||||
if self.c.Context().Current() != self.c.Contexts().Branches {
|
||||
self.c.Context().Push(self.c.Contexts().Branches, types.OnFocusOpts{})
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -387,34 +393,44 @@ func (self *RefsHelper) NewBranch(from string, fromFormattedName string, suggest
|
|||
if newBranchName != suggestedBranchName {
|
||||
newBranchFunc = self.c.Git().Branch.NewWithoutTracking
|
||||
}
|
||||
if err := newBranchFunc(newBranchName, from); err != nil {
|
||||
if IsSwitchBranchUncommittedChangesError(err) {
|
||||
// offer to autostash changes
|
||||
self.c.Confirm(types.ConfirmOpts{
|
||||
Title: self.c.Tr.AutoStashTitle,
|
||||
Prompt: self.c.Tr.AutoStashPrompt,
|
||||
HandleConfirm: func() error {
|
||||
if err := self.c.Git().Stash.Push(fmt.Sprintf(self.c.Tr.AutoStashForNewBranch, newBranchName)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := newBranchFunc(newBranchName, from); err != nil {
|
||||
return err
|
||||
}
|
||||
err := self.c.Git().Stash.Pop(0)
|
||||
// Branch switch successful so re-render the UI even if the pop operation failed (e.g. conflict).
|
||||
refresh()
|
||||
return err
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
// Creating the branch checks it out, which can take a while when
|
||||
// the ref we're branching off is distant, so do it on a worker.
|
||||
return self.c.WithWaitingStatus(self.c.Tr.CreatingBranchStatus, func(gocui.Task) error {
|
||||
if err := newBranchFunc(newBranchName, from); err != nil {
|
||||
if IsSwitchBranchUncommittedChangesError(err) {
|
||||
// offer to autostash changes
|
||||
self.c.OnUIThread(func() error {
|
||||
self.c.Confirm(types.ConfirmOpts{
|
||||
Title: self.c.Tr.AutoStashTitle,
|
||||
Prompt: self.c.Tr.AutoStashPrompt,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.CreatingBranchStatus, func(gocui.Task) error {
|
||||
if err := self.c.Git().Stash.Push(fmt.Sprintf(self.c.Tr.AutoStashForNewBranch, newBranchName)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := newBranchFunc(newBranchName, from); err != nil {
|
||||
return err
|
||||
}
|
||||
err := self.c.Git().Stash.Pop(0)
|
||||
// Branch switch successful so re-render the UI even if the pop operation failed (e.g. conflict).
|
||||
refresh()
|
||||
return err
|
||||
})
|
||||
},
|
||||
})
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
refresh()
|
||||
return nil
|
||||
refresh()
|
||||
return nil
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -427,6 +427,7 @@ type TranslationSet struct {
|
|||
UndoingStatus string
|
||||
RedoingStatus string
|
||||
CheckingOutStatus string
|
||||
CreatingBranchStatus string
|
||||
CommittingStatus string
|
||||
RewordingStatus string
|
||||
RevertingStatus string
|
||||
|
|
@ -1576,6 +1577,7 @@ func EnglishTranslationSet() *TranslationSet {
|
|||
UndoingStatus: "Undoing",
|
||||
RedoingStatus: "Redoing",
|
||||
CheckingOutStatus: "Checking out",
|
||||
CreatingBranchStatus: "Creating branch",
|
||||
CommittingStatus: "Committing",
|
||||
RewordingStatus: "Rewording",
|
||||
RevertingStatus: "Reverting",
|
||||
|
|
|
|||
Loading…
Reference in a new issue