Skip to content

Commit 268854f

Browse files
authored
Suggestions end up in unsubmittable pending state (#6504)
Fixes #6494
1 parent 5a1b1eb commit 268854f

1 file changed

Lines changed: 41 additions & 12 deletions

File tree

src/view/reviewManager.ts

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as nodePath from 'path';
77
import * as vscode from 'vscode';
8-
import type { Branch, Repository } from '../api/api';
8+
import type { Branch, Change, Repository } from '../api/api';
99
import { GitApiImpl, GitErrorCodes, Status } from '../api/api1';
1010
import { openDescription } from '../commands';
1111
import { DiffChangeType, DiffHunk, parsePatch, splitIntoSmallerHunks } from '../common/diffHunk';
@@ -782,21 +782,50 @@ export class ReviewManager extends Disposable {
782782
let hasError: boolean = false;
783783
let diff: DiffHunk[] = [];
784784
const convertedFiles: vscode.Uri[] = [];
785+
786+
const convertOneSmallHunk = async (changeFile: Change, hunk: DiffHunk) => {
787+
try {
788+
await this._reviewCommentController?.createSuggestionsFromChanges(changeFile.uri, this.convertDiffHunkToSuggestion(hunk));
789+
convertedFiles.push(changeFile.uri);
790+
} catch (e) {
791+
hasError = true;
792+
}
793+
};
794+
795+
const getDiffFromChange = async (changeFile: Change) => {
796+
if (!resourceStrings.includes(changeFile.uri.toString()) || (changeFile.status !== Status.MODIFIED)) {
797+
return;
798+
}
799+
return parsePatch(await this._folderRepoManager.repository.diffWithHEAD(changeFile.uri.fsPath)).map(hunk => splitIntoSmallerHunks(hunk)).flat();
800+
};
801+
785802
await vscode.window.withProgress({ location: vscode.ProgressLocation.Window, title: 'Converting changes to suggestions' }, async () => {
786-
await Promise.all(this._folderRepoManager.repository.state.workingTreeChanges.map(async changeFile => {
787-
if (!resourceStrings.includes(changeFile.uri.toString()) || (changeFile.status !== Status.MODIFIED)) {
788-
return;
803+
// We need to create one suggestion first. This let's us ensure that only one review will be created.
804+
let i = 0;
805+
for (; (convertedFiles.length === 0) && (i < this._folderRepoManager.repository.state.workingTreeChanges.length); i++) {
806+
const changeFile = this._folderRepoManager.repository.state.workingTreeChanges[i];
807+
const diff = await getDiffFromChange(changeFile);
808+
if (diff) {
809+
for (const hunk of diff) {
810+
await convertOneSmallHunk(changeFile, hunk);
811+
}
789812
}
790-
diff = parsePatch(await this._folderRepoManager.repository.diffWithHEAD(changeFile.uri.fsPath)).map(hunk => splitIntoSmallerHunks(hunk)).flat();
791-
await Promise.allSettled(diff.map(async hunk => {
792-
try {
793-
await this._reviewCommentController?.createSuggestionsFromChanges(changeFile.uri, this.convertDiffHunkToSuggestion(hunk));
794-
convertedFiles.push(changeFile.uri);
795-
} catch (e) {
796-
hasError = true;
813+
}
814+
815+
// If we have already created a suggestion, we can create the rest in parallel
816+
const promises: Promise<void>[] = [];
817+
for (; i < this._folderRepoManager.repository.state.workingTreeChanges.length; i++) {
818+
const changeFile = this._folderRepoManager.repository.state.workingTreeChanges[i];
819+
promises.push(getDiffFromChange(changeFile).then(async (diff) => {
820+
if (diff) {
821+
await Promise.allSettled(diff.map(async hunk => {
822+
return convertOneSmallHunk(changeFile, hunk);
823+
}));
797824
}
798825
}));
799-
}));
826+
}
827+
828+
await Promise.all(promises);
800829
});
801830
if (!hasError) {
802831
const checkoutAllFilesResponse = vscode.l10n.t('Reset all changes');

0 commit comments

Comments
 (0)