Home / Alt manpages / git-commit-graph(1)

  • git-commit-graph(1)
  • User command
  • linux

Build and Check a Git Commit-Graph Safely

On a repository with tens of thousands of commits, history traversal gets slow, and git commit-graph is the index Git built to speed that up. This guide has you build a commit-graph, verify it against the object database, and understand exactly what changed on disk. The graph does not replace commits, refs or packfiles: it sits alongside them.

Allow about ten minutes for a normal repository. You need Git 2.43.0 or a compatible installation and write access to the repository. The examples below use the installed git-man package version 1:2.43.0-1ubuntu7.3. Run these commands as the repository owner: elevated privileges are not normally needed, and using them can leave root-owned maintenance files behind.

1. Confirm the installed command

Start with read-only checks. This separates a command-version problem from a repository problem, and changes no files:

$ git --version
git version 2.43.0
$ git commit-graph -h
usage: git commit-graph verify [--object-dir <dir>] [--shallow] [--[no-]progress]
   or: git commit-graph write [--object-dir <dir>] [--append]
                              [--split[=<strategy>]] [--reachable | --stdin-packs | --stdin-commits]
                              [--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress]

The subcommands used here are write and verify. If your help output does not list them, stop and read the manual for the Git version actually installed on that host.

2. Inspect the repository before writing

Move to the target repository and check that Git sees it as a worktree. These are ordinary, read-only commands:

$ cd /path/to/repository
$ git rev-parse --show-toplevel
/path/to/repository
$ git rev-parse --git-dir
.git
$ git config --get core.commitGraph || echo 'core.commitGraph is unset'

An unset core.commitGraph is not an error; the default is to use commit-graphs when available. If the value is explicitly false, write prints a warning and returns success without writing a graph.

Tip

That success status is a distraction trap, so always check the expected location afterwards rather than trusting the exit code alone.

Checkpoint

You are in the intended repository, and you know whether a local configuration setting disables commit-graph use.

3. Write a graph for the repository

Run the basic write command first:

$ git commit-graph write
$ printf 'write status: %s\n' "$?"
write status: 0

For the usual repository layout, Git writes the graph below .git/objects/info/commit-graph. Check the file rather than assuming every repository shares that layout:

$ git rev-parse --git-path objects/info/commit-graph
/path/to/repository/.git/objects/info/commit-graph
$ test -r "$(git rev-parse --git-path objects/info/commit-graph)" && echo 'commit-graph is readable'
commit-graph is readable

The write is based on commits found in packfiles. A repository with only loose objects, or one whose graph is disabled, may not produce the file you expect. Do not create an empty file by hand as a workaround: this is a binary format with checks and object references built in.

Writing is a maintenance operation that can take real time on a large repository, though it never rewrites commits. It can replace or remove existing commit-graph data, so take care if another process is doing repository maintenance at the same time. There is no useful manual undo for an interrupted write; let the command finish, then verify. To remove a graph deliberately, use your normal Git maintenance procedure rather than deleting arbitrary files while Git is active.

4. Verify the graph against the object database

Verification reads the graph and checks its contents against the repository objects:

$ git commit-graph verify
$ printf 'verify status: %s\n' "$?"
verify status: 0

Success is normally quiet. A non-zero status means Git found a problem or could not read the graph. Capture the full diagnostic, then confirm the repository is not being modified by another Git process right now.

Warning

Do not "fix" a verification failure by deleting the object database or running a broad cleanup; that risks losing data the verification never actually accused of being wrong.

If there is no graph to verify, Git may report that it cannot open the commit-graph file. That usually means the earlier write did not create one, often because there were no suitable packed commits or core.commitGraph is disabled. Re-run the inspection from step 2 before touching configuration.

Checkpoint

git commit-graph verify returns status 0. That is the completion test that matters, not merely a successful write command.

5. Include all reachable commits when needed

The basic write only considers packed commits. To build from commits reachable from every ref, feed the ref tips in as commit IDs:

$ git show-ref -s | git commit-graph write --stdin-commits
$ git commit-graph verify
$ printf 'reachable graph status: %s\n' "$?"
reachable graph status: 0

--stdin-commits expects one hexadecimal object ID per line. Malformed or missing IDs are errors, though non-commit objects can simply be ignored. Do not combine this option with --reachable or --stdin-packs, since those are alternative input modes, not additive ones.

--reachable is the shorter form when you want Git itself to walk from every ref:

$ git commit-graph write --reachable
$ git commit-graph verify

Use one mode at a time. Keep the explicit stdin form for scripts where the input set needs to stay visible in the pipeline itself.

6. Add changed-path data deliberately

Path history commands such as git log -- path/to/file can benefit from changed-path Bloom filters. Ask Git to compute them with --changed-paths:

$ git commit-graph write --reachable --changed-paths
$ git commit-graph verify

Verification may print progress, depending on the repository and whether standard error is connected to a terminal, and the command can take considerably longer on a large repository. This option also shapes future writes, by recording that changed-path data is wanted; use --no-changed-paths to rewrite without storing it.

On this installed Git, the default commitGraph.generationVersion is 2. Avoid changing it just to make a write succeed. If several machines run different Git versions, check their support for the graph and Bloom-filter format before sharing a repository between them.

7. Use split graphs only for a reason

A split graph stores layers below objects/info/commit-graphs:

$ git commit-graph write --reachable --split
$ git commit-graph verify
$ git rev-parse --git-path objects/info/commit-graphs
/path/to/repository/.git/objects/info/commit-graphs

The bare --split lets Git apply its own merge rules. --split=no-merge keeps adding tip layers, while --split=replace replaces the existing chain with a freshly written one. Both affect maintenance cost and disk contents, so do not add them automatically to a one-off repair command. A later split write can remove unused graph layers as part of its normal expiry behaviour.

If you are chasing a split-chain failure, git commit-graph verify --shallow checks only the tip graph. That is a narrower diagnostic, not proof every layer is valid, so use plain verify for the final check.

Common traps

  • Replace objects or grafts. Git disables commit-graph reading and writing whenever replace objects or commit grafts are active. Check for that state before treating a missing graph as corruption.
  • Wrong object directory. --object-dir <dir> wants a known alternate object directory containing info and pack, not an arbitrary output folder. Git rejects a path that is not an absolute, known object directory.
  • Concurrent maintenance. Do not run this alongside another process that is repacking or changing refs. Wait for the other operation to finish, then write and verify again.
  • Configuration surprises. Check core.commitGraph and any commitGraph.* settings before assuming an option's default applies.

Done means

  • Confirmed the installed Git version and command syntax.
  • Inspected the target repository and its commit-graph configuration.
  • Wrote the graph using one deliberate input mode.
  • Ran git commit-graph verify and got status 0.
  • Chose changed-path filters or split storage only when their trade-offs fit the repository.
  • Left commits, refs and packfiles untouched throughout.