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


I know deleting the repo isn't the best option and I can't believe that this is the solution recommended by GitHub in 2022. As pointed out in GitHub documentation:

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. For more information, see "Deleting a repository." If you need to purge a removed object and you are unable to delete the repository, please contact support for help.

If your problem is only the issues created in your original repository you could migrate them to the new recreated repo before deleting the original, as pointed in this post.

The GitHub UI lets you migrate single issues like so:

gh issue transfer <issue ID> <destination repo>

But that would take hours if some of the repos had over a hundred issues (also my case). Combining it with a few shell pipes let us to:

gh issue list -s all -L 500 --json number | \
    jq -r '.[] | .number' | \
    xargs -I% gh issue transfer % https://github.com/<destination repo>

All this will do is grab the last 500 issues from the original repo and transfer them to yours new <destination repo>. If you have to transfer more than 500 issues increase this value or just run it multiple times. Paid attention because the command must be executed in the correct original repo directory.

So far so good, after that you could purge the original repo and remove LFS storage from GitHub.

Be careful and remember that when you delete a repository stars and forks are also deleted, it wasn't my case but could be yours. If so, search for complementary solutions before blindly removing your repo.


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.


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."