From 3a222005368b7af09e4364ec953d9f8f384f81de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 14:07:58 +0000 Subject: [PATCH 1/4] Initial plan From cb9936955d6ce93467804683d6ac8b19677f5c11 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 14:15:22 +0000 Subject: [PATCH 2/4] Initial plan for fixing remote selection when starting work on issue Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/@types/vscode.proposed.chatParticipantAdditions.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index 71520fa1ec..aa7001a3d2 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -105,6 +105,7 @@ declare module 'vscode' { isComplete?: boolean; toolSpecificData?: ChatTerminalToolInvocationData; fromSubAgent?: boolean; + presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); } From 236916470b9d6498c5f2907a8497c0b2c54459a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 14:22:21 +0000 Subject: [PATCH 3/4] Fix getOrigin to fall back to configured GitHub remotes when upstream is not GitHub Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/github/folderRepositoryManager.ts | 16 ++++---- .../github/folderRepositoryManager.test.ts | 37 ++++++++++++++++++- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/github/folderRepositoryManager.ts b/src/github/folderRepositoryManager.ts index 9dd9002c84..ab15267eae 100644 --- a/src/github/folderRepositoryManager.ts +++ b/src/github/folderRepositoryManager.ts @@ -1493,18 +1493,18 @@ export class FolderRepositoryManager extends Disposable { return this.createAndAddGitHubRepository(remote, this._credentialStore); } - Logger.error(`The remote '${upstreamRef.remote}' is not a GitHub repository.`, this.id); + Logger.warn(`The remote '${upstreamRef.remote}' is not a GitHub repository. Falling back to configured GitHub remotes.`, this.id); - // No GitHubRepository? We currently won't try pushing elsewhere, - // so fail. - throw new BadUpstreamError(this.repository.state.HEAD!.name!, upstreamRef, 'is not a GitHub repo'); + // No GitHubRepository? Fall back to using configured GitHub remotes + // instead of failing, to support scenarios where the upstream is set to + // a non-GitHub remote but GitHub remotes are configured separately. + } else { + // Otherwise, we'll push upstream. + return upstream; } - - // Otherwise, we'll push upstream. - return upstream; } - // If no upstream is set, let's go digging. + // If no upstream is set, or upstream is not a GitHub remote, let's go digging. const [first, ...rest] = this._githubRepositories; return !rest.length // Is there only one GitHub remote? ? first // I GUESS THAT'S WHAT WE'RE GOING WITH, THEN. diff --git a/src/test/github/folderRepositoryManager.test.ts b/src/test/github/folderRepositoryManager.test.ts index ad1cbff0f6..018850302c 100644 --- a/src/test/github/folderRepositoryManager.test.ts +++ b/src/test/github/folderRepositoryManager.test.ts @@ -30,6 +30,7 @@ describe('PullRequestManager', function () { let manager: FolderRepositoryManager; let telemetry: MockTelemetry; let mockThemeWatcher: MockThemeWatcher; + let mockRepository: MockRepository; beforeEach(function () { sinon = createSandbox(); @@ -37,11 +38,11 @@ describe('PullRequestManager', function () { telemetry = new MockTelemetry(); mockThemeWatcher = new MockThemeWatcher(); - const repository = new MockRepository(); + mockRepository = new MockRepository(); const context = new MockExtensionContext(); const credentialStore = new CredentialStore(telemetry, context); const repositoriesManager = new RepositoriesManager(credentialStore, telemetry); - manager = new FolderRepositoryManager(0, context, repository, telemetry, new GitApiImpl(repositoriesManager), credentialStore, new CreatePullRequestHelper(), mockThemeWatcher); + manager = new FolderRepositoryManager(0, context, mockRepository, telemetry, new GitApiImpl(repositoriesManager), credentialStore, new CreatePullRequestHelper(), mockThemeWatcher); }); afterEach(function () { @@ -68,6 +69,38 @@ describe('PullRequestManager', function () { assert.deepStrictEqual(manager.activePullRequest, pr); }); }); + + describe('getOrigin', function () { + it('falls back to configured GitHub remote when upstream is not GitHub', async function () { + // Setup: Add a GitHub remote + const githubUrl = 'https://github.com/test/repo.git'; + await mockRepository.addRemote('github', githubUrl); + + const githubProtocol = new Protocol(githubUrl); + const githubRemote = new GitHubRemote('github', githubUrl, githubProtocol, GitHubServerType.GitHubDotCom); + const rootUri = Uri.file('/test/repo'); + const githubRepository = new GitHubRepository(1, githubRemote, rootUri, manager.credentialStore, telemetry); + + // Manually set up the GitHub repository in the manager (simulating successful initialization) + (manager as any)._githubRepositories = [githubRepository]; + + // Add a non-GitHub remote (simulating the scenario from the bug) + await mockRepository.addRemote('origin', 'https://example.com/git/repo.git'); + + // Create a branch with upstream set to non-GitHub remote + await mockRepository.createBranch('test-branch', true); + await mockRepository.setBranchUpstream('test-branch', 'refs/remotes/origin/main'); + + // Mock getAllGitHubRemotes to return only the github remote + sinon.stub(manager, 'getAllGitHubRemotes').resolves([githubRemote]); + + // Act: getOrigin should fall back to the configured GitHub remote instead of throwing + const result = await manager.getOrigin(); + + // Assert: Should return the GitHub repository, not throw an error + assert.strictEqual(result, githubRepository); + }); + }); }); describe('titleAndBodyFrom', function () { From 5d0bafa2f97b4196258cc4d68a760b5bc5daf643 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 14:26:27 +0000 Subject: [PATCH 4/4] Address code review feedback: remove unrelated file change and improve comments Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/@types/vscode.proposed.chatParticipantAdditions.d.ts | 1 - src/github/folderRepositoryManager.ts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index aa7001a3d2..71520fa1ec 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -105,7 +105,6 @@ declare module 'vscode' { isComplete?: boolean; toolSpecificData?: ChatTerminalToolInvocationData; fromSubAgent?: boolean; - presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); } diff --git a/src/github/folderRepositoryManager.ts b/src/github/folderRepositoryManager.ts index ab15267eae..ff051f0176 100644 --- a/src/github/folderRepositoryManager.ts +++ b/src/github/folderRepositoryManager.ts @@ -1498,6 +1498,7 @@ export class FolderRepositoryManager extends Disposable { // No GitHubRepository? Fall back to using configured GitHub remotes // instead of failing, to support scenarios where the upstream is set to // a non-GitHub remote but GitHub remotes are configured separately. + // Fallback logic follows below (lines 1507-1514). } else { // Otherwise, we'll push upstream. return upstream;