Skip to content

Commit 5924f49

Browse files
committed
Review individual file changes
1 parent 63dd3ad commit 5924f49

File tree

5 files changed

+69
-6
lines changed

5 files changed

+69
-6
lines changed

package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,6 +1880,20 @@
18801880
"enablement": "github.copilot.chat.reviewDiff.enabled && !github.copilot.interactiveSession.disabled",
18811881
"category": "GitHub Copilot"
18821882
},
1883+
{
1884+
"command": "github.copilot.chat.review.stagedFileChange",
1885+
"title": "%github.copilot.command.reviewFileChange%",
1886+
"icon": "$(code-review)",
1887+
"enablement": "github.copilot.chat.reviewDiff.enabled && !github.copilot.interactiveSession.disabled",
1888+
"category": "GitHub Copilot"
1889+
},
1890+
{
1891+
"command": "github.copilot.chat.review.unstagedFileChange",
1892+
"title": "%github.copilot.command.reviewFileChange%",
1893+
"icon": "$(code-review)",
1894+
"enablement": "github.copilot.chat.reviewDiff.enabled && !github.copilot.interactiveSession.disabled",
1895+
"category": "GitHub Copilot"
1896+
},
18831897
{
18841898
"command": "github.copilot.chat.review.changes.cancel",
18851899
"title": "%github.copilot.command.reviewChanges.cancel%",
@@ -3152,6 +3166,14 @@
31523166
"command": "github.copilot.chat.review.changes",
31533167
"when": "false"
31543168
},
3169+
{
3170+
"command": "github.copilot.chat.review.stagedFileChange",
3171+
"when": "false"
3172+
},
3173+
{
3174+
"command": "github.copilot.chat.review.unstagedFileChange",
3175+
"when": "false"
3176+
},
31553177
{
31563178
"command": "github.copilot.chat.review.changes.cancel",
31573179
"when": "false"
@@ -3446,6 +3468,18 @@
34463468
"group": "inline@-3"
34473469
}
34483470
],
3471+
"scm/resourceState/context": [
3472+
{
3473+
"command": "github.copilot.chat.review.stagedFileChange",
3474+
"group": "3_copilot",
3475+
"when": "github.copilot.chat.reviewDiff.enabled && scmProvider == git && scmResourceGroup == index"
3476+
},
3477+
{
3478+
"command": "github.copilot.chat.review.unstagedFileChange",
3479+
"group": "3_copilot",
3480+
"when": "github.copilot.chat.reviewDiff.enabled && scmProvider == git && scmResourceGroup == workingTree"
3481+
}
3482+
],
34493483
"scm/inputBox": [
34503484
{
34513485
"command": "github.copilot.git.generateCommitMessage",

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"github.copilot.command.reviewUnstagedChanges": "Code Review - Unstaged Changes",
1818
"github.copilot.command.reviewChanges": "Code Review - Uncommitted Changes",
1919
"github.copilot.command.reviewChanges.cancel": "Code Review - Cancel",
20+
"github.copilot.command.reviewFileChange": "Review Changes",
2021
"github.copilot.command.gotoPreviousReviewSuggestion": "Previous Suggestion",
2122
"github.copilot.command.gotoNextReviewSuggestion": "Next Suggestion",
2223
"github.copilot.command.continueReviewInInlineChat": "Discard and Copy to Inline Chat",

src/extension/inlineChat/vscode-node/inlineChatCommands.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,14 @@ ${message}`,
314314
disposables.add(vscode.commands.registerCommand('github.copilot.chat.review.stagedChanges', () => doReview(...instaService.invokeFunction(getServicesForReview), 'index', vscode.ProgressLocation.SourceControl)));
315315
disposables.add(vscode.commands.registerCommand('github.copilot.chat.review.unstagedChanges', () => doReview(...instaService.invokeFunction(getServicesForReview), 'workingTree', vscode.ProgressLocation.SourceControl)));
316316
disposables.add(vscode.commands.registerCommand('github.copilot.chat.review.changes', () => doReview(...instaService.invokeFunction(getServicesForReview), 'all', vscode.ProgressLocation.SourceControl)));
317+
disposables.add(vscode.commands.registerCommand('github.copilot.chat.review.stagedFileChange', (resource: vscode.SourceControlResourceState) => {
318+
vscode.window.showTextDocument(resource.resourceUri, { preview: false });
319+
return doReview(...instaService.invokeFunction(getServicesForReview), { group: 'index', file: resource.resourceUri }, vscode.ProgressLocation.SourceControl);
320+
}));
321+
disposables.add(vscode.commands.registerCommand('github.copilot.chat.review.unstagedFileChange', (resource: vscode.SourceControlResourceState) => {
322+
vscode.window.showTextDocument(resource.resourceUri, { preview: false });
323+
return doReview(...instaService.invokeFunction(getServicesForReview), { group: 'workingTree', file: resource.resourceUri }, vscode.ProgressLocation.SourceControl);
324+
}));
317325
disposables.add(vscode.commands.registerCommand('github.copilot.chat.review.changes.cancel', () => cancelReview(vscode.ProgressLocation.SourceControl, instaService.invokeFunction(accessor => accessor.get(IRunCommandExecutionService)))));
318326
disposables.add(vscode.commands.registerCommand('github.copilot.chat.review.apply', doApplyReview));
319327
disposables.add(vscode.commands.registerCommand('github.copilot.chat.review.applyAndNext', (commentThread: vscode.CommentThread) => doApplyReview(commentThread, true)));

src/extension/review/node/doReview.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import type { TextEditor } from 'vscode';
6+
import type { TextEditor, Uri } from 'vscode';
77
import { IAuthenticationService } from '../../../platform/authentication/common/authentication';
88
import { IRunCommandExecutionService } from '../../../platform/commands/common/runCommandExecutionService';
99
import { TextDocumentSnapshot } from '../../../platform/editing/common/textDocumentSnapshot';
@@ -69,7 +69,7 @@ export async function doReview(
6969
workspaceService: IWorkspaceService,
7070
commandService: IRunCommandExecutionService,
7171
notificationService: INotificationService,
72-
group: 'selection' | 'index' | 'workingTree' | 'all' | { repositoryRoot: string; commitMessages: string[]; patches: { patch: string; fileUri: string; previousFileUri?: string }[] },
72+
group: 'selection' | 'index' | 'workingTree' | 'all' | { group: 'index' | 'workingTree'; file: Uri } | { repositoryRoot: string; commitMessages: string[]; patches: { patch: string; fileUri: string; previousFileUri?: string }[] },
7373
progressLocation: ProgressLocation,
7474
cancellationToken?: CancellationToken
7575
): Promise<FeedbackResult | undefined> {
@@ -121,7 +121,7 @@ export async function doReview(
121121
try {
122122
const copilotToken = await authService.getCopilotToken();
123123
const canUseGitHubAgent = (group === 'index' || group === 'workingTree' || group === 'all' || typeof group === 'object') && copilotToken.isCopilotCodeReviewEnabled;
124-
result = canUseGitHubAgent ? await githubReview(logService, gitExtensionService, authService, capiClientService, domainService, fetcherService, envService, ignoreService, workspaceService, group, progress, tokenSource.token) : await review(instantiationService, gitExtensionService, workspaceService, group, editor, progress, tokenSource.token);
124+
result = canUseGitHubAgent ? await githubReview(logService, gitExtensionService, authService, capiClientService, domainService, fetcherService, envService, ignoreService, workspaceService, group, progress, tokenSource.token) : await review(instantiationService, gitExtensionService, workspaceService, typeof group === 'object' && 'group' in group ? group.group : group, editor, progress, tokenSource.token);
125125
} catch (err) {
126126
result = { type: 'error', reason: err.message, severity: err.severity };
127127
} finally {

src/extension/review/node/githubReviewAgent.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export async function githubReview(
3939
envService: IEnvService,
4040
ignoreService: IIgnoreService,
4141
workspaceService: IWorkspaceService,
42-
group: 'index' | 'workingTree' | 'all' | { repositoryRoot: string; commitMessages: string[]; patches: { patch: string; fileUri: string; previousFileUri?: string }[] },
42+
group: 'index' | 'workingTree' | 'all' | { group: 'index' | 'workingTree'; file: Uri } | { repositoryRoot: string; commitMessages: string[]; patches: { patch: string; fileUri: string; previousFileUri?: string }[] },
4343
progress: Progress<ReviewComment[]>,
4444
cancellationToken: CancellationToken
4545
): Promise<FeedbackResult> {
@@ -76,7 +76,7 @@ export async function githubReview(
7676
}));
7777
return changes;
7878
}))).flat()
79-
: await Promise.all(group.patches.map(async patch => {
79+
: 'repositoryRoot' in group ? await Promise.all(group.patches.map(async patch => {
8080
const uri = Uri.parse(patch.fileUri);
8181
const document = await workspaceService.openTextDocument(uri).then(undefined, () => undefined);
8282
if (!document) {
@@ -92,7 +92,27 @@ export async function githubReview(
9292
after,
9393
document,
9494
};
95-
}))).filter((change): change is NonNullable<typeof change> => !!change);
95+
}))
96+
: await (async () => {
97+
const { group: g, file } = group;
98+
const repository = git.getRepository(file);
99+
const document = await workspaceService.openTextDocument(file).then(undefined, () => undefined);
100+
if (!repository || !document) {
101+
return [];
102+
}
103+
const before = await (g === 'index' ? repository.show('HEAD', file.fsPath).catch(() => '') : repository.show('', file.fsPath).catch(() => ''));
104+
const after = g === 'index' ? await (repository.show('', file.fsPath).catch(() => '')) : document.getText();
105+
const relativePath = path.relative(repository.rootUri.fsPath, file.fsPath);
106+
return [
107+
{
108+
repository,
109+
relativePath: process.platform === 'win32' ? relativePath.replace(/\\/g, '/') : relativePath,
110+
before,
111+
after,
112+
document,
113+
}
114+
];
115+
})()).filter((change): change is NonNullable<typeof change> => !!change);
96116

97117
if (!changes.length) {
98118
return { type: 'success', comments: [] };

0 commit comments

Comments
 (0)