Git LFS

Git Large File Storage

Git stores every version of every file as a blob. For large binary files — images, videos, datasets, compiled assets — this causes the repository to grow quickly. Cloning becomes slow, and every developer downloads the full history of every large file whether they need it or not.

Git LFS (Large File Storage) solves this by replacing large files with small pointer files in the repository. The actual file content is stored on a separate LFS server. Git downloads large files only when you check out a commit that needs them.

How it works

Without LFS:
  .git/objects/ contains every version of every large file
  repo size grows with each commit that touches a large file

With LFS:
  .git/objects/ contains small pointer files (~130 bytes each)
  large file content lives on the LFS server
  Git downloads only the versions you check out

A pointer file looks like this:

version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345678

Git LFS intercepts push, pull, and checkout to upload and download the real content transparently.

Setup

Install Git LFS (once per machine):

$ git lfs install
Updated git hooks.
Git LFS initialized.

This adds LFS hooks to your global Git configuration. The hooks intercept Git operations to handle large files automatically.

Track files by pattern

Tell LFS which files to manage using glob patterns:

$ git lfs track "*.psd"
$ git lfs track "*.zip"
$ git lfs track "assets/videos/**"

Each track command adds a line to .gitattributes:

$ cat .gitattributes
*.psd filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
assets/videos/** filter=lfs diff=lfs merge=lfs -text

Commit .gitattributes so other developers get the same LFS rules:

$ git add .gitattributes
$ git commit -m "Track large files with LFS"

Common operations

Push

LFS uploads tracked files to the LFS server automatically during git push:

$ git push origin main
Uploading LFS objects: 100% (3/3), 45 MB | 2.1 MB/s, done.

Pull and fetch

git pull downloads LFS files for the current checkout. To download LFS content without merging:

$ git lfs fetch              # download LFS objects for current ref
$ git lfs fetch --all        # download LFS objects for all refs
$ git lfs pull               # fetch + checkout (update working tree)

Check tracked files

$ git lfs ls-files           # list all LFS-tracked files in the repo
$ git lfs status             # show pending LFS uploads

Migrate existing files to LFS

If large files are already in the repository history, use migrate to rewrite history and move them to LFS:

# Migrate all .zip files in the entire history
$ git lfs migrate import --include="*.zip" --everything

# Migrate only in the current branch
$ git lfs migrate import --include="*.zip"

This rewrites commits, so coordinate with your team and force-push afterward.

Hosting support

HostFree LFS storageFree bandwidth/month
GitHub1 GB1 GB
GitLab5 GB (project)Unlimited (self-managed)
Bitbucket1 GB5 GB

All three hosts offer paid plans for additional storage and bandwidth. Self-hosted GitLab and Bitbucket have configurable limits.

Gotchas

On this page