Chapter 22Lesson 03~135 minutes

Commit-Graphs, Multi-Pack Indexes, Maintenance, Garbage Collection, and Performance: Configuration, Design Choices, and Tradeoffs

Design maintenance policy around current maintenance strategies, auto-maintenance controls, commit-graph/MIDX settings, FSMonitor, untracked cache, Scalar, and developer/CI/server lifecycle differences.

ConfigurationFSMonitorScalarOperational policy

Learning objectives

  • Choose among current maintenance strategies and task-level overrides.
  • Distinguish maintenance.auto from traditional gc.auto heuristics.
  • Use current commit-graph changed-path controls and recognize deprecated settings.
  • Separate FSMonitor/untracked-cache working-tree acceleration from object-store optimization.
  • Select policies differently for developer clones, CI checkouts, and central servers.

1. Performance configuration is a policy decision, not a collection of magic switches

Optimization changes CPU, memory, disk, background I/O, network access, and recovery behavior. A developer clone, an ephemeral CI checkout, and a central bare repository have different lifecycles. Configure each environment from measured constraints instead of copying a “fast Git” profile everywhere.

2. Inspect scope and origin before changing behavior

git config --list --show-origin --show-scope
git config --show-origin --get maintenance.strategy
git config --show-origin --get maintenance.auto
git config --show-origin --get gc.auto
git config --show-origin --get core.commitGraph
git config --show-origin --get core.multiPackIndex
git config --show-origin --get commitGraph.changedPaths
git config --show-origin --get core.untrackedCache
git config --show-origin --get core.fsmonitor

Repository-local settings are appropriate for a lab; global settings affect every repository for that user. Scheduled maintenance registration also commonly involves global configuration because one scheduler invocation can iterate over registered repositories.

3. Current maintenance strategies encode different cost/retention models

Strategy Current intent Best fit
none No strategy-selected tasks Explicit/manual control
gc Run the GC task Traditional/simple maintenance
geometric Geometric repacking plus auxiliary housekeeping; can expire stale data under configured policy Current recommended large-repository manual strategy
incremental Small scheduled tasks; avoids scheduling GC/data-deleting tasks Background maintenance with bounded foreground impact

Current documentation makes geometric the default for manual maintenance and describes incremental as the background-oriented small-task strategy. This has evolved across Git versions, so mixed-version fleets need an explicit documented strategy.

4. Task-specific configuration overrides strategy defaults

git config --local maintenance.commit-graph.enabled true
git config --local maintenance.commit-graph.schedule hourly
git config --local maintenance.incremental-repack.enabled true
git config --local maintenance.incremental-repack.schedule daily

If git maintenance run receives explicit --task options, those tasks take precedence. Otherwise strategy and maintenance.<task>.enabled/.schedule determine what runs.

5. maintenance.auto and gc.auto are related but not identical control surfaces

maintenance.auto controls whether eligible foreground commands trigger git maintenance run --auto. Traditional gc.auto defines a loose-object threshold for automatic GC heuristics; gc.autoPackLimit covers pack-count consolidation. Setting gc.auto=0 disables the GC auto heuristics, but it is not a universal “disable every kind of maintenance” switch.

Registration for scheduled maintenance can disable foreground auto-maintenance in the registered repository so background scheduling owns the work.

6. core.commitGraph controls reading the commit-graph; writing is separate

Current Git defaults core.commitGraph to true. If a valid commit-graph exists, Git may use it for graph traversal. Writing/updating the file comes from git commit-graph write, GC, or the commit-graph maintenance task.

git config --local core.commitGraph true
git config --local commitGraph.changedPaths true

commitGraph.changedPaths=true makes writes compute changed-path Bloom filters by default.

7. commitGraph.readChangedPaths is now deprecated

Current Git documents commitGraph.readChangedPaths as deprecated. New policy should use the current changed-path configuration/version controls rather than institutionalizing a deprecated toggle. commitGraph.changedPathsVersion can affect compatibility: newer Bloom-filter versions may not be understood by older Git releases.

Mixed-version rule: choose the oldest Git version that must read the repository's auxiliary formats, then verify compatibility before enabling newer format versions fleet-wide.

8. core.multiPackIndex defaults to true, but a MIDX must exist to help

The setting tells Git to use a multi-pack index when present. It does not create one. Writing, verifying, repacking, compacting, and expiring MIDX structures are separate operations. Current Git 2.54+ also includes version-2/incremental MIDX features with compatibility boundaries for older clients.

9. FSMonitor solves working-tree scanning, not object-store lookup

The built-in filesystem monitor can tell Git which paths may have changed so commands such as status avoid scanning every file. Current Git documentation describes the built-in daemon as platform-dependent; Windows and macOS are explicitly supported in current configuration documentation. Other platforms may use different support/build/runtime paths.

git config --local core.fsmonitor true

Do not enable it blindly in a mixed-version toolchain. Older Git clients historically interpreted boolean core.fsmonitor values differently.

10. The untracked cache avoids repeated directory scans when filesystem mtimes are reliable

git update-index --test-untracked-cache
git config --local core.untrackedCache true

The untracked cache stores directory information in the index. Its benefit is strongest in large working trees with many untracked paths. The filesystem must update directory mtimes reliably for the cache assumptions to hold.

11. FSMonitor and untracked cache can complement each other

Current status documentation explains that using both can reduce two different costs: identifying modified tracked paths and enumerating changed directories for untracked files. Performance improves after caches warm; benchmark several runs before drawing conclusions.

12. Scalar is an optional large-repository management layer

scalar is shipped as a Git tool for managing large repositories. It can configure recommended large-repository settings and maintenance behavior. It is useful when a team wants an opinionated bundle of features, but it is not a prerequisite for understanding Git's underlying commit-graph, maintenance, sparse/partial, and working-tree mechanisms.

scalar version
scalar list

Use Scalar only after verifying its availability and the configuration it will apply. The mandatory chapter labs use core Git commands so learners understand the mechanisms directly.

13. Developer, CI, and server repositories have different maintenance responsibilities

A long-lived developer clone benefits from working-tree acceleration and background maintenance. An ephemeral CI clone may be deleted before background maintenance could repay its cost; checkout depth/transfer choices matter more. A central bare server has no working tree, so FSMonitor/untracked-cache are irrelevant, while pack/commit-graph/ref maintenance can be important at scale.

14. Decision table — justify the operational cost

Environment Measured problem Likely choice Tradeoff
Long-lived developer monorepo slow status + growing packs untracked cache/FSMonitor where supported + scheduled incremental/geometric maintenance background CPU/I/O; platform/version dependencies
Ephemeral CI clone checkout/fetch dominates optimize transfer/checkout; minimal local maintenance less history/auxiliary reuse
Bare integration server many packs/history queries MIDX/commit-graph and controlled server maintenance maintenance windows and I/O load
Small repository no measurable bottleneck defaults lowest operational complexity

15. Knowledge check

Question 1. Does core.multiPackIndex=true automatically create a MIDX?

Question 2. Why is commitGraph.readChangedPaths a poor new policy knob?

Question 3. Which performance problem does FSMonitor address?

Question 4. Why might an ephemeral CI clone skip background maintenance?

Question 5. When should Scalar be considered?

16. Summary

Configuration should follow repository lifetime and bottleneck. Current Git offers maintenance strategies, task overrides, commit-graph/MIDX defaults, working-tree accelerators, and Scalar; each solves a different problem and carries different portability, retention, and background-work costs.

Next

Diagnose when optimization targets the wrong layer

Lesson 4 engineers misdiagnosed status latency, corrupted auxiliary structures, maintenance overlap, cold/warm-cache benchmark errors, and dangerous pruning assumptions.

Authoritative references

 git-maintenance configuration
 git-config
 git-update-index caches
 git-fsmonitor--daemon
 scalar

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.