Skip to content

fix: correct diff output when duplicate functions exist in new file#94

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/fix-difference-algorithm-bug
Draft

fix: correct diff output when duplicate functions exist in new file#94
Copilot wants to merge 2 commits intomainfrom
copilot/fix-difference-algorithm-bug

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 27, 2026

When new code introduces both a modified version of a function and an identical copy of the original, Myers diff (minimum edit distance) silently matches old→identical copy at zero cost — making the modified version appear entirely green and the original appear as unchanged context. The old function should be shown as modified.

Root cause

Myers prefers the zero-cost match to the identical copy over the more expensive match to the modified version. This is algorithmically correct but semantically wrong from a code-review perspective.

Fix — two post-processing passes in compute-lines.ts after diffLines()

  • cleanupLongDistanceSame — handles the simple [ADDED(A), SAME(S)] pattern.
    Detects when S's first significant line (>8 trimmed chars) also appears inside A, meaning Myers matched old S to a later identical copy while a nearby modified version lives in A. Splits A at that line and rearranges:

    [ADDED(A), SAME(S)]
    → [ADDED(A_before), REMOVED(S), ADDED(A_from + S)]
    

    REMOVED(S) is now paired with ADDED(A_from) — different content — so changes are highlighted.

  • cleanupSplitMatches — handles the interleaved [ADDED, SAME, ADDED, SAME, …] pattern that Myers produces when old and new share one or more lines (e.g. a common setLoading(true) call).
    Detects consecutive SAME blocks whose new-file position gap is >3× their old-file gap (matched across different occurrences). Consolidates the affected run:

    [ADDED(A1), SAME(S1), ADDED(A2), SAME(S2)]
    → [ADDED(A1), REMOVED(S1+S2), ADDED(new_content_from_S1)]
    

Both passes are no-ops when the diff already contains REMOVED blocks (non-pure-addition scenario).

Tests added

Three cases in a new describe block:

  • Interleaved Myers pattern (body B shares a line with body A)
  • Simple Myers pattern (no shared lines between bodies)
  • Regression guard: prepending content must not falsely convert unchanged context lines to REMOVED

…or duplicate functions

When a function is copied verbatim in the new file (e.g. old getNewPlan +
new modified getNewPlan + old getNewPlan copy), the Myers algorithm matches
the old content to the identical later copy (0 edit distance), leaving the
modified earlier version as all-added.

Two complementary post-processing passes are applied after diffLines():

1. cleanupLongDistanceSame — handles the simple [ADDED(A), SAME(S)] pattern
   by finding S's first significant line inside A, splitting A at that point,
   and rearranging to [ADDED(before), REMOVED(S), ADDED(from+S)].

2. cleanupSplitMatches — handles the interleaved [ADDED,SAME,ADDED,SAME…]
   pattern by detecting consecutive SAME blocks whose new-file positions jump
   far more than their old-file positions (ratio > 3×), then consolidating to
   [ADDED(before), REMOVED(all-SAMEs-old), ADDED(new-content-from-first-SAME)].

Three new tests cover: the interleaved Myers variant, the simple variant, and
a regression guard that prepending content to a file does not falsely trigger
the fix.

Agent-Logs-Url: https://github.com/Aeolun/react-diff-viewer-continued/sessions/400ed340-4aa8-4e09-9c98-d583dcbfb7d1

Co-authored-by: Aeolun <1116482+Aeolun@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix bug with difference algorithm for same named functions fix: correct diff output when duplicate functions exist in new file Apr 27, 2026
Copilot AI requested a review from Aeolun April 27, 2026 01:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] When there is a function with the same name, there is a problem with the difference algorithm

2 participants