To find the largest files stored in a repository’s reachable Git history on macOS, open Terminal, change to the repository, and pipe Git’s object list through git cat-file and sort. This reports each blob’s uncompressed size in bytes and a path hint. It can reveal files that were deleted or replaced but remain in commits reachable from branches or tags.

Run a history scan from Terminal

In Terminal, use cd to enter the repository. Quote the folder path if it contains spaces. Then run:

git rev-list --objects --all |
  git cat-file --batch-check='%(objecttype) %(objectsize) %(objectname) %(rest)' |
  awk '$1 == "blob"' |
  sort -k2,2nr |
  head -20

The output is sorted largest first. Each row shows the object type, byte count, object ID and, when Git provides one, a path hint. git rev-list --objects --all walks objects referenced by commits reachable from refs, such as local branches and tags; git cat-file --batch-check reports each object's type and size. The pipeline filters for blobs, the objects that hold file contents. Git’s rev-list documentation describes object traversal and names, and cat-file documents batch size and type output.

sort -k2,2nr uses macOS’s built-in sort to order numerically in reverse by the second whitespace-separated field, the byte size. head -20 limits display to 20 rows; change the number or remove that last line to see more. The command only reads repository data. It does not modify commits or files.

Interpret the results carefully

A row identifies a blob object, not necessarily a file currently present in the working tree. A large object can come from an old version of a file, and a path hint is not a complete historical path index: Git documents that with --objects, names are hints, may be altered for newlines, and when an object has multiple names only one may be shown. Treat the listed path as a lead, then inspect relevant commits to confirm when and where the content appeared. Git’s rev-list object-name notes explain these limitations.

This scan covers objects reachable from refs discovered by --all, not every object that may physically remain in the object database. To check local object storage, including unreachable objects, run:

git cat-file --batch-all-objects \
  --batch-check='%(objecttype) %(objectsize) %(objectname)' |
  awk '$1 == "blob"' |
  sort -k2,2nr |
  head -20

--batch-all-objects visits all objects in the repository and alternate object stores, including objects that are not reachable from refs. This second command omits file paths, so use the object ID to investigate further. The cat-file documentation notes both the broader object coverage and that each object is shown once even if stored multiple times.

Blob size is not the same as disk space

The reported objectsize is the uncompressed size of a Git object. Git may compress objects or store them as deltas inside packfiles, so a large blob is not necessarily consuming that exact amount of disk. For an overview of storage use, run git count-objects -vH; its size-pack field reports packed data size and its other fields summarize loose objects and related storage. Git’s count-objects manual documents these figures. To inspect packed-object sizes and delta details, git verify-pack -v lists each packed object's size and size in the packfile, but requires the relevant .idx file. The verify-pack manual defines that output.

If you find a large historical file

First decide whether your task is to understand the current checkout or reduce repository history. For the current version only, inspect files in Finder or use a file-size listing in Terminal; the history scan answers a different question by searching reachable Git objects.

If a large file should be removed from every revision, deleting it in a new commit alone does not erase older copies from history. History rewriting changes commit IDs and affects other people using the repository, so coordinate before doing it and preserve a backup. The git-filter-repo project offers a read-only analysis mode, git filter-repo --analyze, which writes reports to help decide what to filter; it does not perform the rewrite in analysis mode. The project’s documentation describes the analysis option and warns that filtering rewrites history.

The first pipeline is the practical starting point when the goal is to find the biggest file contents behind a local repository’s history. Use the all-object scan when unreachable leftovers matter, and compare Git object sizes with pack storage before attributing disk use to a particular blob.

Sources