Skip to content

Commit 1820691

Browse files
committed
fix(diff): correctly classify file type for addition-only modifications
The diff viewer was not showing green background highlighting for added lines in modified files that only had additions (no deletions), like `src/constants.js` in svelte 5.16.2→5.50.0. Root cause: 1. `parseUnifiedDiff` used a heuristic that reclassified files based on diff content: if a file had only insertions, it was marked as 'add' (new file). This was wrong for modifications with only additions. 2. `computeDiff` in ViewerPanel used `parsed.type` ('add') instead of the correctly computed `type` ('modify') based on file existence. 3. DiffLine intentionally skips green background when fileStatus='add' (all lines in a new file are additions, so highlighting is redundant). This caused addition-only modifications to lose visual highlighting. Fix: - `parseUnifiedDiff`: Replace the content-based heuristic with proper /dev/null path detection from --- / +++ headers, which is the standard way unified diffs indicate new/deleted files. - `ViewerPanel.vue`: Use the file-existence-based type instead of the parsed diff type.
1 parent 930667e commit 1820691

File tree

2 files changed

+20
-17
lines changed

2 files changed

+20
-17
lines changed

app/components/diff/ViewerPanel.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ function computeDiff() {
119119
from: props.fromVersion,
120120
to: props.toVersion,
121121
path: props.file.path,
122-
type: parsed.type,
122+
// Use the type computed from file existence (modify/add/delete) rather than
123+
// parsed.type which incorrectly classifies addition-only modifications as 'add'.
124+
// This matters because DiffLine skips green background highlighting when
125+
// fileStatus is 'add' (since for truly new files all lines are additions).
126+
type,
123127
hunks: hunksWithSkips,
124128
stats,
125129
meta: {},

shared/utils/diff.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -183,19 +183,24 @@ export function parseUnifiedDiff(
183183
let oldLine = 0
184184
let newLine = 0
185185

186+
// Track old path from --- line to detect /dev/null (new/deleted files)
187+
let lastOldPath = ''
188+
186189
for (const line of lines) {
187190
if (line.startsWith('---')) {
188191
if (currentHunk && currentFile) {
189192
const hunk = processHunk(currentHunk, opts)
190193
currentFile.hunks.push(hunk)
191194
}
192195
currentHunk = null
196+
const oldMatch = line.match(/^--- (?:a\/)?(.*)/)
197+
lastOldPath = oldMatch?.[1]?.trimEnd() ?? ''
193198
continue
194199
}
195200

196201
if (line.startsWith('+++')) {
197202
const match = line.match(/^\+\+\+ (?:b\/)?(.*)/)
198-
const path = match?.[1] ?? ''
203+
const path = match?.[1]?.trimEnd() ?? ''
199204

200205
if (currentFile && currentHunk) {
201206
const hunk = processHunk(currentHunk, opts)
@@ -205,13 +210,20 @@ export function parseUnifiedDiff(
205210
files.push(currentFile)
206211
}
207212

213+
// Determine file type from --- / +++ paths:
214+
// /dev/null in the old path means a new file; in the new path means deleted
215+
let fileType: FileDiff['type'] = 'modify'
216+
if (lastOldPath === '/dev/null') fileType = 'add'
217+
else if (path === '/dev/null') fileType = 'delete'
218+
208219
currentFile = {
209-
oldPath: path,
220+
oldPath: lastOldPath === '/dev/null' ? path : lastOldPath || path,
210221
newPath: path,
211-
type: 'modify',
222+
type: fileType,
212223
hunks: [],
213224
}
214225
currentHunk = null
226+
lastOldPath = ''
215227
continue
216228
}
217229

@@ -279,19 +291,6 @@ export function parseUnifiedDiff(
279291
files.push(currentFile)
280292
}
281293

282-
for (const file of files) {
283-
const hasAdds = file.hunks.some(
284-
h => h.type === 'hunk' && h.lines.some(l => l.type === 'insert'),
285-
)
286-
const hasDels = file.hunks.some(
287-
h => h.type === 'hunk' && h.lines.some(l => l.type === 'delete'),
288-
)
289-
290-
if (hasAdds && !hasDels) file.type = 'add'
291-
else if (hasDels && !hasAdds) file.type = 'delete'
292-
else file.type = 'modify'
293-
}
294-
295294
return files
296295
}
297296

0 commit comments

Comments
 (0)