You are located in service: Software Engineering Services (GitLab)




First things first, install git 1.8.2 or newer and then install git-lfs

Create a new repo

git init . echo Hello World > git add git commit -m "Initial commit"

Let's create some more files

ls > foo.txt ls > bar.txt

And add them to git

git add foo.txt bar.txt

You should already have git-lfs installed. To ensure that git-lfs is setup correctly in your git configuration files use the git lfs install command:

git lfs install

Now let's add some large files to be tracked by git-lfs:

dd if=/dev/urandom of=cat.bin bs=1048576 count=1 dd if=/dev/urandom of=dog.bin bs=1048576 count=1

Now we are going ensure that git-lfs is tracking the large *.bin files we just created. Tracking means that in subsequent commits, these files will now be LFS files.

Note: This does NOT mean that versions of the files in previous commits will be converted. That involves a process commonly known as "rewriting history" and is described in the migration section.

We do this by setting a track pattern, using the git lfs track command.

git lfs track '*.bin'

This tells git-lfs to track all files matching the *.bin pattern. The quotes around the *.bin are there to prevent the shell from expanding *.bin, else you would end up only tracking cat.bin dog.bin, and no other bin in the future.

To see a list of all patterns currently being tracked by git-lfs, run git lfs track with no arguments

Listing tracked paths *.bin (.gitattributes)

To see the list of files being tracked by git-lfs, run git lfs ls-files. You will see that this list is currently empty. This is because technically the file isn't an lfs object until after you commit it.

Next, you need to add .gitattributes to your git repository. git lfs track stores the tracked files patterns in .gitattributes. This way when the repo is cloned, the tracked file patterns are preserved.

git add .gitattributes

We can also add the *.bin files now that they are tracked via git-lfs.

git add "*.bin"

Now git status should look like this.

On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: .gitattributes new file: bar.txt new file: cat.bin new file: dog.bin new file: foo.txt

Finally, commit the new files

git commit -m "Add files"

Now, when you run git lfs ls-files, you will see the list of tracked files

f05131d24d * cat.bin 7db207c488 * dog.bin


Adding git-lfs to a pre-existing repo

Let's create pretend repo to understand how converting to git-lfs works

git init . touch git add git commit -m "initial" git tag one echo hi > plain.txt ls > foo.bin git add plain.txt foo.bin git commit -m "Add some files" git tag two echo bye > plain.txt ls > bar.bin ls > foo.bin git add plain.txt foo.bin bar.bin git commit -m "Update and add another file" git tag three echo bye >> plain.txt ls > foo.bin git add plain.txt foo.bin git commit -m "Update some more" git tag four

Now lets decide we want *.bin files to be turned into lfs objects.

git lfs track '*.bin' git add .gitattributes git commit -m "Track .bin files" git tag not_working

Just tracking files does NOT convert them to lfs. They are part of history already, the only way to convert old files is to rewrite history (see the section about migrating existing data).

Next we can try converting the latest version of history only to LFS. Since *.bin are currently tracked, we just need to add the files back after removing them. We will remove it from git without deleting the file (aka remove cache), and then add it back

git rm --cached *.bin git add *.bin git commit -m "Convert last commit to LFS"

Now, git lfs ls-files shows:

4665a5ea42 * bar.bin 4665a5ea42 * foo.bin

We can also see that the foo.bin is an lfs file by git show HEAD:foo.bin

version oid sha256:4665a5ea423c2713d436b5ee50593a9640e0018c1550b5a0002f74190d6caea8 size 36

But when we look at the previous histories, we see that they are still not LFS tracked. git show not_working:foo.bin

bar.bin foo.bin plain.txt

It's important to understand that tracking an LFS file does not remove it from a previous version of history. If you create a repo without LFS before, and put hundreds of MB in there, after all these steps, the old version still has all the large files in git, not in LFS.


Migrating existing repository data to LFS

Sometimes files end up committed within your repository when they should have been committed with LFS. This can be accidental, or can come up when converting an existing Git repository to use Git LFS. To make this possible, Git LFS ships with a git lfs migrate command that allows for such migrations:

Using git lfs migrate

Install Git LFS v2.2.1 (or later)

  • Rewrite e.g. all *.mp4 video files on the current branch that are not present on a remote:

    git lfs migrate import --include="*.mp4"

  • Alternatively, rewrite all *.mp4 video files on a given branch(es) regardless of whether they are present on a remote (may require a force-push):

    git lfs migrate import --include="*.mp4" --include-ref=refs/heads/master --include-ref=refs/heads/my-feature

  • Push the converted repository as a new repository:

    git push

Cleaning up the .git directory after migrating

The above successfully converts pre-existing git objects to lfs objects. However, the regular objects still persist in the .git directory. These will be cleaned up eventually by git, but to clean them up right away, run:

git reflog expire --expire-unreachable=now --all git gc --prune=now