In the process of using GitHub, if sensitive information is accidentally committed to a public repository during a code submission.
If it is discovered in time and the local submission has not been pushed to the GitHub remote repository, this situation can be easily handled by directly modifying the code and using git commit --amend
.
However, if it is discovered that it has already been pushed to the GitHub remote repository, or if a long time has passed and there have been many new commits, this situation will be more complicated.
Step 1:
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch path/to/file/you/want/to/delete" --prune-empty --tag-name-filter cat -- --all
For example:
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch ./picgo/20220418121957.png' --prune-empty --tag-name-filter cat -- --all
- --force: Force the execution of the operation, even if some commits will be lost.
- --index-filter: Modify the history by manipulating the index. The command 'git rm --cached --ignore-unmatch ./picgo/20220418121957.png' indicates the specific command to be executed, which is to remove the file corresponding to the specified path.
- --prune-empty: Remove empty commits during the process.
- --tag-name-filter: Manipulate tags, 'cat' means to keep the tag names unchanged.
- -- --all: Apply the command to all branches and tags.
Step 2:
Force push all branches and tags
git push origin --force --all
git push origin --force --tags
Step 3:
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin # Delete each reference in the refs/original reference
git reflog expire --expire=now --all # Clean up the reflog of all references (branches, tags, etc.). The reflog records the history of reference movements, resets, etc.
git gc --prune=now # Used for garbage collection, i.e., cleaning up unnecessary objects