Skip to content

Instantly share code, notes, and snippets.

@fschiettecatte
Last active September 23, 2023 03:11
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fschiettecatte/ab18e4d738d32b2acc9f34a7b563d4f6 to your computer and use it in GitHub Desktop.
Save fschiettecatte/ab18e4d738d32b2acc9f34a7b563d4f6 to your computer and use it in GitHub Desktop.
Removing all traces of a file from a GIT repository

Removing all traces of a file from a GIT repository

I recently had to remove all traces of a file from a GIT repository.

First clone the repository:

git clone ssh://francois@somehost.com/home/repositories/codebase codebase

Then change directory to the top level of the clone:

cd ./codebase

Remove the file using filter-branch:

git filter-branch --prune-empty -f --index-filter \
    'git rm -f --cached --ignore-unmatch tools/java/foo.jar' \
    --tag-name-filter cat -- --all

You can also remove entire directories (note that 'rm -f' changes to 'rm -rf'):

git filter-branch --prune-empty -f --index-filter \
    'git rm -rf --cached --ignore-unmatch tools/java/' \
    --tag-name-filter cat -- --all

Then update the references:

git for-each-ref --format='delete %(refname)' refs/original \
    | git update-ref --stdin

The --stdin parameter is not supported in git 1.x, so you would use:

git for-each-ref --format='delete %(refname)' refs/original \
    | xargs --verbose --max-lines=1 git update-ref

Expire the reference log:

git reflog expire --expire=now --all

Collect garbage and prune:

git gc --prune=now

Push the update and the tags:

git push --force --all
git push --force --tags

Finally you will need to collect garbage and prune the repository itself:

cd /home/repositories/codebase

git gc --prune=now

Matthias Sohn has a very useful script git-big-objects.sh to show n largest objects in a git repo's pack files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment