A git repository can be larger than the code it holds
History, packfiles and old branches accumulate in .git. How to find the heavy repositories, shrink them safely, and spot a large file in history.
A checkout you can see is one copy of the code. The .git folder next to it holds every version of every file that repository has ever contained, which is why cloning something small can produce something large.
Find the heavy repositories
find ~ -type d -name .git -maxdepth 6 2>/dev/null \
-exec du -sh {} + | sort -h | tail -20That lists the twenty largest .git folders on the Mac. Compare each against the size of the project around it. A .git folder several times larger than the working tree means something heavy is in the history, and the next section finds it.
The routine cleanup first
git count-objects -vH
git gc --aggressive --prune=nowcount-objects reports the split between loose objects and packed ones. gc repacks them and drops anything unreachable, which on a repository with a lot of branch churn can halve the folder. It is safe: nothing reachable from a branch, tag or the reflog is removed.
Note that --prune=now also discards the reflog's protection for commits you have already abandoned, so if you are in the middle of recovering a lost commit, do that first.
When the history itself is the problem
If gc barely moves the number, something large is committed in the history: a video, a dataset, a build artefact, or a dependency folder that should have been ignored. This lists the largest objects in the repository:
git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '$1=="blob" {print $3, $4}' | sort -n | tail -20Removing a file from history rewrites every commit that touched it, which changes commit hashes and requires a force push and a fresh clone for everyone else. On a shared repository that is a coordination problem rather than a technical one, and it is usually not worth doing for disk space alone.
The cheaper options
- Delete the clone. For a repository you can clone again, the local copy is disposable. This is the fastest gigabytes on any developer Mac.
- Clone shallow next time.
git clone --depth 1fetches one commit of history instead of all of it. - Check Git LFS storage. LFS keeps its own cache under
.git/lfs, and it holds versions of large files you no longer have checked out. - Remove build output, not history. Often the repository is fine and the
target,buildornode_modulesfolder beside it is what is large.
du -sh .git/lfs 2>/dev/null
git lfs pruneThat last command removes local LFS files that are not needed by the current checkout, and it is usually the largest safe win on a repository that uses LFS. For the folders beside the repository rather than inside it, node_modules across every project and Rust target folders are the usual suspects.
Common questions
Why is my .git folder so large?
Because it stores every version of every file the repository has ever contained. If it is much larger than the working tree, something heavy is in the history, typically a dataset, a video, or a dependency folder that was committed before being ignored.
Is git gc safe to run?
Yes. It repacks objects and removes ones nothing references, and anything reachable from a branch, tag or the reflog is kept. Using --prune=now additionally drops the reflog's protection for already abandoned commits, so avoid it mid recovery.
How do I find large files in git history?
List all objects with git rev-list --objects --all and check their sizes with git cat-file --batch-check, then sort. That prints the largest blobs with their paths, which is usually enough to identify what was committed by mistake.
Does deleting a local clone lose anything?
Only if the repository has no remote. Run git remote -v first. With a remote, the clone is disposable and re-cloning restores everything, which makes it one of the easiest ways to reclaim space on a developer Mac.