Skip to content

Instantly share code, notes, and snippets.

@KrustyHack
Created January 21, 2022 15:33
Show Gist options
  • Save KrustyHack/a99c75901896a1e130a811008c9c982c to your computer and use it in GitHub Desktop.
Save KrustyHack/a99c75901896a1e130a811008c9c982c to your computer and use it in GitHub Desktop.
Removing sensitive data from a repository

Run the following command, replacing PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA with the path to the file you want to remove, not just its filename. These arguments will:

  • Force Git to process, but not check out, the entire history of every branch and tag
  • Remove the specified file, as well as any empty commits generated as a result
  • Overwrite your existing tags
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' --prune-empty --tag-name-filter cat -- --all

Once you're happy with the state of your repository, force-push your local changes to overwrite your GitHub Enterprise repository, as well as all the branches you've pushed up:

git push origin --force --all

In order to remove the sensitive file from your tagged releases, you'll also need to force-push against your Git tags:

git push origin --force --tags

Tell your collaborators to rebase, not merge, any branches they created off of your old (tainted) repository history. One merge commit could reintroduce some or all of the tainted history that you just went to the trouble of purging.

After some time has passed and you're confident that git filter-branch had no unintended side effects, you can force all objects in your local repository to be dereferenced and garbage collected with the following commands (using Git 1.8.5 or newer):

git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment