Skip to content

Commit

Permalink
Git - Extract querying for status so that it can run in parallel with…
Browse files Browse the repository at this point in the history
… the other operations (#163990)
  • Loading branch information
lszomoru authored Oct 20, 2022
1 parent 76191c7 commit 2fa61a1
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 59 deletions.
6 changes: 3 additions & 3 deletions extensions/git/src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1954,7 +1954,7 @@ export class Repository {

const child = this.stream(args, { env });

const onExit = (exitCode: number) => {
const onClose = (exitCode: number) => {
if (exitCode !== 0) {
const stderr = stderrData.join('');
return e(new GitError({
Expand All @@ -1975,7 +1975,7 @@ export class Repository {
parser.update(raw);

if (limit !== 0 && parser.status.length > limit) {
child.removeListener('exit', onExit);
child.removeListener('close', onClose);
child.stdout!.removeListener('data', onStdoutData);
child.kill();

Expand All @@ -1991,7 +1991,7 @@ export class Repository {
child.stderr!.on('data', raw => stderrData.push(raw as string));

child.on('error', cpErrorHandler(e));
child.on('exit', onExit);
child.on('close', onClose);
});
}

Expand Down
121 changes: 65 additions & 56 deletions extensions/git/src/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,45 @@ export class Repository implements Disposable {

@throttle
private async updateModelState(): Promise<void> {
const config = workspace.getConfiguration('git');
let sort = config.get<'alphabetically' | 'committerdate'>('branchSortOrder') || 'alphabetically';
if (sort !== 'alphabetically' && sort !== 'committerdate') {
sort = 'alphabetically';
}

const [HEAD, refs, remotes, submodules, status, rebaseCommit, mergeInProgress, commitTemplate] =
await Promise.all([
this.repository.getHEADBranch(),
this.repository.getRefs({ sort }),
this.repository.getRemotes(),
this.repository.getSubmodules(),
this.getStatus(),
this.getRebaseCommit(),
this.isMergeInProgress(),
this.getInputTemplate()]);

this._HEAD = HEAD;
this._refs = refs!;
this._remotes = remotes!;
this._submodules = submodules!;
this.rebaseCommit = rebaseCommit;
this.mergeInProgress = mergeInProgress;

// set resource groups
this.mergeGroup.resourceStates = status.merge;
this.indexGroup.resourceStates = status.index;
this.workingTreeGroup.resourceStates = status.workingTree;
this.untrackedGroup.resourceStates = status.untracked;

// set count badge
this.setCountBadge();

this._onDidChangeStatus.fire();

this._sourceControl.commitTemplate = commitTemplate;
}

private async getStatus(): Promise<{ index: Resource[]; workingTree: Resource[]; merge: Resource[]; untracked: Resource[] }> {
const scopedConfig = workspace.getConfiguration('git', Uri.file(this.repository.root));
const untrackedChanges = scopedConfig.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges');
const ignoreSubmodules = scopedConfig.get<boolean>('ignoreSubmodules');
Expand All @@ -1947,6 +1986,8 @@ export class Repository implements Disposable {
const { status, statusLength, didHitLimit } = await this.repository.getStatus({ limit, ignoreSubmodules, untrackedChanges });
const totalTime = new Date().getTime() - start;

this.isRepositoryHuge = didHitLimit ? { limit } : false;

if (didHitLimit) {
/* __GDPR__
"statusLimit" : {
Expand All @@ -1960,12 +2001,28 @@ export class Repository implements Disposable {
this.telemetryReporter.sendTelemetryEvent('statusLimit', { ignoreSubmodules: String(ignoreSubmodules) }, { limit, statusLength, totalTime });
}

if (totalTime > 5000) {
/* __GDPR__
"statusSlow" : {
"owner": "digitarald",
"comment": "Reports when git status is slower than 5s",
"expiration": "1.73",
"ignoreSubmodules": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Setting indicating whether submodules are ignored" },
"didHitLimit": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Total number of status entries" },
"didWarnAboutLimit": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "True when the user was warned about slow git status" },
"statusLength": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Total number of status entries" },
"totalTime": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Total number of ms the operation took" }
}
*/
this.telemetryReporter.sendTelemetryEvent('statusSlow', { ignoreSubmodules: String(ignoreSubmodules), didHitLimit: String(didHitLimit), didWarnAboutLimit: String(this.didWarnAboutLimit) }, { statusLength, totalTime });
}

// Triggers or clears any validation warning
this._sourceControl.inputBox.validateInput = this._sourceControl.inputBox.validateInput;

const config = workspace.getConfiguration('git');
const shouldIgnore = config.get<boolean>('ignoreLimitWarning') === true;
const useIcons = !config.get<boolean>('decorations.enabled', true);
this.isRepositoryHuge = didHitLimit ? { limit } : false;
// Triggers or clears any validation warning
this._sourceControl.inputBox.validateInput = this._sourceControl.inputBox.validateInput;

if (didHitLimit && !shouldIgnore && !this.didWarnAboutLimit) {
const knownHugeFolderPaths = await this.findKnownHugeFolderPathsToIgnore();
Expand Down Expand Up @@ -2001,47 +2058,10 @@ export class Repository implements Disposable {
}
}

if (totalTime > 5000) {
/* __GDPR__
"statusSlow" : {
"owner": "digitarald",
"comment": "Reports when git status is slower than 5s",
"expiration": "1.73",
"ignoreSubmodules": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Setting indicating whether submodules are ignored" },
"didHitLimit": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Total number of status entries" },
"didWarnAboutLimit": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "True when the user was warned about slow git status" },
"statusLength": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Total number of status entries" },
"totalTime": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Total number of ms the operation took" }
}
*/
this.telemetryReporter.sendTelemetryEvent('statusSlow', { ignoreSubmodules: String(ignoreSubmodules), didHitLimit: String(didHitLimit), didWarnAboutLimit: String(this.didWarnAboutLimit) }, { statusLength, totalTime });
}

let sort = config.get<'alphabetically' | 'committerdate'>('branchSortOrder') || 'alphabetically';
if (sort !== 'alphabetically' && sort !== 'committerdate') {
sort = 'alphabetically';
}
const [HEAD, refs, remotes, submodules, rebaseCommit, mergeInProgress, commitTemplate] =
await Promise.all([
this.repository.getHEADBranch(),
this.repository.getRefs({ sort }),
this.repository.getRemotes(),
this.repository.getSubmodules(),
this.getRebaseCommit(),
this.isMergeInProgress(),
this.getInputTemplate()]);

this._HEAD = HEAD;
this._refs = refs!;
this._remotes = remotes!;
this._submodules = submodules!;
this.rebaseCommit = rebaseCommit;
this.mergeInProgress = mergeInProgress;

const index: Resource[] = [];
const workingTree: Resource[] = [];
const merge: Resource[] = [];
const untracked: Resource[] = [];
const index: Resource[] = [],
workingTree: Resource[] = [],
merge: Resource[] = [],
untracked: Resource[] = [];

status.forEach(raw => {
const uri = Uri.file(path.join(this.repository.root, raw.path));
Expand Down Expand Up @@ -2086,18 +2106,7 @@ export class Repository implements Disposable {
return undefined;
});

// set resource groups
this.mergeGroup.resourceStates = merge;
this.indexGroup.resourceStates = index;
this.workingTreeGroup.resourceStates = workingTree;
this.untrackedGroup.resourceStates = untracked;

// set count badge
this.setCountBadge();

this._onDidChangeStatus.fire();

this._sourceControl.commitTemplate = commitTemplate;
return { index, workingTree, merge, untracked };
}

private setCountBadge(): void {
Expand Down

0 comments on commit 2fa61a1

Please sign in to comment.