diff --git a/extensions/git/package.json b/extensions/git/package.json index 5ea3c70e51f..6570b4a36c5 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1515,7 +1515,8 @@ "git.path": { "type": [ "string", - "null" + "null", + "array" ], "markdownDescription": "%config.path%", "default": null, diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 561f8c02f4b..28e72ec312b 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -84,7 +84,7 @@ "command.timelineCopyCommitId": "Copy Commit ID", "command.timelineCopyCommitMessage": "Copy Commit Message", "config.enabled": "Whether git is enabled.", - "config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows).", + "config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows). This can also be an array of string values containing multiple paths to look up.", "config.autoRepositoryDetection": "Configures when repositories should be automatically detected.", "config.autoRepositoryDetection.true": "Scan for both subfolders of the current opened folder and parent folders of open files.", "config.autoRepositoryDetection.false": "Disable automatic repository scanning.", diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 45e49009932..2383e5cb401 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -139,18 +139,28 @@ function findGitWin32(onLookup: (path: string) => void): Promise { .then(undefined, () => findGitWin32InPath(onLookup)); } -export function findGit(hint: string | undefined, onLookup: (path: string) => void): Promise { - const first = hint ? findSpecificGit(hint, onLookup) : Promise.reject(null); +export async function findGit(hint: string | string[] | undefined, onLookup: (path: string) => void): Promise { + const hints = Array.isArray(hint) ? hint : hint ? [hint] : []; - return first - .then(undefined, () => { - switch (process.platform) { - case 'darwin': return findGitDarwin(onLookup); - case 'win32': return findGitWin32(onLookup); - default: return findSpecificGit('git', onLookup); - } - }) - .then(null, () => Promise.reject(new Error('Git installation not found.'))); + for (const hint of hints) { + try { + return await findSpecificGit(hint, onLookup); + } catch { + // noop + } + } + + try { + switch (process.platform) { + case 'darwin': return await findGitDarwin(onLookup); + case 'win32': return await findGitWin32(onLookup); + default: return await findSpecificGit('git', onLookup); + } + } catch { + // noop + } + + throw new Error('Git installation not found.'); } export interface IExecutionResult { diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 8bf85a1b3ee..d35848468db 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -33,7 +33,7 @@ export async function deactivate(): Promise { } async function createModel(context: ExtensionContext, outputChannel: OutputChannel, telemetryReporter: TelemetryReporter, disposables: Disposable[]): Promise { - const pathHint = workspace.getConfiguration('git').get('path'); + const pathHint = workspace.getConfiguration('git').get('path'); const info = await findGit(pathHint, path => outputChannel.appendLine(localize('looking', "Looking for git in: {0}", path))); const askpass = await Askpass.create(outputChannel, context.storagePath);