初次使用 git 的“核弹级选项”:filter-branch 从仓库中删除文件

当初看 Pro Git 时就被作者这个“核弹级选项”的称呼吓到了,因此一直没敢好奇地去尝试。核弹啊,用对了威力无穷,用错了破坏力无穷!

但是,今天,我不得不用了,因为我想把我的原来写一些代码放到 github 上去公开。由于之前没想过要公开,到上传时才发现不能上传大于50M的文件。

折腾了半天,还是无法上传,于是,整个命令出来了:

 git filter-branch --tree-filter 'rm -rf files_to_remove' --prune-empty -f HEAD --all

命令挺复杂的,所以我是在一个 clone 出来的仓库里先试运行。先解释下各个参数:

  • --tree-filter表示修改文件列表。
  • --msg-filter表示修改提交信息,原提交信息从标准输入读入,新提交信息输出到标准输出。
  • --prune-empty表示如果修改后的提交为空则扔掉不要。在一次试运行中我发现虽然文件被删除了,但是还剩下个空的提交,就查了下 man 文档,找到了这个选项。
  • -f是忽略备份。不加这个选项第二次运行这个命令时会出错,意思是 git 上次做了备份,现在再要运行的话得处理掉上次的备份。
  • --all是针对所有的分支。

试运行了几次,看到 40 多次提交逐一被重写,然后检查下,发现要删除的文件确实被删除了。于是高兴地到 github 建立新仓库,并上传了。

折腾完毕,我更加喜欢 git 了 :-)

下面是具体的使用方法,主要是要gc,再覆盖到远程仓库。

git filter-branch --index-filter 'git rm --cached --ignore-unmatch <your-file-name>'
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git fsck --full --unreachable
git repack -A -d
git gc --aggressive --prune=now
git push --force origin master

------------------
2019-06-25更新,--all参数好像不能使用了,其实有更方便的第三方工具BFG可以使用,支持指定文件大小和文件名。
https://rtyley.github.io/bfg-repo-cleaner/

顺便也写下BFG的使用方式吧

首先仓库要使用bare方式,克隆的时候要加上--bare或者--mirror选项。

删除100M以上的文件 

java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git

删除test.sdf文件 

java -jar bfg.jar --delete-files test.sdf some-big-repo.git

删除_Boot 文件夹

java -jar bfg.jar --delete-folders _Boot some-big-repo.git

 最后要gc,再push到远程仓库

git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push --force --all
posted @   至尊王者  阅读(10964)  评论(5编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示