Repository navigation
fix(git): preserve context lines before first change in compact_diff - #1855
paolomainardi wants to merge 1 commit into
Conversation
Assisted-by: opencode/github-copilot/claude-opus-4.6
5cccbd0 to
75fc930
Compare
KuSh
left a comment
There was a problem hiding this comment.
Requesting changes, and apologies this sat so long without a response.
The bug you found is real: context lines before the first +/- in a hunk were silently dropped, and if hunk_shown > 0 is the cause. That much is confirmed. The fix needs one more piece, though, because removing the guard without giving context its own budget trades one silent loss for a worse one — details inline. I built both HEAD and your patch and compared real output through rtk pipe -f git-diff to check this rather than reasoning about it; all 2659 unit tests pass with your patch applied.
Suggested direction: keep the fix, but bound leading context separately — cap it at ~3 lines per hunk, or reserve budget for +/- lines so a change can never be crowded out by its own context.
Two notes on the surrounding state, so you know what you're rebasing into:
- The branch is currently conflicting with
develop. - #3269 is an open PR touching these same lines (it removes the two-space indent so
grep '^-'anchors again). It leaves thehunk_shown > 0guard alone, so the two changes are complementary — but whichever lands second will need a rebase.
A third thing, pre-existing but newly routine once leading context is emitted: ... (N lines truncated) undercounts, because context lines dropped past max_hunk_lines never reach hunk_skipped (there's no else arm on the context branch). In my repro it reported "2 lines truncated" when 22 were dropped. A one-line else { hunk_skipped += 1; } fixes it and would be welcome in the same PR.
| hunk_shown += 1; | ||
| } | ||
| // Context line — always emit (before and after changes) | ||
| result.push(format!(" {}", line)); |
There was a problem hiding this comment.
Emitting every context line unconditionally means leading context now consumes the per-hunk max_hunk_lines budget (100). A hunk with 100 or more leading context lines therefore emits only context and truncates away every actual +/- line.
Repro: 120 context lines followed by one -/+ pair. HEAD shows the change. With this patch the output is let v98, let v99, let v100, ... (2 lines truncated) — the change itself is gone.
That shape is not exotic: git diff -W, --function-context and -U<big> all produce it, and it reaches users through gh pr diff and glab mr diff as well as rtk git diff.
The global max_lines cap is affected the same way — it now fills with context, truncating real changes earlier. On a real 13.8 KB diff from this repo at max_lines=200, changed lines shown drop from 183 to 168 and the file summary goes from +166 -16 to +151 -16.
never_worse() doesn't rescue either case, since the filtered output here is smaller than raw, not larger — so the guard is happy while content is being dropped.
|
Closing in favour of #3022, which makes the same leading context fix and also removes the per hunk and diff wide truncation caps at every call site, with integration coverage. The leading context behaviour has meanwhile also landed on develop through a separate commit. Review and comments are welcome on #3022, or reply here if you think the scope differs. |
Summary
if hunk_shown > 0guard incompact_diff()that silently dropped context lines before the first+/-in each hunktest_compact_diff_preserves_context_before_first_changeBefore / After
All existing tests pass (1732 total).
Fixes #1852