119

Possible Duplicate:
How to purge a huge file from commits history in Git?

I did a stupid thing. Imagine that I committed a 100MB file. Then I see this and delete this file and commit again. This is a normal procedure to delete a file.

But now the side effect is that my history is heavy because it's saved this large file (I believe this is why it is heavy). I am only using local git, so I do not synchronize in any server.

How can I definitively remove this file and save disk space?

Jiaxiang
  • 865
  • 12
  • 23
Rodrigo
  • 11,909
  • 23
  • 68
  • 101
  • 1
    See accepted answer for my question http://stackoverflow.com/questions/7969831/drop-old-commit-git-rebase-causes-merge-conflicts – Daniel Böhmer Nov 10 '11 at 16:59
  • Use the BFG repo-cleaner, a simpler, faster alternative to `git-filter-branch` specifically created by me for removing unwanted files from Git history. See http://stackoverflow.com/a/17890278/438886 – Roberto Tyley Jul 26 '14 at 21:14

3 Answers3

234

You can do it using the git filter-branch command, like this :

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" HEAD

You can find more documentation here http://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository

matt
  • 515,959
  • 87
  • 875
  • 1,141
Leo
  • 5,069
  • 2
  • 20
  • 27
  • 4
    Note that it will also delete the currently checked out version, so make sure you have a backup if you need to keep it. – rleelr Oct 06 '16 at 14:37
  • 11
    I'm using Windows. I had to swap the single quotes for double quotes. – Colonel Panic Oct 12 '16 at 14:33
  • 2
    @rleelr I think github page gives a clean solution without affecting the other files: https://help.github.com/articles/removing-sensitive-data-from-a-repository/ – MeadowMuffins Jun 29 '17 at 10:27
  • 9
    I have this error: `Cannot rewrite branches: You have unstaged changes.` – capybaralet Oct 13 '17 at 22:10
  • I'm not a master in git, so for example I do this on a branch other than master. What happens to the same file which exists on master? Does it automatically get removed from the history of master as well or stays intact as long as I don't merge the branch where I deleted history into the master? – Souvik Ghosh Oct 17 '17 at 18:35
  • If you run this locally, and then push, it will affect the remote server? – Alexander Mills Jul 05 '18 at 05:33
  • 1
    @AlexanderMills yes, just don't forget to push using `--force`, as in `git push origin master --force` for example. – Leo Jul 06 '18 at 13:57
  • 1
    I am not sure if `--force` is necessary – Alexander Mills Jul 06 '18 at 20:53
  • 1
    A useful thing to note: This runs per branch only, and will be sped up hugely by specifying a commit range (eg b42f36Bdc..HEAD) that you know contains the file. – Jethro Dec 19 '18 at 08:27
  • 1
    I've locked myself out: the file in question is so big that it fails to push, so `git push origin master --force` is doomed, and without it I get `Cannot rewrite branches: You have unstaged changes` on the `filter-branch` command. Can I delete a commit that it not yet pushed other than rolling it back? – Cee McSharpface Aug 06 '19 at 17:44
  • 1
    @dlatikay if you didn't push the commit containing the big file yet, you can use `git rebase --interactive` to remove entirely that commit *before* pushing. – Leo Aug 07 '19 at 18:13
  • 1
    A miracle cure for the mp4 that didn't want to go away. – mLstudent33 Nov 20 '19 at 22:25
  • 6
    1. `git filter-branch --tree-filter 'rm -rf path/to/your/file' HEAD` 2. IF have this error: Cannot rewrite branches: You have unstaged changes. 3. `git stash save` 4. `git push origin master --force` – tree em Nov 24 '19 at 06:19
  • 1
    This is an annoying fix. You will get all commits in your entire repository in a pull request. – coderboi May 28 '21 at 22:57
  • @coderboi Yes, you're effectively rewriting your whole history, depending on when said file was added. – Leo May 31 '21 at 12:56
27

The command you are looking for is filter-branch. It allows you to permanently remove files from an enlistment. This blog has a great tutorial on how to remove problematic files from the repository

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
21

You can take this great script from David Underhill to remove the file from the git repository:

#!/bin/bash
set -o errexit

# Author: David Underhill
# Script to permanently delete files/folders from your git repository.  To use 
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2

if [ $# -eq 0 ]; then
    exit 0
fi

# make sure we're at the root of git repo
if [ ! -d .git ]; then
    echo "Error: must run this script from the root of a git repository"
    exit 1
fi

# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD

# remove the temporary history git-filter-branch otherwise leaves behind for a long time
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune
topek
  • 18,609
  • 3
  • 35
  • 43