extension, but this is generally smaller than the full cache entry list.
When a path is updated in index, Git invalidates all nodes of the
recursive cache tree corresponding to the parent directories of that
path. We store these tree nodes as being "invalid" by using "-1" as the
number of cache entries. Invalid nodes still store a span of index
entries, allowing Git to focus its efforts when reconstructing a full
cache tree.
The signature for this extension is { 'T', 'R', 'E', 'E' }.
A series of entries fill the entire extension; each of which
consists of:
- NUL-terminated path component (relative to its parent directory);
- ASCII decimal number of entries in the index that is covered by the
tree this entry represents (entry_count);
- A space (ASCII 32);
- ASCII decimal number that represents the number of subtrees this
tree has;
- A newline (ASCII 10); and
- Object name for the object that would result from writing this span
of index as a tree.
An entry can be in an invalidated state and is represented by having
a negative number in the entry_count field. In this case, there is no
object name and the next entry starts immediately after the newline.
When writing an invalid entry, -1 should always be used as entry_count.
The entries are written out in the top-down, depth-first order. The
first entry represents the root level of the repository, followed by the
first subtree--let's call this A--of the root level (with its name
relative to the root level), followed by the first subtree of A (with
its name relative to A), and so on. The specified number of subtrees
indicates when the current level of the recursive stack is complete.
=== Resolve undo
A conflict is represented in the index as a set of higher stage entries.
When a conflict is resolved (e.g. with "git add path"), these higher
stage entries will be removed and a stage-0 entry with proper resolution
is added.
When these higher stage entries are removed, they are saved in the
resolve undo extension, so that conflicts can be recreated (e.g. with
"git checkout -m"), in case users want to redo a conflict resolution
from scratch.
The signature for this extension is { 'R', 'E', 'U', 'C' }.
A series of entries fill the entire extension; each of which
consists of:
- NUL-terminated pathname the entry describes (relative to the root of
the repository, i.e. full pathname);
- Three NUL-terminated ASCII octal numbers, entry mode of entries in
stage 1 to 3 (a missing stage is represented by "0" in this field);
and
- At most three object names of the entry in stages from 1 to 3
(nothing is written for a missing stage).
=== Split index
In split index mode, the majority of index entries could be stored
in a separate file. This extension records the changes to be made on
top of that to produce the final index.
The signature for this extension is { 'l', 'i', 'n', 'k' }.
The extension consists of:
- Hash of the shared index file. The shared index file path
is $GIT_DIR/sharedindex.<hash>. If all bits are zero, the
index does not require a shared index file.
- An ewah-encoded delete bitmap, each bit represents an entry in the
shared index. If a bit is set, its corresponding entry in the
shared index will be removed from the final index. Note, because
a delete operation changes index entry positions, but we do need
original positions in replace phase, it's best to just mark
entries for removal, then do a mass deletion after replacement.
- An ewah-encoded replace bitmap, each bit represents an entry in
the shared index. If a bit is set, its corresponding entry in the
shared index will be replaced with an entry in this index
file. All replaced entries are stored in sorted order in this
index. The first "1" bit in the replace bitmap corresponds to the
first index entry, the second "1" bit to the second