2/24/2016 - 9:31 PM

Remove sensitive data From:

  1. Clone the GitHub gem repository.
$ git clone
  1. Navigate to the repository's working directory.
$ cd github-gem
  1. Run git filter-branch, forcing (--force) Git to process—but not check out (--index-filter)—the entire history of every branch and tag (--tag-name-filter cat -- --all), removing the specified file ('git rm --cached --ignore-unmatch Rakefile') and any empty commits generated as a result (--prune-empty). Note that you need to specify the path to the file you want to remove, not just its filename.

Be careful! This will overwrite your existing tags.

$ git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch Rakefile' \
--prune-empty --tag-name-filter cat -- --all

If the file used to exist at any other paths (because it was moved or renamed), you must run this command on those paths, as well.

  1. Add the Rakefile to .gitignore to ensure that you don't accidentally commit it again.
$ echo "Rakefile" >> .gitignore
$ git add .gitignore
$ git commit -m "Add Rakefile to .gitignore"
  1. Double-check that you've removed everything you wanted to from your repository's history, and that all of your branches are checked out.

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

$ git push origin --force --all
  1. 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
  1. 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.

  2. 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

Note that you can also achieve this by pushing your filtered history to a new or empty repository and then making a fresh clone from GitHub.