130 lines
4.8 KiB
Plaintext
130 lines
4.8 KiB
Plaintext
gitformat-diff-hunks(5)
|
|
=======================
|
|
|
|
NAME
|
|
----
|
|
gitformat-diff-hunks - Precomputed diff hunk store format
|
|
|
|
SYNOPSIS
|
|
--------
|
|
[verse]
|
|
$GIT_DIR/objects/info/diff-hunks
|
|
|
|
DESCRIPTION
|
|
-----------
|
|
|
|
The diff-hunks store memoizes diff hunk coordinates so that commands
|
|
that need them, such as `git log --stat` and linkgit:git-blame[1], can
|
|
skip running the diff algorithm (and, for blame, loading the blob
|
|
content; the summary formats still test each pair for binariness,
|
|
which can load the blobs). See
|
|
linkgit:git-diff-hunks[1] for how the store is filled and managed and the
|
|
configuration that controls it.
|
|
|
|
The store is a single file, `$GIT_DIR/objects/info/diff-hunks`, written
|
|
in one pass and replaced atomically, so a reader sees either the old
|
|
file or the complete new one.
|
|
|
|
Entries are keyed by the object IDs of the blob pair that was diffed
|
|
and by the diff algorithm and ignore flags (`xdl_opts`) the pair was
|
|
diffed under. A blob pair fully determines the diff input, so an entry
|
|
is valid regardless of which commits, branches, or index states the
|
|
pair was encountered in, and identical diffs performed in different
|
|
contexts share one entry. A reader whose `xdl_opts` differ from an
|
|
entry does not match it and falls back to computing the diff.
|
|
|
|
FILE FORMAT
|
|
-----------
|
|
|
|
All multi-byte integers are stored in network byte order. The file is an
|
|
8-byte header, the chunk table of contents and chunk data described in
|
|
linkgit:gitformat-chunk[5], and a trailing checksum.
|
|
|
|
HEADER
|
|
~~~~~~
|
|
|
|
- 4-byte signature: `DHPF` (diff-hunks precomputed format)
|
|
- 1-byte version number: currently 1
|
|
- 1-byte hash version: 1 for SHA-1, 2 for SHA-256. A store whose hash
|
|
function differs from the repository's is ignored.
|
|
- 1-byte number of chunks
|
|
- 1-byte reserved
|
|
|
|
CHUNK LOOKUP
|
|
~~~~~~~~~~~~
|
|
|
|
A table of contents in the format of linkgit:gitformat-chunk[5], listing
|
|
the offset of each chunk. Both chunks below are required; a file missing
|
|
either is treated as corrupt.
|
|
|
|
CHUNK DATA
|
|
~~~~~~~~~~
|
|
|
|
DHIX (index)::
|
|
A sorted sequence of fixed-size entries. Each entry is the old
|
|
blob object ID, the new blob object ID, a 4-byte `xdl_opts`
|
|
value, and a 4-byte offset into the DHDT chunk. Entries are
|
|
sorted by old object ID, then new object ID, then `xdl_opts`,
|
|
so lookups can use binary search on the full key.
|
|
|
|
DHDT (hunk data)::
|
|
For each index entry, at its offset: a 4-byte hunk count followed
|
|
by that many 16-byte hunk records. A hunk record is four 4-byte
|
|
values: old start, old count, new start, new count.
|
|
Starts are 0-based line numbers in the old and new blob; counts
|
|
are numbers of lines. The hunk count is at least 1: a record with
|
|
no hunks would claim the blob pair equivalent, which the store
|
|
never records, so readers treat such a record as invalid.
|
|
Identical hunk blocks are stored once:
|
|
distinct index entries whose recorded hunks are byte-for-byte
|
|
equal point at the same offset.
|
|
|
|
TRAILER
|
|
~~~~~~~
|
|
|
|
A checksum of all preceding bytes, computed with the repository hash
|
|
function.
|
|
|
|
CORRECTNESS
|
|
-----------
|
|
|
|
Serving hunks from a valid store produces the same output as recomputing
|
|
the diff. The diff of a blob pair is not unique: a zero context length
|
|
triggers xdiff's common-tail trimming, which can pick a different but
|
|
equally valid set of hunks than an untrimmed diff does. A pair is
|
|
therefore recorded only when its trimmed and untrimmed diffs are
|
|
identical, which is the common case. Such an entry answers any consumer
|
|
at any context: git-blame replays its coordinates directly (it diffs at
|
|
zero context), and diffstat sums its per-hunk line counts, which the
|
|
context length does not change. The rare pair whose two diffs differ is
|
|
never recorded, so every consumer computes it.
|
|
|
|
A store that cannot be used is ignored, and the consumer falls back to
|
|
computing the diff. Every offset and count read from the file is
|
|
bounds-checked, so a store that is missing, truncated, of an unknown
|
|
version, or of a different object hash does not change the diff output
|
|
and does not produce a diagnostic; `git diff-hunks verify` is what
|
|
reports corruption.
|
|
|
|
The store is not re-checksummed on the read path. The writer fsyncs the
|
|
file (honoring `core.fsync`) and commits it atomically, so a
|
|
committed store is intact, the same trust model the commit-graph and
|
|
multi-pack-index use. The trailing checksum is recomputed by
|
|
`git diff-hunks verify` to detect corruption.
|
|
|
|
The checksum detects corruption but does not prove who wrote the file. A
|
|
reader trusts the coordinates in a store that passes its checks, so
|
|
anything able to write a checksum-valid file at the store path can
|
|
influence output, the same as it could by writing objects directly.
|
|
|
|
LIMITATIONS
|
|
-----------
|
|
|
|
- Hunk counts, offsets, and line coordinates are 32-bit, capping the
|
|
hunk data at 4 GiB and a single entry at roughly 268 million hunks.
|
|
A result whose coordinates cannot be represented is not recorded.
|
|
|
|
GIT
|
|
---
|
|
Part of the linkgit:git[1] suite
|