-
Notifications
You must be signed in to change notification settings - Fork 11.4k
Description
Summary
generateUnifiedDiff() in packages/opencode/src/patch/index.ts (line ~490) is a naive index-based comparison (old[i] vs new[i]), not a real diff algorithm. Any insertion or deletion causes all subsequent lines to misalign, producing incorrect and bloated diffs.
This is especially severe for JSON files, where many lines are structurally identical (}, },, repeated keys), but affects all file types.
Root Cause
The current implementation:
function generateUnifiedDiff(oldContent: string, newContent: string): string {
const oldLines = oldContent.split("\n")
const newLines = newContent.split("\n")
let diff = "@@ -1 +1 @@\n"
const maxLen = Math.max(oldLines.length, newLines.length)
let hasChanges = false
for (let i = 0; i < maxLen; i++) {
const oldLine = oldLines[i] || ""
const newLine = newLines[i] || ""
if (oldLine !== newLine) {
if (oldLine) diff += `-${oldLine}\n`
if (newLine) diff += `+${newLine}\n`
hasChanges = true
} else if (oldLine) {
diff += ` ${oldLine}\n`
}
}
return hasChanges ? diff : ""
}Problems:
- Not a diff algorithm — compares lines by index position, not by content similarity (no LCS/Myers/Patience)
- Single hunk — always emits
@@ -1 +1 @@, never splits into multiple hunks with context windows - Misaligns on any insert/delete — inserting 1 line at the top marks every subsequent line as changed
- Particularly bad for JSON — many identical lines (
},},) cannot be correctly matched
The source comment itself acknowledges: "Simple diff generation - in a real implementation you'd use a proper diff algorithm".
Suggested Fix
Replace with createTwoFilesPatch() from the diff npm package, which is already a dependency and used correctly in tool/edit.ts and tool/write.ts:
import { createTwoFilesPatch } from "diff"
// In deriveNewContentsFromChunks():
const unifiedDiff = createTwoFilesPatch(filePath, filePath, originalContent, newContent)This is a minimal change — the diff package is already imported elsewhere in the codebase, and createTwoFilesPatch produces proper unified diffs with correct hunk splitting, context windows, and Myers-based line matching.
Reproduction
Any file edit that inserts or removes lines (rather than purely modifying in-place) will produce an incorrect diff. Most visible with JSON files containing repeated structural patterns.
Environment
- opencode v1.2.15
- Affected function:
deriveNewContentsFromChunks()→generateUnifiedDiff()inpackages/opencode/src/patch/index.ts