From fff6003044fed06ef7c5e7598500e0c96bb36003 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 25 Mar 2026 10:28:26 +0100 Subject: [PATCH] Cache PRs in AppState so that they appear immediately at startup Co-authored-by: Stefan Haller --- pkg/config/app_config.go | 19 ++++++++++++++- pkg/gui/controllers/helpers/refresh_helper.go | 23 +++++++++++++++++++ pkg/gui/gui.go | 20 +++++++++++++++- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index 8205f7ef6..038d6c117 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -704,10 +704,27 @@ type AppState struct { ShellCommandsHistory []string `yaml:"customcommandshistory"` HideCommandLog bool + + // Cache of GitHub pull requests per repo path, so that PR info can be + // shown instantly on startup before the async refresh completes. + GithubPullRequests map[string][]CachedPullRequest `yaml:"githubPullRequests"` +} + +// CachedPullRequest stores the essential fields of a GitHub pull request +// for persisting in the app state cache. +type CachedPullRequest struct { + HeadRefName string `yaml:"headRefName"` + Number int `yaml:"number"` + Title string `yaml:"title"` + State string `yaml:"state"` + Url string `yaml:"url"` + HeadRepositoryOwner string `yaml:"headRepositoryOwner"` } func getDefaultAppState() *AppState { - return &AppState{} + return &AppState{ + GithubPullRequests: make(map[string][]CachedPullRequest), + } } func LogPath() (string, error) { diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index 71b03fb1d..e70951970 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -10,6 +10,7 @@ import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts" @@ -907,8 +908,30 @@ func (self *RefreshHelper) setGithubPullRequests(authToken string, baseRemote *m } self.c.Model().PullRequests = prs + self.savePullRequestsToCache(prs) self.rebuildPullRequestsMap() self.c.PostRefreshUpdate(self.c.Contexts().Branches) return nil } + +func (self *RefreshHelper) savePullRequestsToCache(prs []*models.GithubPullRequest) { + repoPath := self.c.Git().RepoPaths.RepoPath() + cached := lo.Map(prs, func(pr *models.GithubPullRequest, _ int) config.CachedPullRequest { + return config.CachedPullRequest{ + HeadRefName: pr.HeadRefName, + Number: pr.Number, + Title: pr.Title, + State: pr.State, + Url: pr.Url, + HeadRepositoryOwner: pr.HeadRepositoryOwner.Login, + } + }) + + appState := self.c.GetAppState() + if appState.GithubPullRequests == nil { + appState.GithubPullRequests = make(map[string][]config.CachedPullRequest) + } + appState.GithubPullRequests[repoPath] = cached + self.c.SaveAppStateAndLogError() +} diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 219683511..3f62bfbc7 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -601,7 +601,7 @@ func (gui *Gui) resetState(startArgs appTypes.StartArgs) types.Context { Authors: map[string]*models.Author{}, MainBranches: git_commands.NewMainBranches(gui.c.Common, gui.os.Cmd), HashPool: &utils.StringPool{}, - PullRequests: nil, + PullRequests: gui.loadCachedPullRequests(), PullRequestsMap: make(map[string]*models.GithubPullRequest), }, Modes: &types.Modes{ @@ -623,6 +623,24 @@ func (gui *Gui) resetState(startArgs appTypes.StartArgs) types.Context { return initialContext(contextTree, startArgs) } +func (gui *Gui) loadCachedPullRequests() []*models.GithubPullRequest { + repoPath := gui.git.RepoPaths.RepoPath() + cachedPRs := gui.c.GetAppState().GithubPullRequests[repoPath] + + return lo.Map(cachedPRs, func(cached config.CachedPullRequest, _ int) *models.GithubPullRequest { + return &models.GithubPullRequest{ + HeadRefName: cached.HeadRefName, + Number: cached.Number, + Title: cached.Title, + State: cached.State, + Url: cached.Url, + HeadRepositoryOwner: models.GithubRepositoryOwner{ + Login: cached.HeadRepositoryOwner, + }, + } + }) +} + func (gui *Gui) getViewBufferManagerForView(view *gocui.View) *tasks.ViewBufferManager { manager, ok := gui.viewBufferManagerMap[view.Name()] if !ok {