diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index 67b8e86f1..4811e026f 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -942,6 +942,7 @@ func (self *RefreshHelper) refreshReflogCommits() error { } func (self *RefreshHelper) refreshRemotes() error { + generation := self.c.State().GetRepoGeneration() prevSelectedRemote := self.c.Contexts().Remotes.GetSelected() remotes, err := self.c.Git().Loaders.RemoteLoader.GetRemotes() @@ -949,25 +950,28 @@ func (self *RefreshHelper) refreshRemotes() error { return err } - self.c.Model().Remotes = remotes + self.onUIThreadUnlessRepoChanged(generation, func() error { + self.c.Model().Remotes = remotes - hadPrs := len(self.c.Model().PullRequestsMap) != 0 - self.rebuildPullRequestsMap() - if !hadPrs && len(self.c.Model().PullRequestsMap) != 0 { - // if we didn't have PRs in the map before but now we do, we need to redraw the branches view - self.refreshView(self.c.Contexts().Branches) - } + hadPrs := len(self.c.Model().PullRequestsMap) != 0 + self.rebuildPullRequestsMap() + if !hadPrs && len(self.c.Model().PullRequestsMap) != 0 { + // if we didn't have PRs in the map before but now we do, we need to redraw the branches view + self.refreshView(self.c.Contexts().Branches) + } - // we need to ensure our selected remote branches aren't now outdated - if prevSelectedRemote != nil && self.c.Model().RemoteBranches != nil { - // find remote now - for _, remote := range remotes { - if remote.Name == prevSelectedRemote.Name { - self.c.Model().RemoteBranches = remote.Branches - break + // we need to ensure our selected remote branches aren't now outdated + if prevSelectedRemote != nil && self.c.Model().RemoteBranches != nil { + // find remote now + for _, remote := range remotes { + if remote.Name == prevSelectedRemote.Name { + self.c.Model().RemoteBranches = remote.Branches + break + } } } - } + return nil + }) self.refreshView(self.c.Contexts().Remotes) self.refreshView(self.c.Contexts().RemoteBranches) diff --git a/pkg/gui/controllers/remotes_controller.go b/pkg/gui/controllers/remotes_controller.go index f7b16e228..e4f606ca3 100644 --- a/pkg/gui/controllers/remotes_controller.go +++ b/pkg/gui/controllers/remotes_controller.go @@ -156,24 +156,28 @@ func (self *RemotesController) addAndCheckoutRemote(remoteName string, remoteUrl return err } - // Do a sync refresh of the remotes so that we can select - // the new one. Loading remotes is not expensive, so we can - // afford it. + // Refresh the remotes so that we can select the new one. The remotes model + // update is bounced onto the UI thread, so the selection (which reads + // Model.Remotes) has to run in Then; reading it inline here would see the + // previous model. Loading remotes is not expensive, so a sync refresh is + // affordable. self.c.Refresh(types.RefreshOptions{ Scope: []types.RefreshableView{types.REMOTES}, Mode: types.SYNC, + Then: func() error { + // Select the remote + for idx, remote := range self.c.Model().Remotes { + if remote.Name == remoteName { + self.c.Contexts().Remotes.SetSelection(idx) + break + } + } + + // Fetch the remote + return self.fetchAndCheckout(self.c.Contexts().Remotes.GetSelected(), branchToCheckout) + }, }) - - // Select the remote - for idx, remote := range self.c.Model().Remotes { - if remote.Name == remoteName { - self.c.Contexts().Remotes.SetSelection(idx) - break - } - } - - // Fetch the remote - return self.fetchAndCheckout(self.c.Contexts().Remotes.GetSelected(), branchToCheckout) + return nil } // Ensures the fork remote exists (matching the given URL).