From 9d3474b60646b911f38225884c958df519e793ac Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Wed, 14 Oct 2020 14:30:43 -0400 Subject: [PATCH] Adds gate & caching to getRemoteWithApiProvider --- src/git/gitService.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/git/gitService.ts b/src/git/gitService.ts index 6f9cc3e..3cfa4a3 100644 --- a/src/git/gitService.ts +++ b/src/git/gitService.ts @@ -40,6 +40,7 @@ import { import { CachedBlame, CachedDiff, CachedLog, GitDocumentState, TrackedDocument } from '../trackers/gitDocumentTracker'; import { vslsUriPrefixRegex } from '../vsls/vsls'; import { + Authentication, BranchDateFormatting, CommitDateFormatting, Git, @@ -127,6 +128,7 @@ export class GitService implements Disposable { private _suspended: boolean = false; private readonly _branchesCache = new Map(); + private readonly _remotesWithApiProviderCache = new Map | null>(); private readonly _tagsCache = new Map(); private readonly _trackedCache = new Map>(); private readonly _userMapCache = new Map(); @@ -138,6 +140,7 @@ export class GitService implements Disposable { window.onDidChangeWindowState(this.onWindowStateChanged, this), workspace.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged, this), configuration.onDidChange(this.onConfigurationChanged, this), + Authentication.onDidChange(() => this._remotesWithApiProviderCache.clear()), ); this.onConfigurationChanged(configuration.initializingChangeEvent); @@ -147,6 +150,7 @@ export class GitService implements Disposable { dispose() { this._repositoryTree.forEach(r => r.dispose()); this._branchesCache.clear(); + this._remotesWithApiProviderCache.clear(); this._tagsCache.clear(); this._trackedCache.clear(); this._userMapCache.clear(); @@ -178,6 +182,9 @@ export class GitService implements Disposable { if (e.changed(RepositoryChange.Stash, true)) return; this._branchesCache.delete(repo.path); + if (e.changed(RepositoryChange.Remotes)) { + this._remotesWithApiProviderCache.clear(); + } this._tagsCache.delete(repo.path); this._trackedCache.clear(); @@ -2792,6 +2799,12 @@ export class GitService implements Disposable { remotes: GitRemote[], options?: { includeDisconnected?: boolean }, ): Promise | undefined>; + @gate( + (remotesOrRepoPath, options) => + `${typeof remotesOrRepoPath === 'string' ? remotesOrRepoPath : remotesOrRepoPath[0]?.repoPath}:${ + options?.includeDisconnected ?? false + }`, + ) @log({ args: { 0: () => false } }) async getRemoteWithApiProvider( remotesOrRepoPath: GitRemote[] | string | undefined, @@ -2799,23 +2812,57 @@ export class GitService implements Disposable { ): Promise | undefined> { if (remotesOrRepoPath == null) return undefined; - // TODO@eamodio Add caching to avoid constant lookups + const repoPath = typeof remotesOrRepoPath === 'string' ? remotesOrRepoPath : remotesOrRepoPath[0]?.repoPath; + if (repoPath != null) { + const remote = this._remotesWithApiProviderCache.get(repoPath); + if (remote !== undefined) return remote ?? undefined; + } const remotes = (typeof remotesOrRepoPath === 'string' ? await this.getRemotes(remotesOrRepoPath) : remotesOrRepoPath ).filter(r => r.provider != null); - const remote = - remotes.length === 1 ? remotes[0] : remotes.find(r => r.default) ?? remotes.find(r => r.name === 'origin'); - if (!remote?.provider?.hasApi()) return undefined; + let remote; + if (remotes.length === 1) { + remote = remotes[0]; + } else { + let originRemote; + for (const r of remotes) { + if (r.default) { + remote = r; + break; + } + + if (r.name === 'origin') { + originRemote = r; + } + } + + remote = remote ?? originRemote ?? null; + } + + if (!remote?.provider?.hasApi()) { + if (repoPath != null) { + this._remotesWithApiProviderCache.set(repoPath, null); + } + return undefined; + } const { provider } = remote; if (!includeDisconnected) { const connected = provider.maybeConnected ?? (await provider.isConnected()); - if (!connected) return undefined; + if (!connected) { + if (repoPath != null) { + this._remotesWithApiProviderCache.set(repoPath, null); + } + return undefined; + } } + if (repoPath != null) { + this._remotesWithApiProviderCache.set(repoPath, remote as GitRemote); + } return remote as GitRemote; }