mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Pause background refreshes while driving a git operation
Several commands (rewording or amending an earlier commit, custom patch operations, etc.) are implemented by starting an interactive rebase that stops at a commit, amending it, and continuing. When no conflict occurs, the user isn't meant to notice a rebase happened at all. But a background file refresh can fire while the rebase is mid-flight and render a dirty working copy of whatever the behind-the-scenes rebase is doing (e.g. applying a custom patch). To fix this, we pause the background routines for the duration of any waiting-status operation — exactly the window in which lazygit is driving the git operation itself and will refresh once at the end. The boundary is also right for the conflict case: when a rebase stops on a conflict the operation returns, the pause releases, and background refreshes resume for the interactive resolution that follows.
This commit is contained in:
parent
f9c81b655d
commit
3cf890b7d7
|
|
@ -66,12 +66,22 @@ func (self *AppStatusHelper) WithWaitingStatus(message string, f func(gocui.Task
|
|||
}
|
||||
|
||||
func (self *AppStatusHelper) WithWaitingStatusImpl(message string, f func(gocui.Task) error, task gocui.Task) error {
|
||||
// A waiting status means lazygit is driving a git operation itself (often
|
||||
// one that internally runs a rebase and continues it). Pause the background
|
||||
// routines for its duration so they don't refresh from an intermediate
|
||||
// state and reveal, say, the half-finished history of a reword.
|
||||
self.c.PauseBackgroundRefreshes(true)
|
||||
defer self.c.PauseBackgroundRefreshes(false)
|
||||
|
||||
return self.statusMgr().WithWaitingStatus(message, self.renderAppStatus, func(waitingStatusHandle *status.WaitingStatusHandle) error {
|
||||
return f(appStatusHelperTask{task, waitingStatusHandle})
|
||||
})
|
||||
}
|
||||
|
||||
func (self *AppStatusHelper) WithWaitingStatusSync(message string, f func() error) error {
|
||||
self.c.PauseBackgroundRefreshes(true)
|
||||
defer self.c.PauseBackgroundRefreshes(false)
|
||||
|
||||
return self.statusMgr().WithWaitingStatus(message, func() {}, func(*status.WaitingStatusHandle) error {
|
||||
stop := make(chan struct{})
|
||||
defer func() { close(stop) }()
|
||||
|
|
|
|||
|
|
@ -68,6 +68,14 @@ func (self *InlineStatusHelper) WithInlineStatus(opts InlineStatusOpts, f func(g
|
|||
visible := view.Visible && self.windowHelper.TopViewInWindow(context.GetWindowName(), false) == view
|
||||
if visible && context.IsItemVisible(opts.Item) {
|
||||
self.c.OnWorker(func(task gocui.Task) error {
|
||||
// An inline status is just a waiting status rendered on the item
|
||||
// rather than in the bottom line, so it gets the same treatment:
|
||||
// pause the background routines while we drive the operation. (The
|
||||
// off-screen branch below goes through WithWaitingStatus, which
|
||||
// already does this.)
|
||||
self.c.PauseBackgroundRefreshes(true)
|
||||
defer self.c.PauseBackgroundRefreshes(false)
|
||||
|
||||
self.start(opts)
|
||||
defer self.stop(opts)
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ func (self *guiCommon) Resume() error {
|
|||
return self.gui.resume()
|
||||
}
|
||||
|
||||
func (self *guiCommon) PauseBackgroundRefreshes(pause bool) {
|
||||
self.gui.BackgroundRoutineMgr.PauseBackgroundRefreshes(pause)
|
||||
}
|
||||
|
||||
func (self *guiCommon) Context() types.IContextMgr {
|
||||
return self.gui.State.ContextMgr
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,10 @@ type IGuiCommon interface {
|
|||
Suspend() error
|
||||
Resume() error
|
||||
|
||||
// Pause or resume the background routines. Calls nest, so every pause must be balanced
|
||||
// by a resume.
|
||||
PauseBackgroundRefreshes(pause bool)
|
||||
|
||||
Context() IContextMgr
|
||||
ContextForKey(key ContextKey) Context
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue