This post is a copy from a thread on stackoverflow
It was found that the --tree-filter
option used in other answers can be very slow, especially on larger repositories with lots of commits.
Here is the method that one can use to completely remove a directory from the git history using the --index-filter
option, which runs much quicker:
- Make a fresh clone of YOUR_REPO
git clone YOUR_REPO cd YOUR_REPO
- Create tracking branches of all branches
for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done
- Remove DIRECTORY_NAME from all commits, then remove the refs to the old commits (repeat these two commands for as many directories that you want to remove)
git filter-branch --index-filter 'git rm -rf --quiet --cached --ignore-unmatch DIRECTORY_NAME/' --prune-empty --tag-name-filter cat -- --all git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
- Ensure all old refs are fully removed
rm -Rf .git/logs .git/refs/original
- Perform a garbage collection to remove commits with no refs
git gc --prune=all --aggressive
- Force push all branches to overwrite their history (use with caution!)
git push origin --all --force git push origin --tags --force
You can check the size of the repository before and after the gc with:
git count-objects -vH