diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index e27b18f1fc1..449dd5ea186 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -834,8 +834,8 @@ export function parseGitmodules(raw: string): Submodule[] { return result; } -export function parseGitRemotes(raw: string): Remote[] { - const remotes: Remote[] = []; +export function parseGitRemotes(raw: string): MutableRemote[] { + const remotes: MutableRemote[] = []; for (const remoteSection of GitConfigParser.parse(raw).filter(s => s.name === 'remote')) { if (remoteSection.subSectionName) { @@ -843,8 +843,7 @@ export function parseGitRemotes(raw: string): Remote[] { name: remoteSection.subSectionName, fetchUrl: remoteSection.properties['url'], pushUrl: remoteSection.properties['pushurl'] ?? remoteSection.properties['url'], - // https://github.com/microsoft/vscode/issues/45271 - isReadOnly: remoteSection.properties['pushurl'] === 'no_push' + isReadOnly: false }); } } @@ -2262,23 +2261,41 @@ export class Repository { } async getRemotes(): Promise { + const remotes: MutableRemote[] = []; + try { // Attempt to parse the config file - const remotes = await this.getRemotesFS(); - if (remotes.length === 0) { - throw new Error('No remotes found in the git config file.'); - } + remotes.push(...await this.getRemotesFS()); - return remotes; + if (remotes.length === 0) { + this.logger.info('No remotes found in the git config file.'); + } } catch (err) { - this.logger.warn(err.message); + this.logger.warn(`getRemotes() - ${err.message}`); + + // Fallback to using git to get the remotes + remotes.push(...await this.getRemotesGit()); } - // Fallback to using git to determine remotes + for (const remote of remotes) { + // https://github.com/microsoft/vscode/issues/45271 + remote.isReadOnly = remote.pushUrl === undefined || remote.pushUrl === 'no_push'; + } + + return remotes; + } + + private async getRemotesFS(): Promise { + const raw = await fs.readFile(path.join(this.dotGit.commonPath ?? this.dotGit.path, 'config'), 'utf8'); + return parseGitRemotes(raw); + } + + private async getRemotesGit(): Promise { + const remotes: MutableRemote[] = []; + const result = await this.exec(['remote', '--verbose']); const lines = result.stdout.trim().split('\n').filter(l => !!l); - const remotes: MutableRemote[] = []; for (const line of lines) { const parts = line.split(/\s/); @@ -2299,19 +2316,11 @@ export class Repository { remote.fetchUrl = url; remote.pushUrl = url; } - - // https://github.com/microsoft/vscode/issues/45271 - remote.isReadOnly = remote.pushUrl === undefined || remote.pushUrl === 'no_push'; } return remotes; } - private async getRemotesFS(): Promise { - const raw = await fs.readFile(path.join(this.dotGit.commonPath ?? this.dotGit.path, 'config'), 'utf8'); - return parseGitRemotes(raw); - } - async getBranch(name: string): Promise { if (name === 'HEAD') { return this.getHEAD(); diff --git a/extensions/git/src/test/git.test.ts b/extensions/git/src/test/git.test.ts index 27ad7d93d5f..10d7461080e 100644 --- a/extensions/git/src/test/git.test.ts +++ b/extensions/git/src/test/git.test.ts @@ -213,18 +213,6 @@ suite('git', () => { ]); }); - test('single remote (read-only)', () => { - const sample = `[remote "origin"] - url = https://github.com/microsoft/vscode.git - fetch = +refs/heads/*:refs/remotes/origin/* - pushurl = no_push -`; - - assert.deepStrictEqual(parseGitRemotes(sample), [ - { name: 'origin', fetchUrl: 'https://github.com/microsoft/vscode.git', pushUrl: 'no_push', isReadOnly: true } - ]); - }); - test('single remote (multiple urls)', () => { const sample = `[remote "origin"] url = https://github.com/microsoft/vscode.git