I'm HOPING there is a better way to do this... BUT after redacted units of time, I found a way where you will NOT lose any history of existing large files. It is probably SLOW but it works.

DISCLAIMER I'm just a stubborn user, can't promise this will work out for you, BACKUP!

I have run into a similar situation myself, but in my case, all my large files were sitting in submodules. So I was able to remove the submodules, track files, and add them back (without the submodules, HORRAY!) This way I can say I did maintain all my history, only some of the history is in the submodules. I'm guessing this is not similar to your situation, and that everything is in one big repo.

  1. Filter-branch to convert all tracking over to lfs
git filter-branch --prune-empty --tree-filter '
git config -f .gitconfig lfs.url "http://127.0.0.1:8080/user/repo"
git lfs track "*.npy"
git add .gitattributes .gitconfig

for file in $(git ls-files | xargs git check-attr filter | grep "filter: lfs" | sed -r "s/(.*): filter: lfs/\1/"); do
  echo "Processing ${file}"

  git rm -f --cached ${file}
  echo "Adding $file lfs style"
  git add ${file}
done' --tag-name-filter cat -- --all
  • You have to use tree-filter here, and not index-filter because we are adding objects back.
  • I just added track *.npy as an example, but add all of your track commands in there. Hopefully you can use the SAME set of rules for EVERY commit
  • The .gitconfig files and git config lines are so that if you have an lfs server in a separate location than the git repo, everything works. IF you have them at the same url, you can skip that step
  1. Push changes to whatever remote or remotes you have, of course you have to use the -f option, which can (and WILL!) have many implications to all the other users using the repo. Make sure no one else pushes or references the commits you just rebased, or else you will have a mess. This is when all the large files are sent to the lfs server.
git push -f origin master

(Optional) Collect garbage to shrink currently checked out repo

rm .git/refs/original -rf
git -c gc.reflogExpireUnreachable=0 -c gc.pruneExpire=now gc
  • The rm command remove a "backup copy" of the the original refs before the filter-branch command, just to CYA. but when you are done with them, WIPE EM!
  • If this doesn't do enough gc, check out http://stackoverflow.com/a/14728706

(Optional) Collect garbage on a bare repo (on the remotes)

git -c gc.reflogExpireUnreachable=0 -c gc.pruneExpire=now gc

I hope this helps!

Untested ideas
Instead Step 1, just add

git lfs track "*.foo"
git config -f .gitconfig lfs.url "http://127.0.0.1:8080/user/repo"
git add .gitattributes .gitconfig

inside the for loop on step two. It should save that wasted initial rebase, and prevent the need for the git add .

Tested using git-lfs 0.5.1 and git 1.9.4.msysgit.1 (Yes, on windows 64 bit)