Gitgit maintenance

git maintenance (Git 2.29+)

Introduced in Git 2.29, git maintenance is the modern, structured approach to keeping a repository healthy in the background. Unlike git gc — which runs as a blocking operation in your terminal — git maintenance start registers an OS-level scheduled task that runs maintenance jobs at regular intervals while you work, without interrupting any Git operation. It is particularly valuable for large repositories and monorepos where gc can take minutes.

Starting Background Maintenance

git maintenance start registers OS-level scheduling mechanisms: launchd on macOS, systemd timers or cron on Linux, and Windows Task Scheduler on Windows. After registering, maintenance tasks run automatically on schedule.

Start background maintenance for the current repo

Bash
git maintenance start

Example output on macOS

Text
Created symlink /Users/you/Library/LaunchAgents/org.git-scm.git.fetcher.plist.
Created symlink /Users/you/Library/LaunchAgents/org.git-scm.git.housekeeping.plist.
Stopping Background Maintenance

Unregister background maintenance

Bash
git maintenance stop
Running Maintenance Manually

Run all maintenance tasks now

Bash
# Run all registered tasks
git maintenance run

# Run a specific task only
git maintenance run --task=gc
git maintenance run --task=commit-graph
git maintenance run --task=prefetch
git maintenance run --task=loose-objects
git maintenance run --task=incremental-repack
Available Maintenance Tasks

Task

What it Does

Default Schedule

gc

Full garbage collection — packs loose objects, prunes expired reflog

Daily (if enabled)

commit-graph

Writes/updates the commit graph file for faster history queries

Hourly

prefetch

Fetches updates from all remotes in background (does not update branches)

Hourly

loose-objects

Packs loose objects into pack files incrementally

Daily

incremental-repack

Repacks existing packs into more efficient arrangements over time

Daily

pack-refs

Packs loose refs into packed-refs file for faster ref lookups

Weekly

The Commit Graph File

The commit graph is a binary data file at .git/objects/info/commit-graph that caches information about commits — parents, generation numbers, tree hashes — enabling Git to answer reachability queries in O(1) instead of traversing the full object graph. Operations like git log, git blame, git merge-base, and git push all benefit from a populated commit graph.

Manually write the commit graph

Bash
# Write commit graph for all reachable commits
git commit-graph write --reachable

# Write an incremental chain (faster for large repos)
git commit-graph write --reachable --split

# Check if commit graph exists
ls .git/objects/info/

Commit graph files

Text
.git/objects/info/
  commit-graph               ← monolithic commit graph
  # or, with --split:
  commit-graphs/
    graph-abc123.graph       ← incremental chain files
    graph-def456.graph
    commit-graph-chain       ← lists which chain files to use

See the performance impact

Bash
# Without commit graph
time git log --oneline main..feature/big-branch | wc -l
# real    0m4.231s

# After writing commit graph
git commit-graph write --reachable
time git log --oneline main..feature/big-branch | wc -l
# real    0m0.087s
Note
The speedup from the commit graph is especially dramatic on repositories with tens of thousands of commits. GitHub, GitLab, and Gitea all maintain commit graphs server-side for this reason.
Configuring Maintenance Tasks

Each task's behavior and schedule can be tuned through the repository's .git/config or global ~/.gitconfig.

Enable and configure maintenance tasks

Bash
# Enable a specific task
git config maintenance.commit-graph.enabled true
git config maintenance.gc.enabled true
git config maintenance.prefetch.enabled false  # disable if bandwidth is a concern

# Schedule options: hourly, daily, weekly
git config maintenance.commit-graph.schedule hourly
git config maintenance.loose-objects.schedule daily
git config maintenance.incremental-repack.schedule daily

.git/config section after setup

Text
[maintenance]
	auto = false
	strategy = incremental

[maintenance "commit-graph"]
	enabled = true
	schedule = hourly

[maintenance "prefetch"]
	enabled = true
	schedule = hourly

[maintenance "gc"]
	enabled = true
	schedule = daily

[maintenance "loose-objects"]
	enabled = true
	schedule = daily

[maintenance "incremental-repack"]
	enabled = true
	schedule = daily

[maintenance "pack-refs"]
	enabled = true
	schedule = weekly
Maintenance Strategy Presets

Use a built-in strategy

Bash
# incremental: no full gc, use incremental tasks instead (best for active repos)
git config maintenance.strategy incremental

# aggressive: runs gc periodically (smaller repos or archival repos)
git config maintenance.strategy aggressive
Tip
For developer workstations working with large repositories (monorepos, game assets, ML models), `git maintenance start` is one of the highest-impact single commands you can run. It will keep your commit graph fresh, pre-fetch remotes in the background, and pack loose objects continuously — making every Git operation feel snappier over time.