diff --git a/src/github/folderRepositoryManager.ts b/src/github/folderRepositoryManager.ts index 9dd9002c84..ff051f0176 100644 --- a/src/github/folderRepositoryManager.ts +++ b/src/github/folderRepositoryManager.ts @@ -1493,18 +1493,19 @@ 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. + // Fallback logic follows below (lines 1507-1514). + } 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 () {