diff --git a/src/env/node/git/localGitProvider.ts b/src/env/node/git/localGitProvider.ts index 89c8f4a..92838a2 100644 --- a/src/env/node/git/localGitProvider.ts +++ b/src/env/node/git/localGitProvider.ts @@ -215,6 +215,11 @@ export class LocalGitProvider implements GitProvider, Disposable { // DocumentSchemes.Vsls, ]); + private _onDidChange = new EventEmitter(); + get onDidChange(): Event { + return this._onDidChange.event; + } + private _onDidChangeRepository = new EventEmitter(); get onDidChangeRepository(): Event { return this._onDidChangeRepository.event; diff --git a/src/git/gitProvider.ts b/src/git/gitProvider.ts index 814f71b..34e3e43 100644 --- a/src/git/gitProvider.ts +++ b/src/git/gitProvider.ts @@ -103,6 +103,7 @@ export interface RepositoryVisibilityInfo { } export interface GitProvider extends Disposable { + get onDidChange(): Event; get onDidChangeRepository(): Event; get onDidCloseRepository(): Event; get onDidOpenRepository(): Event; diff --git a/src/git/gitProviderService.ts b/src/git/gitProviderService.ts index d782f51..f72f3b2 100644 --- a/src/git/gitProviderService.ts +++ b/src/git/gitProviderService.ts @@ -418,6 +418,12 @@ export class GitProviderService implements Disposable { const disposable = Disposable.from( provider, ...disposables, + provider.onDidChange(() => { + const { workspaceFolders } = workspace; + if (workspaceFolders?.length) { + void this.discoverRepositories(workspaceFolders, { force: true }); + } + }), provider.onDidChangeRepository(async e => { if ( e.changed( diff --git a/src/plus/github/githubGitProvider.ts b/src/plus/github/githubGitProvider.ts index c7b40fb..754ef8c 100644 --- a/src/plus/github/githubGitProvider.ts +++ b/src/plus/github/githubGitProvider.ts @@ -121,6 +121,11 @@ export class GitHubGitProvider implements GitProvider, Disposable { descriptor = { id: GitProviderId.GitHub, name: 'GitHub', virtual: true }; readonly supportedSchemes: Set = new Set([Schemes.Virtual, Schemes.GitHub, Schemes.PRs]); + private _onDidChange = new EventEmitter(); + get onDidChange(): Event { + return this._onDidChange.event; + } + private _onDidChangeRepository = new EventEmitter(); get onDidChangeRepository(): Event { return this._onDidChangeRepository.event; @@ -194,11 +199,53 @@ export class GitHubGitProvider implements GitProvider, Disposable { if (workspaceUri == null) return []; return this.openRepository(undefined, workspaceUri, true, undefined, options?.silent); - } catch { + } catch (ex) { + if (ex.message.startsWith('No provider registered with')) { + Logger.error( + ex, + 'No GitHub provider registered with Remote Repositories (yet); queuing pending discovery', + ); + this._pendingDiscovery.add(uri); + this.ensurePendingRepositoryDiscovery(); + } return []; } } + private _pendingDiscovery = new Set(); + private _pendingTimer: ReturnType | undefined; + private ensurePendingRepositoryDiscovery() { + if (this._pendingTimer != null || this._pendingDiscovery.size === 0) return; + + this._pendingTimer = setTimeout(async () => { + try { + const remotehub = await getRemoteHubApi(); + + for (const uri of this._pendingDiscovery) { + if (remotehub.getProvider(uri) == null) { + this._pendingTimer = undefined; + this.ensurePendingRepositoryDiscovery(); + return; + } + + this._pendingDiscovery.delete(uri); + } + + this._pendingTimer = undefined; + + setTimeout(() => this._onDidChange.fire(), 1); + + if (this._pendingDiscovery.size !== 0) { + this.ensurePendingRepositoryDiscovery(); + } + } catch { + debugger; + this._pendingTimer = undefined; + this.ensurePendingRepositoryDiscovery(); + } + }, 250); + } + updateContext(): void { void setContext('gitlens:hasVirtualFolders', this.container.git.hasOpenRepositories(this.descriptor.id)); }