git-diff-hunks(1) ================= NAME ---- git-diff-hunks - Inspect and manage the diff-hunks store SYNOPSIS -------- [synopsis] git diff-hunks verify git diff-hunks clear DESCRIPTION ----------- The diff-hunks store is a cache of diff hunk coordinates, the line ranges that changed between two blobs, so that commands which need them, such as linkgit:git-blame[1] and `git log` and `git diff` with the `--stat`, `--numstat`, and `--shortstat` formats, can skip running the diff algorithm, and blame can skip loading the blob content. (The summary formats still test each pair for binariness, which can load the blobs.) The store is a single file, `$GIT_DIR/objects/info/diff-hunks`. Reading is enabled by default; writing is off by default. A `git diff`, `git log`, `git show`, or `git diff-tree` that produces one of the stat formats fills the store as a side effect, but only when writing is enabled for that run (see "WARMING THE STORE" below), so ordinary reads never modify the repository. When the store does not have the pair, holds a different object hash, the file is unreadable, or an object replacement redirects one of the blobs, the consumer falls back to computing the diff. A store only speeds up these commands; it never changes their output. `git diff-hunks` itself only inspects and manages the file. See linkgit:gitformat-diff-hunks[5] for the file format. WARMING THE STORE ----------------- The store is filled by running ordinary commands with writing enabled. Turn writing on for a single invocation with the `GIT_DIFF_HUNKS_WRITE` environment variable, or persistently with the `diffHunks.write` configuration; the environment variable takes precedence. A repository owner warms the store by running the diff-producing commands they care about with writing on, for example: GIT_DIFF_HUNKS_WRITE=1 git log --all --stat >/dev/null A `--stat` walk records one entry per blob pair; linkgit:git-blame[1] replays the coordinates and the summary formats sum the counts, so a single warming walk serves both. A warming run seeds from the existing store and rewrites the file with the newly computed pairs merged in, so a later run adds to what earlier runs recorded rather than discarding it. A walk records only the pairs it diffs. `git log --all --stat` diffs each commit against its first parent, so a blame that follows a merge's second parent computes those pairs itself: blame coverage is partial on history with merges. Warming with a walk that also diffs the other parents, for example `git log --all -m --stat`, raises blame coverage at the cost of a larger store and a longer warming run. COMMANDS -------- `verify`:: Check the integrity of the store: the trailing hash checksum, the chunk table of contents, the sort order of the index, and the bounds of every entry. Exits with non-zero status if the store is corrupt. An absent store is valid. `clear`:: Remove the store file. CORRECTNESS ----------- A stored result is interchangeable with a freshly computed one because an entry is keyed by the inputs that determine the diff: * the object IDs of the old and new blob, so a result is used only for the exact contents it was computed from; and * the diff algorithm and ignore flags (`xdl_opts`) the hunks were computed under. A lookup whose `xdl_opts` differ from a stored entry misses. This is why, for example, `blame -w` and `--diff-algorithm=` (including a per-path `diff..algorithm`) do not reuse entries recorded under the default settings: they change `xdl_opts`. The context length is not part of the key because only trim-stable pairs are recorded: pairs whose zero-context trimmed diff and untrimmed diff are identical, so one entry answers blame (zero context) and the summary formats (any context) alike. The rare pair where the zero-context trimming optimization picks a different but equally valid set of hunks is never recorded and is always computed. Some options shape the hunks in ways the key does not express, so a diff that uses them is excluded from the store in both directions: break detection (`-B`), `--ignore-matching-lines` (`-I`), and `--anchored`. `--ignore-blank-lines` is different: it is an ignore flag and therefore part of the key, but the summary formats exclude it anyway, because it coalesces hunks differently between the code path that emits text and the one that replays coordinates, so a served answer would not match a store-less run. linkgit:git-blame[1] additionally does not consult the store for reverse blame, ignored revisions, or paths with a textconv driver. The store carries a trailing hash checksum, but readers do not re-checksum it on every load. As with the commit-graph and multi-pack-index, the writer fsyncs the file (honoring `core.fsync`) and commits it atomically, so a committed store is intact; every offset and count is still bounds-checked as it is read. The checksum is verified by `git diff-hunks verify`, not on the read path, so structural corruption that fails a bounds check is read as an absent entry, while a record that stays within bounds but whose bytes were altered is served until `verify` detects the mismatch. CONFIGURATION ------------- `core.diffHunks`:: Whether commands read the store. Defaults to true. See linkgit:git-config[1]. `diffHunks.write`:: Whether diff-producing commands write to the store. Defaults to false. The `GIT_DIFF_HUNKS_WRITE` environment variable overrides it for a single invocation. See linkgit:git-config[1]. Writing the store honors the `core.fsync` configuration through the `diff-hunks` component; see linkgit:git-config[1]. SEE ALSO -------- linkgit:git-blame[1], linkgit:git-log[1], linkgit:gitformat-diff-hunks[5] GIT --- Part of the linkgit:git[1] suite