Background repository maintenance arrives in Git 2.31

The open source Git project has released version 2.31 with contributions from 85 developers, 23 of whom are new. The headline feature is a new git maintenance command that lets Git perform routine repository upkeep in the background, rather than forcing you to pause your work when it decides a maintenance run is due.

Git normally optimizes for the write path while you work, deferring more expensive reorganization until later. That trade-off can backfire when Git's own heuristics trigger a blocking git gc --auto at an inconvenient moment. The new background maintenance feature takes a different approach: it schedules repository health tasks so they never block interactive commands.

Enabling background maintenance is a one-command operation:

$ git maintenance start

Once enabled, Git will pre-fetch the latest objects from your remotes once an hour, update its commit-graph file on the same schedule, and pack loose objects plus incrementally repack packed objects nightly. This should make git fetch noticeably faster over time since recent objects will often already be present locally. The feature is configurable via maintenance.* options, and troubleshooting guidance is documented in the git maintenance manual page.

Faster packfile lookups with reverse indexes

Git stores objects in packfiles for efficiency, and maintains a forward index (the .idx file) to translate object IDs into byte offsets within those packfiles. Going the other direction—mapping a byte position back to the object it belongs to—has historically required building an in-memory reverse index each time it was needed, which meant generating an array of position/object pairs and sorting them. For large packfiles, that construction cost adds up.

Why does the reverse direction matter? Consider the task of printing the size of a single object in a packfile. To measure an object's size, Git must locate that object and the one immediately following it, then subtract the two positions. Finding the adjacent object's start requires the reverse index. A simple benchmark comparing the time to print an object's contents against the time to print its size showed the latter was more than 62 times slower—until Git 2.31 added an on-disk reverse index format with the .rev extension.

With the reverse index serialized to disk, the same measurement runs in roughly the same time as printing the object's contents. The improvement also benefits network operations: when serving a fetch or push, Git can send object bytes directly from disk much faster with the reverse index precomputed.

The .rev format is opt-in for now. You can enable it with git config pack.writeReverseIndex true, then regenerate your packfiles with git repack -Ad. The GitHub engineering team reports using this feature in production for several months with dramatic improvements across many Git operations.

Notable smaller changes

  • New generation numbers for commit graphs. The commit-graph file now supports a new kind of generation number that can accelerate commit walks in certain scenarios. These patches came from Google Summer of Code contributor Abhishek Kumar.
  • Branch name handling for empty clones. When cloning an empty repository, Git now respects the remote's configured default branch name instead of falling back to whatever local convention would otherwise apply. Previously this only worked for repositories that already had commits.
  • Configurable clone remote name. Git 2.30 added the clone.defaultRemoteName configuration option, letting you set the name for the first remote instead of always using "origin".
  • Disk usage reporting in git rev-list. A new --disk-usage flag computes the total object size for the commits you're examining, which is simpler and faster than summing sizes with existing tools. This makes it easier to identify which branches contribute the most to repository growth.
  • Selective diff hunk filtering. Git 2.30 introduced -I<regex>, which lets you exclude hunks where all changed lines match a pattern. For example, git log -p -I'//' will skip hunks that only touch comment lines.
  • Optimized rename detection. In preparation for a future merge backend replacement, significant work has gone into making rename detection faster. The optimization details are documented in a two-part series, "Optimizing git's merge machinery."

For the complete list of changes across both release cycles, consult the release notes for versions 2.30 and 2.31.