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
git filter-branch --tree-filter 'rm -fr imgs' HEAD
but the size of the git repo remains unchanged. Any ideas?
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.
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.
reflogand a new set of refs that Git added when you did the
.git/refs/originalstill 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
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/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:
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.
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
The second and third lines are taken directly from How to clean up unused side-branches in your commit trees?.