Skip to content

fix(core): getDiffContextSnippet produces full-file diff on CRLF line endings due to unnormalized line breaks #29130

Description

@Aditya2584

What happened?

When applying edits or writes to files, getDiffContextSnippet(originalContent, newContent, contextLines) in packages/core/src/tools/diff-utils.ts is called to generate a compact 5-line contextual snippet around the changed lines.

On Windows or for any file with CRLF (\r\n) line endings:

  1. EditToolInvocation.calculateEdit in packages/core/src/tools/edit.ts normalizes currentContent to LF (\n), so editData.currentContent always contains LF.
  2. In execute(), if the file originally used CRLF or on Windows, finalContent is converted back to CRLF (\r\n).
  3. Line 1026 calls:
    const snippet = getDiffContextSnippet(
      editData.currentContent ?? '', // contains \n
      finalContent,                  // contains \r\n
      5,
    );
    

What did you expect to happen?

`getDiffContextSnippet` should normalize line endings (converting `\r\n` to `\n`) before calling `Diff.diffLines`, so that unchanged lines with differing newline representations match correctly and only actual code changes are returned within the 5-line snippet.


### Client information

<details>
<summary>Client Information</summary>

- **Platform:** Windows (CRLF) / Any OS editing CRLF files
- **Version:** Latest main

</details>


### Login information

NAN

### Anything else we need to know?

**Suggested Fix:**
Normalize line endings in `packages/core/src/tools/diff-utils.ts`:

```typescript
export function getDiffContextSnippet(
  originalContent: string,
  newContent: string,
  contextLines = 5,
): string {
  if (!originalContent) {
    return newContent;
  }

  const normalizedOriginal = originalContent.replace(/\r\n/g, '\n');
  const normalizedNew = newContent.replace(/\r\n/g, '\n');

  const changes = Diff.diffLines(normalizedOriginal, normalizedNew);
  const newLines = newContent.split(/\r?\n/);
  // ...

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/coreIssues related to User Interface, OS Support, Core Functionalityeffort/medium2-3 days: UI state, async flow, cross-component refactorsstatus/bot-triaged

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions