Fix worktree checkout for pull requests from forks by Copilot · Pull Request #8987 · microsoft/vscode-pull-request-github · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/@types/vscode.proposed.authIssuers.d.ts
7 changes: 7 additions & 0 deletions src/@types/vscode.proposed.chatParticipantAdditions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,15 @@ declare module 'vscode' {
ranges: Range[];
}

/** The Auto routing tier a request was resolved with. */
export type ChatAutoModeTier = 'efficiency' | 'balance' | 'intelligence' | 'fast';

export class ChatResponseTextEditPart {
uri: Uri;
edits: TextEdit[];
isDone?: boolean;
/** The Auto routing tier that produced these edits, for edit attribution. */
autoTier?: ChatAutoModeTier;
constructor(uri: Uri, done: true);
constructor(uri: Uri, edits: TextEdit | TextEdit[]);
}
Expand All @@ -61,6 +66,8 @@ declare module 'vscode' {
uri: Uri;
edits: NotebookEdit[];
isDone?: boolean;
/** The Auto routing tier that produced these edits, for edit attribution. */
autoTier?: ChatAutoModeTier;
constructor(uri: Uri, done: true);
constructor(uri: Uri, edits: NotebookEdit | NotebookEdit[]);
}
Expand Down
2 changes: 2 additions & 0 deletions src/@types/vscode.proposed.chatSessionsProvider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,8 @@ declare module 'vscode' {
};
readonly maxInputTokens?: number;
readonly maxOutputTokens?: number;
/** The total context window, independent of the input and output token limits. */
readonly maxContextWindowTokens?: number;
readonly capabilities?: {
readonly vision?: boolean;
readonly toolCalling?: boolean;
Expand Down
18 changes: 13 additions & 5 deletions src/github/worktree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import * as path from 'path';
import * as vscode from 'vscode';
import { FolderRepositoryManager } from './folderRepositoryManager';
import { PullRequestGitHelper } from './pullRequestGitHelper';
import { PullRequestModel } from './pullRequestModel';
import { Repository } from '../api/api';
import { commands } from '../common/executeCommands';
Expand Down Expand Up @@ -46,8 +47,7 @@ export async function checkoutPRInWorktree(
const parentDir = path.dirname(repoRootPath);
const repoFolderName = path.basename(repoRootPath);
const defaultWorktreePath = path.join(parentDir, `${repoFolderName}.worktrees`, `pr-${pullRequestModel.number}`);
const branchName = prHead.ref;
const remoteName = pullRequestModel.remote.remoteName;
const isFork = !prHead.repositoryCloneUrl.equals(pullRequestModel.remote.gitProtocol);

// Ask user for worktree location first (not in progress)
const worktreeUri = await vscode.window.showSaveDialog({
Expand All @@ -61,7 +61,6 @@ export async function checkoutPRInWorktree(
}

const worktreePath = worktreeUri.fsPath;
const trackedBranchName = `${remoteName}/${branchName}`;

try {
// Check if the createWorktree API is available
Expand All @@ -76,8 +75,16 @@ export async function checkoutPRInWorktree(
title: vscode.l10n.t('Creating worktree for Pull Request #{0}...', pullRequestModel.number),
},
async () => {
const remoteName = isFork
? await PullRequestGitHelper.createRemote(repositoryToUse, pullRequestModel.remote, prHead.repositoryCloneUrl)
: pullRequestModel.remote.remoteName;
const branchName = isFork
? await PullRequestGitHelper.calculateUniqueBranchNameForPR(repositoryToUse, pullRequestModel)
: prHead.ref;
const trackedBranchName = `${remoteName}/${prHead.ref}`;

// Fetch the PR branch first
await repositoryToUse.fetch({ remote: remoteName, ref: branchName });
await repositoryToUse.fetch({ remote: remoteName, ref: prHead.ref });

// Check if the branch already exists locally
let branchExists = false;
Expand Down Expand Up @@ -122,7 +129,8 @@ export async function checkoutPRInWorktree(
await commands.openFolder(worktreeUri, { forceNewWindow: false });
}
} catch (e) {
const errorMessage = e instanceof Error ? e.message : String(e);
const stderr = e && typeof e === 'object' ? Reflect.get(e, 'stderr') : undefined;
const errorMessage = (typeof stderr === 'string' && stderr.trim()) || (e instanceof Error ? e.message : String(e));
Logger.error(`Failed to create worktree: ${errorMessage}`, logId);
vscode.window.showErrorMessage(vscode.l10n.t('Failed to create worktree: {0}', errorMessage));
}
Expand Down
201 changes: 201 additions & 0 deletions src/test/github/worktree.test.ts
Loading