google-gemini / google-gemini/gemini-cli

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

Open Beginner friendly
#29,130 2 comments 0 reactions 0 assignees View on GitHub
area/core effort/medium status/bot-triaged
Dominant language
TypeScript
Stars
107k
Forks
14.6k
Avg merge
2d 3h
Merged PRs (30d)
45

Description

### 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:
```typescript
const snippet = getDiffContextSnippet(
editData.currentContent ?? '', // contains \n
finalContent, // contains \r\n
5,
);

### What did you expect to happen?

```markdown
`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

Client Information

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

### 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/);
// ...

Contributor guide

Open the contributing guide

Research direction

Start in packages/core/src/tools/diff-utils.ts at getDiffContextSnippet, then inspect its call in packages/core/src/tools/edit.ts around line 1026. Review how Diff.diffLines and line splitting handle CRLF, and verify that a CRLF file produces only the actual changes within the five-line context instead of a full-file diff.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.