Skip to content

fix: scope diff file-header detection to between-hunk positions#1878

Open
carlos-alm wants to merge 1 commit into
fix/issue-1759-rust-tracer-fixture-mainrsfrom
fix/issue-1761-parsediff-hunk-scoped-headers
Open

fix: scope diff file-header detection to between-hunk positions#1878
carlos-alm wants to merge 1 commit into
fix/issue-1759-rust-tracer-fixture-mainrsfrom
fix/issue-1761-parsediff-hunk-scoped-headers

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

  • parseDiffOutput tested every diff line against file-header regexes (--- , +++ b/) unconditionally. A removed line whose original content starts with -- becomes --- ... once diff-prefixed — indistinguishable from a real file header by content alone, causing it to be silently dropped and desyncing the old-line cursor for the rest of the hunk. Same latent issue for added lines starting with ++ b/.
  • Added oldHunkEnd/newHunkEnd tracking (computed from the most recent @@ -a,b +c,d @@ header) and an insideHunk() check; file-header detection now only runs when not currently inside a hunk body. Hunk-header detection itself is untouched (unambiguous by construction).

Closes #1761

Test plan

  • npm test — full suite green (3521 passed, 0 failed)
  • npm run lint — clean
  • Two new regression tests (removed-line and added-line cases), diff format verified against real git diff --unified=0 output on temp fixtures — confirmed both fail with the exact predicted corruption against pre-fix code, pass post-fix
  • Along the way, fixed an existing "handles multiple files" test fixture that had hunk headers declaring zero actual body lines (unrealistic, happened to work under the old unconditional matching but would break under correct position-aware parsing) — added matching body content, preserved original headers/assertions

Stacked on #1877 (base branch fix/issue-1759-rust-tracer-fixture-mainrs) — only the check.ts/test diff is this issue's change.

parseDiffOutput tested every diff line against the file-header regexes
unconditionally, including lines inside an active hunk body. A removed
line whose original content starts with "-- " (e.g. a Markdown
horizontal rule) becomes a "--- " line once diff-prefixed and was
misdetected as a source-file header, silently dropped, and desynced the
old-line cursor for the rest of the hunk. Symmetrically, an added line
starting with "++ b/" becomes a "+++ b/..." line and was misdetected as
a new-file header, flushing the in-progress run under a phantom file
key and misattributing every later line in the hunk to it.

DiffLineTracker now derives an insideHunk() state from the old/new
line-count bounds declared by the most recent hunk header, and
parseDiffOutput only attempts file-header matching while that is false:
before a file's first hunk, or once the previous hunk's declared counts
are fully consumed. Real diffs never have hunk-header counts that lie
about their body length, so this makes header detection position-aware
without weakening it for any real diff shape.

No user-facing behavior, commands, or architecture changed. docs check acknowledged.

Fixes #1761

Impact: 4 functions changed, 5 affected
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Codegraph Impact Analysis

4 functions changed5 callers affected across 4 files

  • DiffLineTracker in src/features/check.ts:74 (4 transitive callers)
  • DiffLineTracker.startHunk in src/features/check.ts:95 (4 transitive callers)
  • DiffLineTracker.insideHunk in src/features/check.ts:116 (4 transitive callers)
  • parseDiffOutput in src/features/check.ts:214 (4 transitive callers)

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a parsing bug in parseDiffOutput where hunk body lines whose own content starts with -- or ++ b/ were misidentified as file-section headers (--- a/... / +++ b/...) because the header regex was applied unconditionally to every line. The fix adds oldHunkEnd/newHunkEnd tracking computed from each @@ -a,b +c,d @@ header and gates all file-header detection behind an insideHunk() position check.

  • src/features/check.ts: Adds oldHunkEnd/newHunkEnd fields and insideHunk() to DiffLineTracker; extends startHunk to accept and record the declared old/new line counts; wraps the file-header detection block in if (!tracker.insideHunk()).
  • tests/integration/check.test.ts: Adds two targeted regression tests covering the removed-line and added-line false-positive cases; updates the "handles multiple files" fixture with realistic hunk bodies.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to the diff parser, well-tested, and leaves unrelated code paths untouched.

The fix correctly uses end-exclusive hunk bounds derived from the declared @@ counts. All edge cases (zero-count sides, absent count defaulting to 1, No newline markers, sequential hunks, new/deleted-file hunks) behave correctly. The two regression tests precisely mirror the bug scenarios, and the handles-multiple-files fixture fix is necessary and correct.

No files require special attention — both changed files are clean.

Important Files Changed

Filename Overview
src/features/check.ts Adds insideHunk() position-aware gating for file-header detection; oldCount/newCount parsing correctly handles the optional count field per unified-diff spec.
tests/integration/check.test.ts Two new regression tests for the false-positive cases are well-formed; handles multiple files fixture updated with a realistic hunk body.

Reviews (1): Last reviewed commit: "fix: scope diff file-header detection to..." | Re-trigger Greptile

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant