The commit-graph file is a supplemental data structure that dramatically accelerates commit graph operations. It stores commit relationships and metadata in an optimized format that avoids the need to decompress and parse individual commit objects.
The commit-graph is stored at $GIT_DIR/objects/info/commit-graph or in the commit-graphs/ directory for chains.
H bytes - Root tree OID8 bytes - Parent data: [0-3]: First parent position (0x70000000 if none) [4-7]: Second parent position OR MSB=1 + offset into Extra Edge List8 bytes - Generation and timestamp: [0-3]: Bits 31-2 = topological level (gen v1) Bits 1-0 = commit time bits 33-34 [4-7]: Commit time bits 31-0 (seconds since epoch)
Parent Position Encoding
0x70000000 = No parent (root commit)
0x00000000 - 0x6FFFFFFF = Direct position reference
0x80000000+ = MSB set, remaining bits point to Extra Edge List
This encoding supports up to ~1.8 billion commits per graph.
Root commits: corrected date = commit date (or 1 if date is 0)
Other commits: corrected date = max(commit date, 1 + max(parent corrected dates))
def compute_corrected_commit_date(commit): if not commit.parents: return max(commit.date, 1) max_parent_date = max(parent.corrected_date for parent in commit.parents) return max(commit.date, max_parent_date + 1)
Generation Number Property
Key Invariant: If commits A and B have generation numbers N and M where N ≤ M, then A cannot reach B.This enables early termination in graph walks without exploring unreachable commits.
.git/objects/info/commit-graphs/├── commit-graph-chain # Plain text list of hashes├── graph-{hash0}.graph # Base layer (oldest)├── graph-{hash1}.graph # Layer 1 └── graph-{hash2}.graph # Top layer (newest)
Commit at position i in layer 2 has global position: X0 + X1 + i
class CommitGraphChain: def __init__(self, layers): self.layers = layers self.offsets = [0] for layer in layers: self.offsets.append(self.offsets[-1] + layer.num_commits) def find_commit(self, position): for i, offset in enumerate(self.offsets[1:]): if position < offset: local_pos = position - self.offsets[i] return self.layers[i].get_commit(local_pos)
New layers are merged to maintain logarithmic chain length:Condition 1: If commits in layer N < X × commits in layer N+1 (default X=2)Condition 2: If commits in layer N+1 > C (default C=64,000)When triggered, layers are consolidated: