What Causes This Issue
Developers working with large Git repositories on macOS frequently encounter sluggish git status, git checkout, and git fetch operations. The problem intensifies when repositories exceed several gigabytes or contain hundreds of thousands of files — common in monorepos, game projects, and long-running iOS codebases. Users in the Apple Support Community report that performance degrades sharply after macOS upgrades, when Spotlight indexing conflicts with Git’s filesystem scanning, or when Xcode’s built-in source control attempts to scan the entire work tree.
Root causes include: the default fsmonitor daemon not running, untuned packfile configuration, missing commit-graph generation, and sparse checkout or partial clone features left disabled. Antivirus tools and Time Machine can also lock files during Git operations. On Apple Silicon, the issue sometimes stems from Rosetta-translated Git binaries instead of native arm64 builds.
Step-by-Step Fixes
- Enable and verify fsmonitor — Run
git config --global core.fsmonitor truethengit fsmonitor--daemon status. The daemon should report “running.” If it fails, ensuregitis the native arm64 binary (arch -arm64 git version). - Generate commit-graph and reachability bitmap — Execute
git commit-graph write --reachable --splitfollowed bygit repack -ad --write-bitmap-index. This accelerates history traversal andgit logby orders of magnitude. - Configure sparse checkout for monorepos — In the repo root, run
git sparse-checkout init --conethengit sparse-checkout set <directory1> <directory2>to limit the working tree to active folders. Pair withgit clone --filter=blob:none --sparsefor new clones. - Tune packfile limits — Add to
~/.gitconfig:[pack]packSizeLimit = 2gthreads = 0[repack]writeBitmaps = true
This prevents excessive small packfiles and enables parallel delta compression. - Exclude .git from Spotlight and Time Machine — Open System Settings → Siri & Spotlight → Spotlight Privacy, add the repository root. In Time Machine Options, exclude the same path. This stops metadata indexers from fighting Git for file handles.
- Upgrade to Git 2.45+ via Homebrew — Run
brew install gitand ensure/opt/homebrew/bin/gitprecedes/usr/bin/gitin$PATH. Newer releases include fsmonitor–daemon improvements and bundle-uri support for faster fetches. - Disable Xcode source control for massive repos — In Xcode Settings → Source Control, uncheck “Enable Source Control” for the project. Use command-line Git or a dedicated client (Tower, Fork, GitKraken) instead. Xcode’s scanner chokes on repos over 50k files.
- Run maintenance via cron — Add a daily job:
0 3 * * * cd /path/to/repo && git maintenance run --auto. This auto-schedulesgc,commit-graph, andprefetchwithout manual intervention.
Additional Solutions
Partial clone with blobless filter reduces initial clone time and disk usage. Use git clone --filter=blob:none --sparse <url> then populate directories on demand. For CI runners, combine with --depth=1 and --branch to fetch only recent history.
Configure core.untrackedCache to true for repos with many ignored files (build artifacts, node_modules, DerivedData). This caches git status results between runs. Test first — some network filesystems misbehave with this setting.
Use git maintenance register to install launchd timers that run git maintenance run hourly. This keeps the repository optimized without cron. Verify with git maintenance start and check ~/Library/LaunchAgents/ for the plist.
Migrate LFS assets to a dedicated server if .git/lfs exceeds 10 GB. Large binary assets slow down git fetch and git push even with core.fsmonitor. Configure lfs.url to point to an S3-backed endpoint (e.g., https://lfs.example.com) and run git lfs migrate import --everything.
Check for filesystem case-sensitivity conflicts. APFS case-insensitive volumes cause Git to treat README.md and readme.md as the same file, triggering repeated index rewrites. Create a case-sensitive APFS volume via Disk Utility, clone there, and symlink into your home directory.
When to Contact Apple Support
Open a support case if: fsmonitor daemon crashes repeatedly with kqueue errors in Console.app (indicates a kernel-level filesystem notification bug), Git operations hang indefinitely on APFS volumes with no disk pressure (possible fsck_apfs needed), or Xcode source control crashes the sourcecontrol daemon after enabling core.fsmonitor (signals a framework regression). Provide sysdiagnose output and the exact Git version (git --version --build-options).
FAQ
Why does git status take 30+ seconds on my 200k-file repo? The fsmonitor daemon is likely disabled or crashed. Run git fsmonitor--daemon status; if stopped, restart with git fsmonitor--daemon start. Ensure core.fsmonitor=true is set globally.
Does git maintenance replace manual git gc? Yes. git maintenance run --auto schedules gc, commit-graph write, prefetch, and loose-objects cleanup based on repository size and activity. It’s safer than manual git gc --aggressive, which can bloat packfiles.
Can I use sparse checkout with Xcode? Poorly. Xcode’s project loader expects all referenced files on disk. Sparse checkout hides unpinned directories, causing “file not found” build errors. Either disable sparse checkout for Xcode projects or use git sparse-checkout set to include every folder the project references.
Is the Homebrew Git binary required on Apple Silicon? Strongly recommended. The system /usr/bin/git (currently 2.39.x on macOS 15) lacks fsmonitor--daemon improvements, bundle-uri, and repack --write-bitmap-index optimizations. Homebrew’s 2.45+ is native arm64 and 15-30% faster on large repos.
How do I measure if fixes worked? Run time git status and time git checkout <branch> before and after. Target: git status under 200 ms on a 100k-file repo with fsmonitor warm. Use git count-objects -vH to track packfile count and size — fewer, larger packs indicate healthy repacking.






































