【Git】git-filter-branch

1.命令使用场景###

①Removing sensitive data from a repository(https://help.github.com/en/github/authenticating-to-github/removing-sensitive-data-from-a-repository)
②使用git filter-branch删除没有使用的大文件(https://blog.csdn.net/weixin_34392435/article/details/92166474)
③Git 永久删除文件(https://git-scm.com/docs/git-filter-branch)

2.要删除的文件是TestImagesForNSFW.rtf,运行如下命令:###

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch /images/TestImagesForNSFW.rtf" --prune-empty --tag-name-filter cat -- --all

3.命令各参数简介###

filter-branch 是让git重写每一个分支;
--force 假如遇到冲突也让git强制执行;
--index-filter 选项指定重写的时候应该执行什么命令,要执行的命令紧跟在它的后面,在这里就是git rm --cached --ignore-unmatch /images/TestImagesForNSFW.rtf,让git删除掉缓存的文件,如果有匹配的话。
--prune-empty 选项告诉git,如果因为重写导致某些commit变成了空(比如修改的文件全部被删除),那么忽略掉这个commit。
--tag-name-filter 表示对每一个tag如何重命名,重命名的命令紧跟在后面,当前的tag名会从标注输入送给后面的命令,用cat就表示保持tag名不变。
紧跟着的-- 表示分割符,
最后的--all 表示对所有的文件都考虑在内。

4.预防措施###

为了防止再次不小心将敏感数据提交,可以修改.gitignore文件的内容,凡是成功匹配的文件都不会被git看到,比如在本例中可以在.gitignore后面追加一行”/images/TestImagesForNSFW.rtf”

5.如果commit已经同步到了github,那么再运行如下命令永久删除远端上的文件。###

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

6.回收内存###

git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now