Skip to content

fix(git): stop silently truncating large diffs#3022

Open
georgebashi wants to merge 1 commit into
rtk-ai:developfrom
georgebashi:fix/compact-diff-never-truncate
Open

fix(git): stop silently truncating large diffs#3022
georgebashi wants to merge 1 commit into
rtk-ai:developfrom
georgebashi:fix/compact-diff-never-truncate

Conversation

@georgebashi

@georgebashi georgebashi commented Jul 16, 2026

Copy link
Copy Markdown

Summary

Test plan

  • cargo fmt --all --check && cargo clippy --all-targets && cargo test — 2,495 passed, 8 ignored, no warnings
  • Replaced truncation assertions with content-preservation tests; added leading-context coverage
  • Added git_diff_large_change_preserves_all_content: a 1,200-line diff retains and can grep its final-line marker
  • Release binary: raw diff 2,407 lines; compact diff 2,411 lines (previously ~110); final-line grep succeeds; zero truncation markers
  • Recovery-hint/cap check: N/A because diff truncation was removed

Closes #1852.

AI-assisted contribution.

`compact_diff` (used by `git diff`, `git show`, `git stash show`,
`gh pr diff`, `glab mr diff`, and the `git-diff` pipe filter) silently
dropped diff content at two levels: a 100-line-per-hunk cap and a
500-line global cap. Content past the cap was replaced with a
"... (N lines truncated)" / "... (more changes truncated)" marker.

This caused the exact data-loss class rtk-ai#827 was meant to fix. rtk-ai#827
("never truncate diff content", closes rtk-ai#827) only patched the sibling
`condense_unified_diff` in diff_cmd.rs (the `rtk diff` stdin path) — its
message claimed it also covered the "git diff path", but that path uses
`compact_diff` in git.rs, which was never touched. The caps were also
effectively unconfigurable: every `git::run` caller passes `max_lines:
None`, so `unwrap_or(500)` always applied.

The failure is worst under a pipe: the PreToolUse hook rewrites
`gh pr diff URL | grep X` to `rtk gh pr diff URL | grep X` (rtk-ai#1560), so
grep scans the truncated output and silently finds nothing — an agent
concludes the content isn't there. Reported for `gh pr diff | grep`
returning empty while `rtk proxy gh pr diff | grep` found the matches.

Make `compact_diff` never drop diff content, matching the decision
already made for `condense_unified_diff`. Only lossless compression
remains: strip diff metadata (index/mode/`---`/`+++`) and append a
per-file `+N -M` summary. As a side effect this also fixes rtk-ai#1852
(leading context before the first change in a hunk was dropped) and
removes the misleading "[full diff: rtk git diff --no-compact]" hint
that named the wrong command on the `gh pr diff` path.

The now-unused `max_lines` parameter is retained (prefixed `_`) on
`run_diff`/`run_show` to avoid churning the `git::run` signature and
its callers; the `--no-compact` / `--stat` passthrough escape hatches
are unchanged.

- Rewrite `compact_diff(diff)` to drop no `+`/`-`/context lines
- Update all 6 call sites (git.rs x3, gh_cmd, glab_cmd, pipe_cmd)
- Replace the two truncation-asserting unit tests with
  content-preservation tests; add a leading-context test (rtk-ai#1852)
- Add an end-to-end integration test: a 1200-line `rtk git diff`
  preserves a marker near the end and stays greppable

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: George Bashi <georgeb@yelp.com>
@CLAassistant

CLAassistant commented Jul 16, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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.

fix(git): compact_diff drops context lines before first change in hunk

2 participants