Git LFS (Large File Storage) is a Git extension that replaces large files in your Git repository with small text pointers, while storing the file contents on a remote server. This keeps your Git repository lean and fast.

Let’s imagine you’re working on a game development project. You’ve got massive texture files, high-resolution audio assets, and large 3D models. If you commit these directly to Git, your repository will quickly balloon in size. Cloning and fetching will become agonizingly slow, and you might even hit Git’s practical file size limits.

This is where Git LFS comes in. Instead of storing the actual large file, Git LFS stores a small pointer file. This pointer contains information like the file’s SHA-256 checksum and its size. When you check out a commit that uses LFS, Git LFS downloads the actual file content from a separate LFS server.

Here’s how it works in practice.

First, you need to install Git LFS. On macOS, you can brew install git-lfs. On Debian/Ubuntu, it’s sudo apt-get install git-lfs. After installation, run git lfs install to set up Git hooks.

Next, you tell Git LFS which file types to track. For example, to track all .psd (Photoshop) and .wav files:

git lfs track "*.psd"
git lfs track "*.wav"

This creates or updates a .gitattributes file in your repository. This file is crucial because it tells Git which files should be handled by LFS. It will look something like this:

*.psd filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text

Now, add and commit .gitattributes like any other file:

git add .gitattributes
git commit -m "Configure Git LFS for PSD and WAV files"

From this point on, any .psd or .wav files you add, modify, or delete will be managed by LFS. For instance, if you add a large texture:

# Assume large_texture.psd is > 100MB
git add large_texture.psd
git commit -m "Add large texture asset"

When you push this commit, Git LFS will upload large_texture.psd to your LFS server (which is often provided by your Git hosting service like GitHub, GitLab, or Bitbucket) and commit the pointer file to your main Git repository.

The magic happens during checkout. When you or a collaborator clones or checks out a branch containing LFS files, Git LFS intercepts the process. It sees the pointer file and automatically downloads the actual file content from the LFS server.

To verify what’s being tracked, you can use git lfs ls-files. This command lists all files in the current commit that are managed by LFS.

git lfs ls-files

Output might look like:

large_texture.psd (0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef)
background_music.wav (fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210)

If you need to retrieve a specific LFS file that might have been downloaded but you want to ensure it’s there, you can use git lfs pull.

When you’re working with a team, it’s essential that everyone has Git LFS installed and configured. Otherwise, they’ll just see the small pointer files in their working directory, not the actual large assets.

The most surprising thing about Git LFS is how seamlessly it integrates into the Git workflow once set up. It feels like Git itself is handling the large files, abstracting away the complexity of separate storage. You don’t typically interact with the LFS server directly; Git commands like add, commit, push, pull, and checkout work as expected, with LFS operating in the background via Git hooks.

One common point of confusion is how to remove a large file from LFS and the repository history. Simply deleting the file and committing won’t remove it from past commits or the LFS server. You’ll likely need to use tools like git filter-repo or the BFG Repo-Cleaner to rewrite history, which is a more advanced operation. For current work, just stop tracking it in .gitattributes and commit that change, then add the file as a regular file if needed.

After you’ve got LFS set up and are pushing, the next thing you’ll encounter is managing LFS storage quotas provided by your Git host.

Want structured learning?

Take the full Git course →