Skip to content

Commit 2a09308

Browse files
committed
Improve patch application by reverting only fallback-applied patches for intelligent update, preserving clean changes
1 parent 5bdf2e6 commit 2a09308

2 files changed

Lines changed: 66 additions & 20 deletions

File tree

packages/vscode/src/commands/apply-chat-response-command/apply-chat-response-command.ts

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,11 @@ export function apply_chat_response_command(context: vscode.ExtensionContext) {
413413
let all_original_states: OriginalFileState[] = []
414414
const failed_patches: DiffPatch[] = []
415415
let any_patch_used_fallback = false
416+
const applied_patches: {
417+
patch: DiffPatch
418+
original_states: OriginalFileState[]
419+
used_fallback: boolean
420+
}[] = []
416421

417422
// Process patches
418423
const total_patches = clipboard_content.patches.length
@@ -433,6 +438,11 @@ export function apply_chat_response_command(context: vscode.ExtensionContext) {
433438
all_original_states = all_original_states.concat(
434439
result.original_states
435440
)
441+
applied_patches.push({
442+
patch,
443+
original_states: result.original_states,
444+
used_fallback: !!result.used_fallback
445+
})
436446
}
437447
if (result.used_fallback) {
438448
any_patch_used_fallback = true
@@ -572,8 +582,23 @@ export function apply_chat_response_command(context: vscode.ExtensionContext) {
572582
await revert_files(all_original_states)
573583
context.workspaceState.update(LAST_APPLIED_CHANGES_STATE_KEY, null)
574584
} else if (response == 'Looks off, use intelligent update') {
575-
// Revert the applied patches first
576-
await revert_files(all_original_states)
585+
const fallback_patches_info = applied_patches.filter(
586+
(p) => p.used_fallback
587+
)
588+
const good_patches_info = applied_patches.filter(
589+
(p) => !p.used_fallback
590+
)
591+
592+
const fallback_patches = fallback_patches_info.map((p) => p.patch)
593+
const fallback_states = fallback_patches_info.flatMap(
594+
(p) => p.original_states
595+
)
596+
const good_states = good_patches_info.flatMap(
597+
(p) => p.original_states
598+
)
599+
600+
// Revert only the patches that used fallback, without showing a message
601+
await revert_files(fallback_states, false)
577602

578603
// Then try with intelligent update
579604
const api_providers_manager = new ApiProvidersManager(context)
@@ -584,71 +609,89 @@ export function apply_chat_response_command(context: vscode.ExtensionContext) {
584609
)
585610

586611
if (!config_result) {
612+
// Config was cancelled. The fallback patches are reverted.
613+
// The state should now be just the good patches.
614+
context.workspaceState.update(
615+
LAST_APPLIED_CHANGES_STATE_KEY,
616+
good_states.length > 0 ? good_states : null
617+
)
587618
return
588619
}
589620

590621
const { provider, config: intelligent_update_config } =
591622
config_result
592623

624+
// Convert only fallback patches to clipboard format
625+
const fallback_patches_text = fallback_patches
626+
.map(
627+
(patch) =>
628+
`\`\`\`\n// ${patch.file_path}\n${patch.content}\n\`\`\``
629+
)
630+
.join('\n')
631+
593632
let endpoint_url = ''
594-
if (provider.type == 'built-in') {
633+
if (provider.type === 'built-in') {
595634
const provider_info =
596635
PROVIDERS[provider.name as keyof typeof PROVIDERS]
597636
endpoint_url = provider_info.base_url
598637
} else {
599638
endpoint_url = provider.base_url
600639
}
601640

602-
// Convert all patches to clipboard format for intelligent update
603-
const all_patches_text = clipboard_content.patches
604-
.map(
605-
(patch) =>
606-
`\`\`\`\n// ${patch.file_path}\n${patch.content}\n\`\`\``
607-
)
608-
.join('\n')
609-
610641
try {
611642
const intelligent_update_states = await handle_intelligent_update(
612643
{
613644
endpoint_url,
614645
api_key: provider.api_key,
615646
config: intelligent_update_config,
616-
chat_response: all_patches_text,
647+
chat_response: fallback_patches_text,
617648
context: context,
618649
is_single_root_folder_workspace
619650
}
620651
)
621652

622653
if (intelligent_update_states) {
654+
const combined_states = [
655+
...good_states,
656+
...intelligent_update_states
657+
]
623658
context.workspaceState.update(
624659
LAST_APPLIED_CHANGES_STATE_KEY,
625-
intelligent_update_states
660+
combined_states
626661
)
627662
const response = await vscode.window.showInformationMessage(
628663
`Successfully applied patches using intelligent update.`,
629664
'Revert'
630665
)
631666

632667
if (response == 'Revert') {
633-
await revert_files(intelligent_update_states)
668+
await revert_files(combined_states)
634669
context.workspaceState.update(
635670
LAST_APPLIED_CHANGES_STATE_KEY,
636671
null
637672
)
638673
}
639674
} else {
675+
// Intelligent update was canceled.
676+
context.workspaceState.update(
677+
LAST_APPLIED_CHANGES_STATE_KEY,
678+
good_states.length > 0 ? good_states : null
679+
)
640680
vscode.window.showInformationMessage(
641-
'Intelligent update was canceled. Original changes have been reverted.'
681+
'Intelligent update was canceled. Fallback changes reverted; clean changes kept.'
642682
)
643683
}
644684
} catch (error) {
645685
Logger.error({
646686
function_name: 'apply_chat_response_command',
647-
message: 'Error during intelligent update of all patches'
687+
message: 'Error during intelligent update of fallback patches'
648688
})
649-
689+
context.workspaceState.update(
690+
LAST_APPLIED_CHANGES_STATE_KEY,
691+
good_states.length > 0 ? good_states : null
692+
)
650693
vscode.window.showErrorMessage(
651-
'Error during intelligent update. Original patches have been reverted.'
694+
'Error during intelligent update. Fallback changes reverted; clean changes kept.'
652695
)
653696
}
654697
}

packages/vscode/src/commands/apply-chat-response-command/utils/file-operations.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ export async function create_file_if_needed(
134134
* Reverts applied changes to files based on their original states.
135135
*/
136136
export async function revert_files(
137-
original_states: OriginalFileState[]
137+
original_states: OriginalFileState[],
138+
show_message = true
138139
): Promise<boolean> {
139140
Logger.log({
140141
function_name: 'revert_files',
@@ -262,7 +263,9 @@ export async function revert_files(
262263
}
263264
}
264265

265-
vscode.window.showInformationMessage('Changes successfully reverted.')
266+
if (show_message) {
267+
vscode.window.showInformationMessage('Changes successfully reverted.')
268+
}
266269
Logger.log({
267270
function_name: 'revert_files',
268271
message: 'Changes successfully reverted.'

0 commit comments

Comments
 (0)