Git LFS — A 2GB .git Folder Broke CI for Everyone
Binary assets bloated the .git folder to 2GB.
20+ years shipping production infrastructure and CI/CD at scale. Drawn from code that ran under real load.
- ✓Solid grasp of devops fundamentals
- ✓Comfortable reading and writing code examples independently
- ✓Basic understanding of production deployment concepts
Install with brew install git-lfs or apt install git-lfs. Run git lfs track '*.psd' to track PSD files. Commit the .gitattributes file. Git LFS transparently replaces tracked files with pointers.
Git stores every version of every file in the .git folder. A 10MB image modified 100 times = 1GB in .git. Git LFS is like a valet parking service for big files: you hand the keys (a text pointer) to Git, and the valet (LFS server) parks the actual car (binary file) elsewhere. When you need the car, the valet brings it back. Your garage (.git) stays small because you're only storing parking tickets (42-byte pointers), not the cars themselves.
Git is designed for text files. Every version of every file lives in .git forever. A 100MB design file modified 50 times generates 5GB of .git storage — and everyone who clones the repo downloads all 5GB. Git LFS solves this by replacing large files with text pointers and storing the actual blobs on a remote server. The trade-off: LFS files aren't in the object store, so git bisect, git log -p, and git archive may not include LFS content. This guide covers setup, the incident that broke CI with a 2GB .git folder, and how to migrate existing history to LFS.
Installing and Configuring Git LFS
Install git-lfs: brew install git-lfs (macOS) or apt install git-lfs (Linux). Run git lfs install once to configure Git. Then track file patterns: git lfs track '*.psd' creates/updates .gitattributes.
git lfs track supports glob patterns: .zip, assets//.png, .psd, .sketch. Each pattern adds a line to .gitattributes. Commit .gitattributes to share the tracking rules with your team.
Push and pull work transparently: git push uploads LFS files alongside commits. git pull downloads LFS files. git lfs pull fetches only LFS content (run after a shallow clone).
LFS files stored on GitHub LFS count toward your GitHub storage quota (1GB free, paid plans for more). Self-hosted LFS servers are available for enterprises.
git bisect, git log -p, and git archive don't include LFS content by default. Use GIT_LFS_SKIP_SMUDGE=1 to clone without downloading LFS files, then selectively fetch what you need.GIT_LFS_SKIP_SMUDGE=1 to avoid downloading LFS files unless the build needs them. For builds that need assets, use git lfs pull --include='.png' --exclude='.psd' to fetch only what's required. GitHub Actions users: actions/checkout@v4 with lfs: true handles this automatically..gitattributes. CI should use shallow clones + selective LFS smudge. Migrate existing history with git lfs migrate import.CI Clone Time Went From 2 Seconds to 15 Minutes — Blame 2GB .git
git clone --depth 1 but even depth 1 required downloading the pack files containing LFS-like blobs. 5. CI clone time went from 2 seconds to 15+ minutes. 6. Developers avoided pulling main because of the download time, leading to stale branches and merge hell.brew install git-lfs. 2. Created .gitattributes with .psd filter=lfs diff=lfs merge=lfs -text. 3. Ran git lfs migrate import --include='.psd,.sketch,.fig' --everything to rewrite history. 4. Force-pushed the cleaned history (coordinated team-wide reset). 5. Updated CI pipeline to install git-lfs and run git lfs pull only for essential assets. 6. Set LFS file size limit to 50MB per file.- Git stores every version of every binary file.
- LFS replaces binaries with text pointers.
- Install LFS BEFORE binary files enter the repo.
- Migrate existing history with
git lfs migrate import. - CI should use shallow clones + selective LFS pull.
git lfs trackgit lfs fetch --all only when needed, otherwise shallow clone + LFS smudgeKey takeaways
20+ years shipping production infrastructure and CI/CD at scale. Drawn from code that ran under real load.
That's Git. Mark it forged?
3 min read · try the examples if you haven't