Raw
1 git-diff-hunks(1)
2 =================
3
4 NAME
5 ----
6 git-diff-hunks - Inspect and manage the diff-hunks store
7
8 SYNOPSIS
9 --------
10 [synopsis]
11 git diff-hunks verify
12 git diff-hunks clear
13
14 DESCRIPTION
15 -----------
16
17 The diff-hunks store is a cache of diff hunk coordinates, the line
18 ranges that changed between two blobs, so that commands
19 which need them, such as linkgit:git-blame[1] and `git log` and `git diff`
20 with the `--stat`, `--numstat`, and `--shortstat` formats, can skip
21 running the diff algorithm, and blame can skip loading the blob
22 content. (The summary formats still test each pair for binariness,
23 which can load the blobs.)
24
25 The store is a single file, `$GIT_DIR/objects/info/diff-hunks`. Reading is
26 enabled by default; writing is off by default. A `git diff`, `git log`,
27 `git show`, or `git diff-tree` that produces one of the stat formats
28 fills the store as a side effect, but only when writing is enabled for
29 that run (see "WARMING THE STORE" below), so ordinary reads never
30 modify the repository. When the store does not have the pair, holds a
31 different object hash, the file is unreadable, or an object replacement
32 redirects one of the blobs, the consumer falls back to computing the
33 diff. A store only speeds up these commands; it never changes their
34 output.
35
36 `git diff-hunks` itself only inspects and manages the file. See
37 linkgit:gitformat-diff-hunks[5] for the file format.
38
39 WARMING THE STORE
40 -----------------
41
42 The store is filled by running ordinary commands with writing enabled.
43 Turn writing on for a single invocation with the `GIT_DIFF_HUNKS_WRITE`
44 environment variable, or persistently with the `diffHunks.write`
45 configuration; the environment variable takes precedence. A repository
46 owner warms the store by running the diff-producing commands they care
47 about with writing on, for example:
48
49 GIT_DIFF_HUNKS_WRITE=1 git log --all --stat >/dev/null
50
51 A `--stat` walk records one entry per blob pair;
52 linkgit:git-blame[1] replays the coordinates and the summary formats
53 sum the counts, so a single warming walk serves both.
54 A warming run seeds from the existing store and rewrites the file
55 with the newly computed pairs merged in, so a later run adds to what
56 earlier runs recorded rather than discarding it.
57
58 A walk records only the pairs it diffs. `git log --all --stat` diffs
59 each commit against its first parent, so a blame that follows a
60 merge's second parent computes those pairs itself: blame coverage is
61 partial on history with merges. Warming with a walk that also diffs
62 the other parents, for example `git log --all -m --stat`, raises
63 blame coverage at the cost of a larger store and a longer warming
64 run.
65
66 COMMANDS
67 --------
68
69 `verify`::
70 Check the integrity of the store: the trailing hash checksum, the
71 chunk table of contents, the sort order of the index, and the
72 bounds of every entry. Exits with non-zero status if the store is
73 corrupt. An absent store is valid.
74
75 `clear`::
76 Remove the store file.
77
78 CORRECTNESS
79 -----------
80
81 A stored result is interchangeable with a freshly computed one because an
82 entry is keyed by the inputs that determine the diff:
83
84 * the object IDs of the old and new blob, so a result is used only for
85 the exact contents it was computed from; and
86 * the diff algorithm and ignore flags (`xdl_opts`) the hunks were
87 computed under. A lookup whose `xdl_opts` differ from a stored entry
88 misses. This is why, for example, `blame -w` and
89 `--diff-algorithm=<algorithm>` (including a per-path
90 `diff.<driver>.algorithm`) do not reuse entries recorded under the
91 default settings: they change `xdl_opts`.
92
93 The context length is not part of the key because only trim-stable
94 pairs are recorded: pairs whose zero-context trimmed diff and untrimmed
95 diff are identical, so one entry answers blame (zero context) and the
96 summary formats (any context) alike. The rare pair where
97 the zero-context trimming optimization picks a different but
98 equally valid set of hunks is
99 never recorded and is always computed.
100
101 Some options shape the hunks in ways the key does not express, so a
102 diff that uses them is excluded from the store in both directions:
103 break detection (`-B`), `--ignore-matching-lines` (`-I`), and
104 `--anchored`. `--ignore-blank-lines` is different: it is an ignore
105 flag and therefore part of the key, but the summary formats exclude
106 it anyway, because it coalesces hunks differently between the code
107 path that emits text and the one that replays coordinates, so a
108 served answer would not match a store-less run.
109 linkgit:git-blame[1] additionally does not
110 consult the store for reverse blame, ignored revisions, or paths with a
111 textconv driver.
112
113 The store carries a trailing hash checksum, but readers do not
114 re-checksum it on every load. As with the commit-graph and
115 multi-pack-index, the writer fsyncs the file (honoring `core.fsync`) and
116 commits it atomically, so a committed store is intact; every offset and
117 count is still bounds-checked as it is read. The checksum is verified by
118 `git diff-hunks verify`, not on the read path, so structural corruption
119 that fails a bounds check is read as an absent entry, while a record
120 that stays within bounds but whose bytes were altered is served until
121 `verify` detects the mismatch.
122
123 CONFIGURATION
124 -------------
125
126 `core.diffHunks`::
127 Whether commands read the store. Defaults to true. See
128 linkgit:git-config[1].
129
130 `diffHunks.write`::
131 Whether diff-producing commands write to the store. Defaults to
132 false. The `GIT_DIFF_HUNKS_WRITE` environment variable overrides it
133 for a single invocation. See linkgit:git-config[1].
134
135 Writing the store honors the `core.fsync` configuration through the
136 `diff-hunks` component; see linkgit:git-config[1].
137
138 SEE ALSO
139 --------
140 linkgit:git-blame[1],
141 linkgit:git-log[1],
142 linkgit:gitformat-diff-hunks[5]
143
144 GIT
145 ---
146 Part of the linkgit:git[1] suite