Git - add setting to control repository scan depth (#140260)

This commit is contained in:
Ladislau Szomoru 2022-01-07 10:18:53 +01:00 committed by GitHub
parent 6540fc6105
commit a4d7014d7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 5 deletions

View file

@ -2215,6 +2215,12 @@
"scope": "resource",
"default": 10000,
"description": "%config.statusLimit%"
},
"git.repositoryScanMaxDepth": {
"type": "number",
"scope": "resource",
"default": 1,
"markdownDescription": "%config.repositoryScanMaxDepth%"
}
}
},

View file

@ -193,6 +193,7 @@
"config.showUnpublishedCommitsButton.whenEmpty": "Only shows the action button if there are no other changes and there are unpublished commits.",
"config.showUnpublishedCommitsButton.never": "Never shows the action button.",
"config.statusLimit": "Controls how to limit the number of changes that can be parsed from Git status command. Can be set to 0 for no limit.",
"config.repositoryScanMaxDepth": "Controls the depth used when scanning workspace folders for Git repositories when `#git.autoRepositoryDetection#` is set to `true` or `subFolders`. Can be set to `-1` for no limit.",
"submenu.explorer": "Git",
"submenu.commit": "Commit",
"submenu.commit.amend": "Amend",

View file

@ -17,6 +17,7 @@ import { Askpass } from './askpass';
import { IPushErrorHandlerRegistry } from './pushError';
import { ApiRepository } from './api/api1';
import { IRemoteSourcePublisherRegistry } from './remotePublisher';
import { Log, LogLevel } from './log';
const localize = nls.loadMessageBundle();
@ -133,12 +134,20 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
}
/**
* Scans the first level of each workspace folder, looking
* for git repositories.
* Scans each workspace folder, looking for git repositories. By
* default it scans one level deep but that can be changed using
* the git.repositoryScanMaxDepth setting.
*/
private async scanWorkspaceFolders(): Promise<void> {
const config = workspace.getConfiguration('git');
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
const repositoryScanMaxDepth = config.get<number>('repositoryScanMaxDepth', 1);
// Log repository scan settings
if (Log.logLevel <= LogLevel.Trace) {
this.outputChannel.appendLine(`${logTimestamp()} Trace: autoRepositoryDetection="${autoRepositoryDetection}"`);
this.outputChannel.appendLine(`${logTimestamp()} Trace: repositoryScanMaxDepth=${repositoryScanMaxDepth}`);
}
if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'subFolders') {
return;
@ -146,9 +155,11 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
await Promise.all((workspace.workspaceFolders || []).map(async folder => {
const root = folder.uri.fsPath;
const children = (await fs.promises.readdir(root, { withFileTypes: true })).filter(dirent => dirent.isDirectory()).map(dirent => dirent.name);
const subfolders = new Set(children.filter(child => child !== '.git').map(child => path.join(root, child)));
// Workspace folder children
const subfolders = new Set(await this.traverseWorkspaceFolder(root, repositoryScanMaxDepth));
// Repository scan folders
const scanPaths = (workspace.isTrusted ? workspace.getConfiguration('git', folder.uri) : config).get<string[]>('scanRepositories') || [];
for (const scanPath of scanPaths) {
if (scanPath === '.git') {
@ -167,6 +178,29 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
}));
}
private async traverseWorkspaceFolder(workspaceFolder: string, maxDepth: number): Promise<string[]> {
const result: string[] = [];
const foldersToTravers = [{ path: workspaceFolder, depth: 0 }];
while (foldersToTravers.length > 0) {
const currentFolder = foldersToTravers.shift()!;
if (currentFolder.depth < maxDepth || maxDepth === -1) {
const children = await fs.promises.readdir(currentFolder.path, { withFileTypes: true });
const childrenFolders = children
.filter(dirent => dirent.isDirectory() && dirent.name !== '.git')
.map(dirent => path.join(currentFolder.path, dirent.name));
result.push(...childrenFolders);
foldersToTravers.push(...childrenFolders.map(folder => {
return { path: folder, depth: currentFolder.depth + 1 };
}));
}
}
return result;
}
private onPossibleGitRepositoryChange(uri: Uri): void {
const config = workspace.getConfiguration('git');
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
@ -303,7 +337,9 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
repository.status(); // do not await this, we want SCM to know about the repo asap
} catch (ex) {
// noop
this.outputChannel.appendLine(`${logTimestamp()} Opening repository for path='${repoPath}' failed; ex=${ex}`);
if (Log.logLevel <= LogLevel.Trace) {
this.outputChannel.appendLine(`${logTimestamp()} Trace: Opening repository for path='${repoPath}' failed; ex=${ex}`);
}
}
}