Remove a directory permanently from git

In my personal git repo, I have a directory that contains thousands of small images that are no longer needed. Is there a way to delete them from the entire git history? I have tried

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


  • Using Git to manage two versions of a website
  • How to push/pull Git rebase
  • What's the best way to update a branch to the latest master while still keeping all the changes that were previously committed?
  • The working copy <Project name> failed to commit files. - The repository has an uncompleted operation
  • Merging changesets in git for a code review
  • Get the diff in Git for files that have been renamed and then significantly changed. This does not currently work properly for me
  • git filter-branch --tree-filter 'rm -fr imgs' HEAD

    but the size of the git repo remains unchanged. Any ideas?


  • Gitolite hook doesn't work
  • How to use git merge --squash?
  • NuGet and Git Submodules
  • Visual Studio (Microsoft ) Symbol server with git
  • git Undo auto merging on a specific file only not the whole branch
  • How to use mingw32 when installing a distutils package?
  • 6 Solutions collect form web for “Remove a directory permanently from git”

    Actually none of these techniques workedfor me.
    I found the most reliable was was to simply pull locally into another repo:

    git pull file://$(pwd)/myGitRepo

    It also saves you the hassle of deletig old tags.

    see the story on my blog:

    The ProGit book has an interesting section on Removing Object.

    It does end with this:

    Your history no longer contains a reference to that file.
    However, your reflog and a new set of refs that Git added when you did the filter-branch under .git/refs/original still do, so you have to remove them and then repack the database. You need to get rid of anything that has a pointer to those old commits before you repack:

    $ rm -Rf .git/refs/original
    $ rm -Rf .git/logs/
    $ git gc
    $ git prune --expire 

    (git prune --expire is not mandatory but can remove the directory content from the loose objects)
    Backup everything before doing those commands, just in case 😉

    git-filter-branch by default saves old refs in refs/original/* namespace.

    You need to delete them, and then do git gc --prune=now

    Brandon Thomson asked in a comment to Rainer Blome‘s solution if this just fixed the gitk view or if the refs will be really gone. A good way to check this is to remember one of the sha1 hashes (or a unique prefix of it) of the old commits and try

    $ git ls-tree hash-value

    This should show you the content of the repos main folder as it was in this commit. After

    $ rm -Rf .git/refs/original
    $ rm -Rf .git/logs/

    as shown by VonC and removing the refs/original/… lines from .git/info/refs and .git/packed-refs as shown by Rainer Blome, a final

    $ git gc --prune=now

    made not only the refs, but also the old objects (commits, trees, and blobs) go away. The above shown git ls-tree hash-value proves this.
    Another nice command to check this is git count-objects -v (run it before the filter-brach and after the pruning and compare the size).

    Note: As I’m not allowed yet to comment on the other answers, I had to write a new one although it mainly combines previous given answers.

    If you want to go the manual cleanup route, there are some more files that may also contain
    a ref to the position of your original branch before the git-filter-branch.
    For example, I filtered my “home” branch:


    179ad3e725816234a7182476825862e28752746d refs/original/refs/heads/home


    179ad3e725816234a7182476825862e28752746d refs/original/refs/heads/home

    After I removed those lines, gitk did not show the old commits any more.

    As this is an old question, perhaps some of this wasn’t possible back then. This also assumes you’re using bash or cygwin.

    Warning: The second and third lines will permanently delete all commits unreachable from your branches/tags.

    After running filter-branch, do

    for ref in $(git for-each-ref --format='%(refname)' refs/original); do git update-ref -d $ref; done
    git reflog expire --expire=now --all
    git gc --prune=now

    git for-each-ref --format='%(refname)' gets the reference names, and git update-ref -d deletes the reference. It is generally better not to modify the .git folder directly, and in particular this command handles the case when the refs are in packed-refs.

    The second and third lines are taken directly from How to clean up unused side-branches in your commit trees?.

    Git Baby is a git and github fan, let's start git clone.