Skip to content

Commit c05580f

Browse files
authored
Automatically push base_ref if it doesnt exist on remote (#7144)
* checkpoint for microsoft/vscode#252632 * automatically push base_ref if it doesnt exist on remote (fix microsoft/vscode#252632)
1 parent 6242166 commit c05580f

1 file changed

Lines changed: 27 additions & 9 deletions

File tree

src/github/copilotRemoteAgent.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { CopilotPRWatcher, CopilotStateModel } from './copilotPrWatcher';
1717
import { CredentialStore } from './credentials';
1818
import { FolderRepositoryManager } from './folderRepositoryManager';
1919
import { RepositoriesManager } from './repositoriesManager';
20+
import { GitHubRepository } from './githubRepository';
21+
import Logger from '../common/logger';
2022

2123
type RemoteAgentSuccessResult = { link: string; state: 'success'; number: number; webviewUri: vscode.Uri; llmDetails: string };
2224
type RemoteAgentErrorResult = { error: string; state: 'error' };
@@ -169,13 +171,14 @@ export class CopilotRemoteAgentManager extends Disposable {
169171
.getConfiguration(CODING_AGENT).get(CODING_AGENT_AUTO_COMMIT_AND_PUSH, false);
170172
}
171173

172-
async repoInfo(): Promise<{ owner: string; repo: string; baseRef: string; remote: GitHubRemote; repository: Repository; fm: FolderRepositoryManager } | undefined> {
174+
async repoInfo(): Promise<{ owner: string; repo: string; baseRef: string; remote: GitHubRemote; repository: Repository; ghRepository: GitHubRepository; fm: FolderRepositoryManager } | undefined> {
173175
if (!this.repositoriesManager.folderManagers.length) {
174176
return;
175177
}
176178
const fm = this.repositoriesManager.folderManagers[0];
177179
const repository = fm?.repository;
178-
if (!repository) {
180+
const ghRepository = fm?.gitHubRepositories.find(repo => repo.remote instanceof GitHubRemote) as GitHubRepository | undefined;
181+
if (!repository || !ghRepository) {
179182
return;
180183
}
181184

@@ -194,7 +197,7 @@ export class CopilotRemoteAgentManager extends Disposable {
194197
if (!owner || !repo || !baseRef || !repository) {
195198
return;
196199
}
197-
return { owner, repo, baseRef, remote, repository, fm };
200+
return { owner, repo, baseRef, remote, repository, ghRepository, fm };
198201
}
199202

200203
async commandImpl(args?: ICopilotRemoteAgentCommandArgs): Promise<string | undefined> {
@@ -212,7 +215,7 @@ export class CopilotRemoteAgentManager extends Disposable {
212215
return;
213216
}
214217
const { repository, owner, repo } = repoInfo;
215-
const repoName = `${owner}/${repo}`; // TODO: Make sure this is where we'll push to
218+
const repoName = `${owner}/${repo}`;
216219
const hasChanges = repository.state.workingTreeChanges.length > 0 || repository.state.indexChanges.length > 0;
217220
const learnMoreCb = async () => {
218221
vscode.env.openExternal(vscode.Uri.parse('https://docs.github.com/copilot/using-github-copilot/coding-agent'));
@@ -300,15 +303,15 @@ export class CopilotRemoteAgentManager extends Disposable {
300303
if (!repoInfo) {
301304
return { error: vscode.l10n.t('No repository information found. Please open a workspace with a GitHub repository.'), state: 'error' };
302305
}
303-
const { owner, repo, remote, repository, baseRef } = repoInfo;
306+
const { owner, repo, remote, repository, ghRepository, baseRef } = repoInfo;
304307

305308
// NOTE: This is as unobtrusive as possible with the current high-level APIs.
306309
// We only create a new branch and commit if there are staged or working changes.
307310
// This could be improved if we add lower-level APIs to our git extension (e.g. in-memory temp git index).
308311

309312
let ref = baseRef;
310-
const hasChanges = repository.state.workingTreeChanges.length > 0 || repository.state.indexChanges.length > 0;
311-
if (hasChanges && autoPushAndCommit) {
313+
const hasChanges = autoPushAndCommit && (repository.state.workingTreeChanges.length > 0 || repository.state.indexChanges.length > 0);
314+
if (hasChanges) {
312315
if (!this.autoCommitAndPushEnabled()) {
313316
return { error: vscode.l10n.t('Uncommitted changes detected. Please commit or stash your changes before starting the remote agent. Enable \'{0}\' to push your changes automatically.', CODING_AGENT_AUTO_COMMIT_AND_PUSH), state: 'error' };
314317
}
@@ -346,6 +349,21 @@ export class CopilotRemoteAgentManager extends Disposable {
346349
}
347350
}
348351

352+
const base_ref = hasChanges ? baseRef : ref;
353+
try {
354+
if (!(await ghRepository.hasBranch(base_ref))) {
355+
if (!this.autoCommitAndPushEnabled()) {
356+
// We won't auto-push a branch if the user has disabled the setting
357+
return { error: vscode.l10n.t('The branch \'{0}\' does not exist on the remote repository \'{1}/{2}\'. Please create the remote branch first.', base_ref, owner, repo), state: 'error' };
358+
}
359+
// Push the branch
360+
Logger.appendLine(`Base ref needs to exist on remote. Auto pushing base_ref '${base_ref}' to remote repository '${owner}/${repo}'`, CopilotRemoteAgentManager.ID);
361+
await repository.push(remote.remoteName, base_ref, true);
362+
}
363+
} catch (error) {
364+
return { error: vscode.l10n.t('Failed to configure base branch \'{0}\' does not exist on the remote repository \'{1}/{2}\'. Please create the remote branch first.', base_ref, owner, repo), state: 'error' };
365+
}
366+
349367
let title = prompt;
350368
const titleMatch = problemContext.match(/TITLE: \s*(.*)/i);
351369
if (titleMatch && titleMatch[1]) {
@@ -358,8 +376,8 @@ export class CopilotRemoteAgentManager extends Disposable {
358376
pull_request: {
359377
title,
360378
body_placeholder: problemContext,
361-
base_ref: hasChanges && autoPushAndCommit ? baseRef : ref,
362-
...(hasChanges && autoPushAndCommit && { head_ref: ref })
379+
base_ref,
380+
...(hasChanges && { head_ref: ref })
363381
}
364382
};
365383

0 commit comments

Comments
 (0)