Introduction
Git is optimized for text files — source code, configs, YAML playbooks. When you push large binary files (ISOs, VM images, datasets, compiled artifacts), you'll hit the pack exceeds maximum allowed size error. Git Large File Storage (LFS) solves this by storing large files on a separate server while keeping lightweight pointers in your repo.
The Error
$ git push origin main
remote: error: pack exceeds maximum allowed size (100 MB)
fatal: the remote end hung up unexpectedly
This happens when:
- A single file exceeds the platform's size limit (GitHub: 100MB, GitLab: varies)
- The cumulative pack file is too large
- Large binary files were committed to history
Quick Fix: Git LFS
Install Git LFS
# macOS
brew install git-lfs
# Ubuntu/Debian
sudo apt install git-lfs
# RHEL/Fedora
sudo dnf install git-lfs
# Windows
# Included with Git for Windows, or:
choco install git-lfs
Initialize in Your Repo
cd my-repo
git lfs install
# Updated git hooks. Git LFS initialized.
Track Large Files
# Track specific file types
git lfs track "*.iso"
git lfs track "*.tar.gz"
git lfs track "*.zip"
git lfs track "*.vmdk"
git lfs track "*.qcow2"
# Track specific files
git lfs track "data/training-set.csv"
# Commit the .gitattributes file
git add .gitattributes
git commit -m "Configure Git LFS tracking"
Verify Tracking
git lfs track
# Listing tracked patterns
# *.iso (.gitattributes)
# *.tar.gz (.gitattributes)
git lfs ls-files
# a1b2c3d4e5 * data/large-dataset.csv
# f6g7h8i9j0 * images/vm-image.vmdk
Understanding .gitattributes
# .gitattributes
*.iso filter=lfs diff=lfs merge=lfs -text
*.tar.gz filter=lfs diff=lfs merge=lfs -text
*.vmdk filter=lfs diff=lfs merge=lfs -text
*.qcow2 filter=lfs diff=lfs merge=lfs -text
data/*.csv filter=lfs diff=lfs merge=lfs -text
File Types to Track with LFS
| Category | Extensions | Typical Size |
|---|---|---|
| VM images | .vmdk, .qcow2, .vdi, .ova | 1-50 GB |
| Archives | .iso, .tar.gz, .zip, .7z | 100 MB - 10 GB |
| Datasets | .csv, .parquet, .h5 | 100 MB - 5 GB |
| Media | .mp4, .mov, .wav | 50 MB - 5 GB |
| Compiled | .jar, .war, .whl | 10 MB - 500 MB |
| ML models | .pt, .onnx, .pb, .safetensors | 100 MB - 50 GB |
Migrate Existing Repo to LFS
If large files are already in your Git history:
# Migrate existing tracked files to LFS
git lfs migrate import --include="*.iso,*.tar.gz,*.vmdk" --everything
# This rewrites history — force push required
git push --force origin main
Warning:
migrate importrewrites Git history. Coordinate with your team before running this.
Migrate a Single File
git lfs migrate import --include="path/to/large-file.bin" --everything
Alternative: Remove Large Files from History
If you don't want LFS, remove the large files entirely:
# Using git-filter-repo (recommended over filter-branch)
pip install git-filter-repo
# Remove a specific file from all history
git filter-repo --path path/to/large-file.iso --invert-paths
# Remove all files larger than 50MB from history
git filter-repo --strip-blobs-bigger-than 50M
Prevent Future Issues
Pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-added-large-files
args: ['--maxkb=10000'] # 10MB limit
Git Config
# Warn about large files
git config --global core.bigFileThreshold 50m
.gitignore
# Don't track these at all
*.iso
*.vmdk
*.ova
build/
dist/
*.egg-info/
LFS with Ansible Projects
Common large files in Ansible repos:
# Track large Ansible artifacts
git lfs track "*.rpm"
git lfs track "*.deb"
git lfs track "files/*.tar.gz"
git lfs track "files/*.zip"
Platform LFS Limits
| Platform | Free LFS Storage | Free Bandwidth | Paid Plans |
|---|---|---|---|
| GitHub | 1 GB | 1 GB/month | $5/50GB pack |
| GitLab | 5 GB (SaaS) | Unlimited | Per plan |
| Bitbucket | 1 GB | 5 GB/month | Per plan |
Troubleshooting
"Smudge filter lfs failed"
# Re-install LFS hooks
git lfs install
git lfs pull
LFS Files Show as Pointers
# Download actual content
git lfs fetch --all
git lfs checkout
Check LFS Status
git lfs status
git lfs env
Related Articles
Conclusion
Install Git LFS with git lfs install, track large files with git lfs track "*.iso", commit .gitattributes, and push normally. For existing repos, use git lfs migrate import to move large files out of Git history. Use .gitignore for files that shouldn't be tracked at all, and pre-commit hooks to prevent accidentally committing large files. Keep your Git repos lean — track code in Git, store artifacts in LFS or an artifact registry.