Skip to content

Instantly share code, notes, and snippets.

@maxiboch
Last active October 28, 2022 14:56
Show Gist options
  • Save maxiboch/4760e3bc8b1d6a683702fef3750e27c1 to your computer and use it in GitHub Desktop.
Save maxiboch/4760e3bc8b1d6a683702fef3750e27c1 to your computer and use it in GitHub Desktop.
git-lfs Migration Cheatsheet
Guide to Fixing LFS Tracking on Repos
Prereqs:
git version >= 2.3
git-lfs version >= 2.3
OSX: homebrew
OSX: coreutils - once you have homebrew installed, run > brew install coreutils
(note to self: use the fastest way, see bottom-ish of doc!)
INVESTIGATION
As a basic first step, you can run:
> git lfs migrate info --everything
which will give a list of the top 5 file types that are taking up space in the repo.
The "--everything" means it will look across all branches.
for even more info:
git lfs migrate info --everything --top=25
This will give an additional 25 file types
If you want to get a sense of the actualy files that are taking up space,
this command will get you a list of the biggest files in the repo.
It can be very useful for finding extension-less files, like those
inside .app files on OSX, etc.:
> git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| sed -n 's/^blob //p' \
| sort --numeric-sort --key=2 \
| cut -c 1-12,41- \
| $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
and this one will filter that list against files already tracked in lfs, so you only see the non-tracked files:
> git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| sed -n 's/^blob //p' \
| grep -vF --file=<(git lfs ls-files -a | awk '{print $3}') \
| sort --numeric-sort --key=2 \
| cut -c 1-12,41- \
| $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
MIGRATION
If you already had a .gitattributes file in your repo from the first commit, and it has all the types you want to lfs, you can run
> git lfs migrate import --everything --fixup
and that should move all those files to LFS
If your .gitattributes wasn't started with the repo, or doesn't include all the types you want, you can start running one-off commands:
> git lfs migrate info --everything --include="*.psd"
this will preview the migration
> git lfs migrate import --everything --include="*.psd"
this will actually run it
Note that you can do multiple files types at the same time
> git lfs migrate import --everything --include="*.psd,*.bmp"
Remember you can omit --everything if you're only trying to clean up a single branch
Look here to see if there have been any updates to make it possible to specifiy the .gitattributes file you want to use
when calling lfs migrate: https://github.com/git-lfs/git-lfs/issues/3442
FASTEST WAY BUT SCARY
If you're feeling ambitious, you could try putting the .gitattributes in the first commit by rewriting history.
For this to work, you need a .gitattributes in your git repo that has all the lfs types you want spec'd.
Then it's just a matter of re-writing the first commit (and therefore the whole tree), placing the .gitattributes file in
the first commit:
> git filter-branch --index-filter 'cd ../..;git update-index --add .gitattributes;cd -' -- --all
Then running fixup across all the branches
> git lfs migrate import --everything
FLOW
Usually, if I don't have a .gitattributes set up already, I would end up running something like:
> git lfs migrate info --everything --include="*.psd,*.bpm...etc"
> git lfs migrate import --everything --include="*.psd,*.bpm...etc"
> git gc
over and over until it's reporting as expected.
For a Unity project, I expect something like:
*.meta 34 MB 27869/27869 files(s) 100%
*.mat 20 MB 8461/8461 files(s) 100%
*.cs 18 MB 1869/1872 files(s) 100%
*.html 1.4 MB 39/39 files(s) 100%
*.shader 1.4 MB 311/311 files(s) 100%
FINAL STEPS
Run garbage collector locally:
> git gc
Run this command to push all those changes to the remote repo
> git push --all -f
You can omit --all if you are only working on one branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment