Created
May 31, 2025 13:09
-
-
Save madebycm/9ec594e71dfb5e155970625873e7dd69 to your computer and use it in GitHub Desktop.
Permanently shred all traces of a file in git
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # @author madebycm (2025-05-31) | |
| # File to be completely destroyed from Git history | |
| TARGET_FILE="README.md" | |
| echo "⚠️ WARNING: This will completely remove $TARGET_FILE from ALL Git history!" | |
| echo "This action CANNOT be undone and will require force-pushing." | |
| echo "" | |
| read -p "Are you absolutely sure? Type 'YES' to continue: " confirmation | |
| if [ "$confirmation" != "YES" ]; then | |
| echo "Aborted." | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "Starting complete removal of $TARGET_FILE from Git history..." | |
| # Create a backup tag before we start (just in case) | |
| git tag backup-before-destroy-$(date +%Y%m%d-%H%M%S) | |
| # Method 1: Using git filter-branch (traditional method) | |
| echo "Step 1: Running git filter-branch..." | |
| FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --force --index-filter \ | |
| "git rm --cached --ignore-unmatch $TARGET_FILE" \ | |
| --prune-empty --tag-name-filter cat -- --all | |
| # Method 2: Using BFG Repo-Cleaner alternative (git filter-repo) | |
| # This is more thorough and faster | |
| if command -v git-filter-repo &> /dev/null; then | |
| echo "Step 2: Running git-filter-repo for thorough removal..." | |
| git filter-repo --path $TARGET_FILE --invert-paths --force | |
| else | |
| echo "Step 2: git-filter-repo not found, using additional filter-branch pass..." | |
| FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --force --tree-filter \ | |
| "rm -f $TARGET_FILE" \ | |
| --prune-empty --tag-name-filter cat -- --all | |
| fi | |
| # Clean up refs | |
| echo "Step 3: Cleaning up references..." | |
| rm -rf .git/refs/original/ | |
| git reflog expire --expire=now --all | |
| git gc --prune=now --aggressive | |
| # Remove the file from working directory if it still exists | |
| if [ -f "$TARGET_FILE" ]; then | |
| echo "Step 4: Removing $TARGET_FILE from working directory..." | |
| rm -f "$TARGET_FILE" | |
| fi | |
| echo "" | |
| echo "✅ Local removal complete!" | |
| echo "" | |
| echo "⚠️ IMPORTANT: To remove from GitHub, you MUST now run:" | |
| echo " git push origin --force --all" | |
| echo " git push origin --force --tags" | |
| echo "" | |
| echo "⚠️ WARNING: This will rewrite history for all collaborators!" | |
| echo "" | |
| echo "After pushing, also consider:" | |
| echo "1. Contact GitHub support to purge cached views" | |
| echo "2. Ensure all collaborators delete and re-clone the repository" | |
| echo "3. Check GitHub's 'Commits' page to verify removal" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment