Git: How to remove file from historical commit?

You will need to git rebase in the interactive mode see an example here: How can I remove a commit on GitHub? and how to remove old commits.

If your commit is at HEAD minus 10 commits:

$ git rebase -i HEAD~10

After the edition of your history, you need to push the "new" history, you need to add the + to force (see the refspec in the push options):

$ git push origin +master

If other people have already cloned your repository, you will to inform them, because you just changed the history.


I tried using the following answer on windows https://stackoverflow.com/a/8741530/8461756

Single quote does not work on windows; you need double-quotes.

Following worked for me.

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PathRelativeRepositoryRoot/bigfile.csv" -- --all

After removing the big file, I was able to push my changes to GitHub master.


You can use git-extras tool. The obliterate command completely remove a file from the repository, including past commits and tags.

https://github.com/tj/git-extras/blob/master/Commands.md


Chapter 9 of the Pro Git book has a section on Removing Objects.

Let me outline the steps briefly here:

git filter-branch --index-filter \
    'git rm --cached --ignore-unmatch path/to/mylarge_50mb_file' \
    --tag-name-filter cat -- --all

Like the rebasing option described before, filter-branch is rewriting operation. If you have published history, you'll have to --force push the new refs.

The filter-branch approach is considerably more powerful than the rebase approach, since it

  • allows you to work on all branches/refs at once,
  • renames any tags on the fly
  • operates cleanly even if there have been several merge commits since the addition of the file
  • operates cleanly even if the file was (re)added/removed several times in the history of (a) branch(es)
  • doesn't create new, unrelated commits, but rather copies them while modifying the trees associated with them. This means that stuff like signed commits, commit notes etc. are preserved

filter-branch keeps backups too, so the size of the repo won't decrease immediately unless you expire the reflogs and garbage collect:

rm -Rf .git/refs/original       # careful
git gc --aggressive --prune=now # danger

Tags:

Git