Skip to content

Commit

Permalink
Suggestions end up in unsubmittable pending state (#6504)
Browse files Browse the repository at this point in the history
Fixes #6494
  • Loading branch information
alexr00 authored Dec 2, 2024
1 parent 5a1b1eb commit 268854f
Showing 1 changed file with 41 additions and 12 deletions.
53 changes: 41 additions & 12 deletions src/view/reviewManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import * as nodePath from 'path';
import * as vscode from 'vscode';
import type { Branch, Repository } from '../api/api';
import type { Branch, Change, Repository } from '../api/api';
import { GitApiImpl, GitErrorCodes, Status } from '../api/api1';
import { openDescription } from '../commands';
import { DiffChangeType, DiffHunk, parsePatch, splitIntoSmallerHunks } from '../common/diffHunk';
Expand Down Expand Up @@ -782,21 +782,50 @@ export class ReviewManager extends Disposable {
let hasError: boolean = false;
let diff: DiffHunk[] = [];
const convertedFiles: vscode.Uri[] = [];

const convertOneSmallHunk = async (changeFile: Change, hunk: DiffHunk) => {
try {
await this._reviewCommentController?.createSuggestionsFromChanges(changeFile.uri, this.convertDiffHunkToSuggestion(hunk));
convertedFiles.push(changeFile.uri);
} catch (e) {
hasError = true;
}
};

const getDiffFromChange = async (changeFile: Change) => {
if (!resourceStrings.includes(changeFile.uri.toString()) || (changeFile.status !== Status.MODIFIED)) {
return;
}
return parsePatch(await this._folderRepoManager.repository.diffWithHEAD(changeFile.uri.fsPath)).map(hunk => splitIntoSmallerHunks(hunk)).flat();
};

await vscode.window.withProgress({ location: vscode.ProgressLocation.Window, title: 'Converting changes to suggestions' }, async () => {
await Promise.all(this._folderRepoManager.repository.state.workingTreeChanges.map(async changeFile => {
if (!resourceStrings.includes(changeFile.uri.toString()) || (changeFile.status !== Status.MODIFIED)) {
return;
// We need to create one suggestion first. This let's us ensure that only one review will be created.
let i = 0;
for (; (convertedFiles.length === 0) && (i < this._folderRepoManager.repository.state.workingTreeChanges.length); i++) {
const changeFile = this._folderRepoManager.repository.state.workingTreeChanges[i];
const diff = await getDiffFromChange(changeFile);
if (diff) {
for (const hunk of diff) {
await convertOneSmallHunk(changeFile, hunk);
}
}
diff = parsePatch(await this._folderRepoManager.repository.diffWithHEAD(changeFile.uri.fsPath)).map(hunk => splitIntoSmallerHunks(hunk)).flat();
await Promise.allSettled(diff.map(async hunk => {
try {
await this._reviewCommentController?.createSuggestionsFromChanges(changeFile.uri, this.convertDiffHunkToSuggestion(hunk));
convertedFiles.push(changeFile.uri);
} catch (e) {
hasError = true;
}

// If we have already created a suggestion, we can create the rest in parallel
const promises: Promise<void>[] = [];
for (; i < this._folderRepoManager.repository.state.workingTreeChanges.length; i++) {
const changeFile = this._folderRepoManager.repository.state.workingTreeChanges[i];
promises.push(getDiffFromChange(changeFile).then(async (diff) => {
if (diff) {
await Promise.allSettled(diff.map(async hunk => {
return convertOneSmallHunk(changeFile, hunk);
}));
}
}));
}));
}

await Promise.all(promises);
});
if (!hasError) {
const checkoutAllFilesResponse = vscode.l10n.t('Reset all changes');
Expand Down

0 comments on commit 268854f

Please sign in to comment.