Skip to content

Apply a mergeable edit on its own when the previous command can't be undone to merge [patch] - #182

Open
matt-edmondson wants to merge 1 commit into
mainfrom
fix/merge-undo-failure-177
Open

matt-edmondson wants to merge 1 commit into
mainfrom
fix/merge-undo-failure-177

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #177

What was wrong

#168 made the merge path undo the previous command before merging. That lastCommand.Undo() call sat outside any try block. When it threw, Execute(command) threw too, so the new command was never executed or recorded. The merge chain wasn't broken, so every later mergeable edit took the same path and was lost the same way.

Change

  • ExecuteMerged is now TryExecuteMerged, and it returns bool.
  • If the pre-merge Undo() throws, it returns false. Nothing has been mutated at that point, and the stack is still accurate.
  • Execute then continues on the ordinary non-merge path. It executes the new command on its own, pushes it as a new entry and raises CommandExecuted for it.
  • After a failed merge (the merge itself or the merged Execute), the method still restores and rethrows exactly as before.

I didn't set _mergeChainBroken, which the triage comment suggested as an option. After the fallback, the failing command is no longer the current one, so the next edit can't retry that merge. It merges into the new command instead, and that command's Undo works. Breaking the chain would only stop ordinary coalescing of the next keystroke.

#176 reworks the body of the same method, after the Undo() call. This change only wraps the Undo() and adds the bool return, so any conflict should be small.

Tests

New MergeUndoFailureTests:

  • APreviousCommandWhoseUndoThrows_StillLetsAMergeableEditApply (the acceptance case): Execute(B) applies B, CommandExecuted is raised for A then B, the history holds A then B, and nothing is reported as discarded.
  • AfterTheFallback_TheNextEditMergesIntoTheNewCommand: a third keystroke merges into B, not A, and Undo then returns to A's state.

With the service change reverted, both tests fail. With it, the full suite passes: 208/208 on Linux / .NET 10. That includes the #168 in-place MergeWith tests.


Generated by Claude Code

…undone to merge [patch]

With auto-merge on, Execute undid the previous command before merging,
outside any try block. When that Undo threw, Execute threw too, and the
new command was never executed or recorded. Every later mergeable edit
failed the same way.

A failing pre-merge Undo now changes nothing and Execute falls back to
the non-merge path: the new command is executed and pushed as its own
entry. The failing command is then no longer current, so the next edit
merges into the new one rather than retrying.

Fixes #177

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW3sakBdbLSZUGjwGAi
@sonarqubecloud

sonarqubecloud Bot commented Nov 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants