How to delete a file tracked by git-lfs and release the storage quota?

There doesn't currently appear to be a great way of removing large assets from git-lfs. GitHub's current suggestion is to use a tool called The BFG to completely strip all existence of the file from your repo.

Presumably it'll then be removed from the lfs storage when git's garbage collection is next run by GitHub.

For more info see https://help.github.com/en/github/managing-large-files/removing-files-from-git-large-file-storage

Edit 2019-11-20

GitHub have updated their documentation on this explicitly stating there is no way to free up your git-lfs storage without deleting your repository. https://help.github.com/en/github/managing-large-files/removing-files-from-git-large-file-storage

Their only recommendation is to still use the BFG tool to strip the file from your repository, which will reduce the size of your repository when cloning, but will still count towards your git-lfs quota until you delete the repository.

GitLab again suggest using the BFG tool and will automatically clean the lfs storage of any files which aren't referenced in any commits, although currently this doesn't seem to be working correctly. This issue has been open since 2017 with no resolution.

BitBucket have a section in the repository settings which you can clean up lfs files. https://www.atlassian.com/git/tutorials/git-lfs#deleting-remote-files


The answer given by Wader is not related to the question.

The given link to a github article is about large files directly checked into the git repo, which is NOT the same as git-lfs!

As for the question: how this situation is handled depends on the underlying storage server. git-lfs support can be provided by different services, e.g. GitHub oder GitLab.

GitLab stores git-lfs files not per repository. They are stored by their SHA-256 hash value. If the same file is used in several repositories (e.g clones), it is only stored once. It solely depends on GitLab how it handles referenced files and should be looked up in the manual.

According to GitHubs documentation (https://help.github.com/articles/removing-files-from-git-large-file-storage/), it is recommended to delete and recreate a repository: "To remove Git LFS objects from a repository, delete and recreate the repository. When you delete a repository, any associated issues, stars, and forks are also deleted."


The answer given by Chris is not accurate; combined with the comment from 0xcaff ("that's a terrible solution"), it may mislead the inexperient user (or distracted reader).

The right answer is a mixture of Wader's and Chris'.

I just solved a case where I wanted to mirror a repository (let's call it REPO-1) that once upon a time used LFS, but has not been history-cleaned from the large files.

At some moment in the last month I removed support for LFS in REPO-1 with git lfs uninstall. And that was working fine for subsequent git clones (i.e., no git-lfs anymore). But today when I tried to pull a previously push --mirror version of REPO-1 I got messages Smudge error: Error downloading <big-filename> ... Object does not exist on the server: [404] Object does not exist on the server

So, if you want to get rid of LFS and any reference to the once-tracked files you have to:

  1. uninstall LFS from the repo;
  2. clean the repo's history;
  3. delete (or rename) the old (github) repo, create a new one and push the cleaned repo into it.

1

To uninstall LFS is a simple command like git lfs uninstall will do it.

2

To clean the repo's history is a bit scary, but works just fine with git filter-branch, item 3 of the Github docs --https://help.github.com/en/articles/removing-sensitive-data-from-a-repository -- should be about enough:

$ git filter-branch --force --index-filter \
      "git rm --cached --ignore-unmatch FILENAME-1 FILENAME-2 FILENAME-3" \
      --prune-empty --tag-name-filter cat -- --all

3

The deletion and re-creation of the repository is not as destructive at seems like, remember that your local repository is completely independent, self-sustained clone of what's in Github. When you push the your local (clean) version to the new, blank repository it will be like that (deletion/creation) never happened.