Skip to content

Commit 23d8322

Browse files
committed
introduce git APIState
fixes microsoft#77787
1 parent 30eaedc commit 23d8322

3 files changed

Lines changed: 40 additions & 13 deletions

File tree

extensions/git/src/api/api1.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { Model } from '../model';
77
import { Repository as BaseRepository, Resource } from '../repository';
8-
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions } from './git';
8+
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState } from './git';
99
import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode';
1010
import { mapEvent } from '../util';
1111

@@ -214,6 +214,14 @@ export class ApiImpl implements API {
214214

215215
readonly git = new ApiGit(this._model);
216216

217+
get state(): APIState {
218+
return this._model.state;
219+
}
220+
221+
get onDidChangeState(): Event<APIState> {
222+
return this._model.onDidChangeState;
223+
}
224+
217225
get onDidOpenRepository(): Event<Repository> {
218226
return mapEvent(this._model.onDidOpenRepository, r => new ApiRepository(r));
219227
}

extensions/git/src/api/git.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,11 @@ export interface Repository {
176176
log(options?: LogOptions): Promise<Commit[]>;
177177
}
178178

179+
export type APIState = 'uninitialized' | 'initialized';
180+
179181
export interface API {
182+
readonly state: APIState;
183+
readonly onDidChangeState: Event<APIState>;
180184
readonly git: Git;
181185
readonly repositories: Repository[];
182186
readonly onDidOpenRepository: Event<Repository>;

extensions/git/src/model.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import * as path from 'path';
1212
import * as fs from 'fs';
1313
import * as nls from 'vscode-nls';
1414
import { fromGitUri } from './uri';
15-
import { GitErrorCodes } from './api/git';
15+
import { GitErrorCodes, APIState as State } from './api/git';
1616

1717
const localize = nls.loadMessageBundle();
1818

@@ -63,15 +63,22 @@ export class Model {
6363

6464
private possibleGitRepositoryPaths = new Set<string>();
6565

66+
private _onDidChangeState = new EventEmitter<State>();
67+
readonly onDidChangeState = this._onDidChangeState.event;
68+
69+
private _state: State = 'uninitialized';
70+
get state(): State { return this._state; }
71+
72+
setState(state: State): void {
73+
this._state = state;
74+
this._onDidChangeState.fire(state);
75+
}
76+
6677
private disposables: Disposable[] = [];
6778

6879
constructor(readonly git: Git, private globalState: Memento, private outputChannel: OutputChannel) {
6980
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
70-
this.onDidChangeWorkspaceFolders({ added: workspace.workspaceFolders || [], removed: [] });
71-
7281
window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables);
73-
this.onDidChangeVisibleTextEditors(window.visibleTextEditors);
74-
7582
workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables);
7683

7784
const fsWatcher = workspace.createFileSystemWatcher('**');
@@ -82,7 +89,15 @@ export class Model {
8289
const onPossibleGitRepositoryChange = filterEvent(onGitRepositoryChange, uri => !this.getRepository(uri));
8390
onPossibleGitRepositoryChange(this.onPossibleGitRepositoryChange, this, this.disposables);
8491

85-
this.scanWorkspaceFolders();
92+
this.doInitialScan().finally(() => this.setState('initialized'));
93+
}
94+
95+
private async doInitialScan(): Promise<void> {
96+
await Promise.all([
97+
this.onDidChangeWorkspaceFolders({ added: workspace.workspaceFolders || [], removed: [] }),
98+
this.onDidChangeVisibleTextEditors(window.visibleTextEditors),
99+
this.scanWorkspaceFolders()
100+
]);
86101
}
87102

88103
/**
@@ -157,8 +172,8 @@ export class Model {
157172
.filter(r => !activeRepositories.has(r!.repository))
158173
.filter(r => !(workspace.workspaceFolders || []).some(f => isDescendant(f.uri.fsPath, r!.repository.root))) as OpenRepository[];
159174

160-
possibleRepositoryFolders.forEach(p => this.openRepository(p.uri.fsPath));
161175
openRepositoriesToDispose.forEach(r => r.dispose());
176+
await Promise.all(possibleRepositoryFolders.map(p => this.openRepository(p.uri.fsPath)));
162177
}
163178

164179
private onDidChangeConfiguration(): void {
@@ -175,15 +190,15 @@ export class Model {
175190
openRepositoriesToDispose.forEach(r => r.dispose());
176191
}
177192

178-
private onDidChangeVisibleTextEditors(editors: TextEditor[]): void {
193+
private async onDidChangeVisibleTextEditors(editors: TextEditor[]): Promise<void> {
179194
const config = workspace.getConfiguration('git');
180195
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
181196

182197
if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'openEditors') {
183198
return;
184199
}
185200

186-
editors.forEach(editor => {
201+
await Promise.all(editors.map(async editor => {
187202
const uri = editor.document.uri;
188203

189204
if (uri.scheme !== 'file') {
@@ -196,8 +211,8 @@ export class Model {
196211
return;
197212
}
198213

199-
this.openRepository(path.dirname(uri.fsPath));
200-
});
214+
await this.openRepository(path.dirname(uri.fsPath));
215+
}));
201216
}
202217

203218
@sequentialize
@@ -421,4 +436,4 @@ export class Model {
421436
this.possibleGitRepositoryPaths.clear();
422437
this.disposables = dispose(this.disposables);
423438
}
424-
}
439+
}

0 commit comments

Comments
 (0)