Git Worktree for Large Repos and Git LFS
Large repositories benefit the most from git worktree. Where cloning a multi-gigabyte repo a second time wastes disk space and bandwidth, worktrees share the entire object database, making additional checkouts fast and lightweight.
Disk Space Savings
A Git repository consists of two things: the object database (all commits, trees, and blobs stored in .git/objects/) and the working tree(the checked-out files). The object database is typically the larger of the two, and it grows with the project’s history.
With worktrees, the object database is shared. You pay for it once. Each additional worktree only adds the working tree files for that branch, which is roughly the size of a single checkout.
# Example: a 5 GB repository
# Two full clones = ~10 GB
~/projects/myapp-clone-1/ # 5 GB (.git + working tree)
~/projects/myapp-clone-2/ # 5 GB (.git + working tree)
# Total: ~10 GB
# One clone + one worktree = ~6.5 GB
~/projects/myapp/ # 5 GB (.git + working tree)
~/projects/myapp-feature/ # 1.5 GB (working tree only, shared .git)
# Total: ~6.5 GB
# One clone + four worktrees = ~11 GB vs 25 GB for five clones
# Savings grow with each additional worktreeYou can check your repository’s object database size with:
# Show the size of the Git object database
git count-objects -vH
# Example output:
# size-pack: 3.2 GiB ← this is shared across all worktrees
# size: 128 KiB ← loose objects (small)Worktrees vs Multiple Clones for Large Repos
For small repos, cloning twice is barely noticeable. For large repos, the difference is significant:
| Factor | Multiple Clones | Worktrees |
|---|---|---|
| Disk space | N x full repo size | 1 repo + N x working tree |
| Clone time | Full network transfer each time | Instant (local only) |
| Git fetch | Must fetch in each clone | Fetch once, visible everywhere |
| Branch refs | Independent per clone | Shared across worktrees |
| Configuration | Separate per clone | Shared (with per-worktree overrides) |
For repositories over 1 GB, worktrees are almost always the better choice. The setup cost is negligible compared to the time and disk space saved.
Git LFS with Worktrees
Git Large File Storage (LFS) replaces large files (images, videos, models, datasets) with lightweight pointer files in the repo and stores the actual content on a remote server. Worktrees and LFS work together, but there are nuances to understand.
LFS files are fetched per-worktree
When you create a new worktree, Git checks out the pointer files but may not automatically download the LFS content. You need to run git lfs pull in the new worktree to fetch the actual files.
# Create a worktree in an LFS-enabled repo
git worktree add ../myapp-feature feature/new-assets
# LFS pointer files are checked out, but actual files may be missing
cd ../myapp-feature
git lfs pull
# Or fetch and checkout LFS files for specific patterns only
git lfs pull --include="assets/images/**"
git lfs pull --exclude="assets/videos/**"Shared LFS cache
Git LFS uses a local cache (by default at .git/lfs/). Since worktrees share the .git directory, they also share the LFS cache. This means if a file was already downloaded in one worktree, it does not need to be downloaded again in another.
# Check the LFS cache size
git lfs ls-files -s
# The cache lives in the shared .git directory
# All worktrees benefit from already-downloaded files
ls -lh .git/lfs/objects/LFS fetch for all worktrees at once
# Fetch LFS objects for recent branches (covers most worktrees)
git lfs fetch --recent
# Or fetch for specific refs
git lfs fetch origin main feature/new-assetsPerformance Tips
- Use shallow worktrees for CI. If you only need the latest commit in a worktree (e.g., for a build server), combine worktrees with a shallow clone to minimize checkout time.
- Run
git gcperiodically. With many worktrees creating objects, the shared object database can accumulate loose objects. Runninggit gcpacks them efficiently. - Avoid excessive worktrees on spinning disks. Multiple worktrees on an HDD can cause I/O contention. SSDs handle parallel reads much better.
- Use
git maintenancefor automated upkeep. Git 2.29 addedgit maintenance start, which periodically runs gc, fetch, and other tasks in the background.
# Enable automatic background maintenance
git maintenance start
# This runs hourly:
# - git maintenance run --task=commit-graph
# - git maintenance run --task=prefetch
# - git maintenance run --task=loose-objects
# - git maintenance run --task=incremental-repackSparse Checkout + Worktrees
For monorepos or very large repositories, you can combine worktrees with sparse checkout to check out only the directories you need. This reduces both disk usage and checkout time per worktree.
# Create a worktree
git worktree add ../myapp-feature feature/auth
# Enable sparse checkout in the new worktree
cd ../myapp-feature
git sparse-checkout init --cone
# Only check out the directories you need
git sparse-checkout set src/auth src/shared tests/auth
# Verify what's checked out
git sparse-checkout list
# src/auth
# src/shared
# tests/authEach worktree can have its own sparse checkout configuration. A frontend developer might check out only src/frontend, while a backend developer checks out src/api— each in their own worktree, all sharing the same repository.
# Different sparse checkouts per worktree
~/projects/
├── myapp.git/ # bare repo
├── frontend/ # sparse: src/frontend, src/shared
│ └── src/
│ ├── frontend/
│ └── shared/
├── backend/ # sparse: src/api, src/shared
│ └── src/
│ ├── api/
│ └── shared/
└── mobile/ # sparse: src/mobile, src/shared
└── src/
├── mobile/
└── shared/