The all-in-one config
Putting the pieces together: this is a single configuration that applies the modern Git performance stack. Drop it into .git/config on a fresh clone, run the one-time tasks, and you have the recommended setup for repos with hundreds of thousands of files and active history.
The config block
[feature]
manyFiles = true
[core]
fsmonitor = true
untrackedCache = true
commitGraph = true
multiPackIndex = true
preloadIndex = true
[index]
version = 4
sparse = true
[fetch]
parallel = 0
writeCommitGraph = true
negotiationAlgorithm = skipping
showForcedUpdates = false
[gc]
auto = 0 # let maintenance handle it
writeCommitGraph = true
[maintenance]
auto = false # let scheduler drive it
[checkout]
workers = 0
thresholdForParallelism = 100
[pack]
useSparse = true
writeBitmaps = true
threads = 0
windowMemory = 256m
[commitGraph]
changedPathsVersion = 2
[diff]
algorithm = histogram
[merge]
conflictStyle = zdiff3
[rebase]
autoSquash = true
autoStash = true
updateRefs = true
[push]
autoSetupRemote = true
[protocol]
version = 2
One-time tasks
# Enable sparse, partial-clone-friendly setup
git sparse-checkout init --cone --sparse-index
git sparse-checkout set apps/web libs/shared
# Build performance artifacts
git commit-graph write --reachable --changed-paths
git multi-pack-index write --bitmap
git update-index --index-version 4
git pack-refs --all
# Start background maintenance
git maintenance start
Verification
git config --list --show-origin | sort
git maintenance status
git fsmonitor--daemon status
git-sizer --no-progress
GIT_TRACE2_PERF=1 git status
Per-platform notes
- Linux: raise
fs.inotify.max_user_watchesto 524288+. - macOS: nothing extra; FSEvents handles huge trees natively.
- Windows: exclude the working tree from real-time AV scanning.
- WSL2: works correctly; WSL1 does not (no inotify).
Per-team notes
Document this in the repo's CONTRIBUTING.md. Pin a Git version (2.39+ recommended) so the team gets consistent behavior. Run git maintenance start in onboarding scripts.
Common mistakes
Applying every setting at once without measuring — some have tradeoffs (e.g., fetch.showForcedUpdates=false hides force-pushes from fetch output). Forgetting the one-time tasks; the config does nothing without them. Using older Git that does not understand half the settings.
Related
See every Performance page; this playbook is the synthesis. Especially "Why Git performance matters at scale" and "Background maintenance: git maintenance run/start/stop".