google-gemini / google-gemini/gemini-cli
fix(core): getDiffContextSnippet produces full-file diff on CRLF line endings due to unnormalized line breaks
- 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
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