git diff of the commitInstead of pasting whole files, diffctx walks the dependency graph from the changed lines outward — and stops as soon as additional context stops paying for itself. Every trade-off optimized for comprehension-per-token.
git diff of the commit
Measured on
home-assistant/core@1d885bd0
— “Restrict device registry entries to a single config entry and subentry”, 66 files
changed — with diffctx . --diff 1d885bd0^..1d885bd0 at the
default auto budget, counted with the o200k_base tokenizer. Clone the
repo and run the command to reproduce it. The selection is smaller than
the patch and still carries the callers, types and config the patch
alone does not show. Against pasting the 66 changed files whole — 768,268
tokens — it is 17.6× (13.9× without the one 158k-token generated test
snapshot among them). The ratio is not a constant:
it tracks how much of the changed files is unrelated to the change, so a
wide refactor across large files compresses far more than a three-file
fix, where diffctx often adds tokens because it pulls in the
callers and types the diff alone does not show.
This is a live model of the pipeline — a toy repository of 18 fragments, scored and selected in your browser with the same rules the engine uses: relevance decays with graph distance, selection is greedy, and the budget is a hard wall. Step through the stages, then drag the dials. The token counts here belong to this 18-fragment toy; the 169,809 → 43,769 above was measured on the real home-assistant commit it links.
A diff rarely lives inside one file. Each edge family is a separate builder; their weighted union is the graph relevance flows across.
Pick one with --scoring. Three
signals below, plus two fusion modes — rrf and
pit — that combine ego and bm25. All of them feed the
same greedy selector.
ego-network: the changed nodes plus their neighbours out to a bounded depth. PPR: Personalized PageRank, a random walk that restarts at the change with probability 1 − α. bm25: lexical similarity of a fragment's identifiers to the change. rrf: reciprocal rank fusion, ranks summed by position. pit: per-item top, each fragment keeps its best rank across modes. τ: the stop threshold — selection halts once the next fragment's marginal value falls below it. o200k_base: the GPT-4o tokenizer every count on this page is measured in.
Bounded ego-network expansion around the changed nodes. Fast, predictable radius, natural decay with distance.
Personalized PageRank with damping α. Global view, smoother decay, catches long-range structure — at a cost in speed.
Lexical retrieval of fragments against the diff hunks. The honest baseline — and the fallback when the graph is sparse.
$ uvx diffctx . --diff HEAD~1zero-install, run once via uv
$ pipx install diffctxrecommended — isolated CLI
$ pipx install 'diffctx[mcp]'+ MCP server for Claude Code / Cursor / Zed
$ diffctx . --diff main..feature -cbranch context → clipboard → any LLM
$ diffctx . --diff main..feature --budget
8000the budget dial above, as a flag — hard token ceiling
$ diffctx . --diff main..feature --tau
0.2the τ dial above, raised — drop weak context, leaner output
$ diffctx graph . --summarycycles, hotspots, coupling
Free, local, offline. Works with any LLM. Python API and standalone binaries included. Theory: Budgeted Typed-Graph Retrieval for Diff-Aware Code Context Selection (Zenodo, 2026).