git 彻底删除历史记录中的大文件

Worked Reference
Reference

大家一定遇到过在使用Git时,不小心将一个很大的文件添加到库中,即使删除,记录中还是保存了这个文件。以后不管是拷贝,还是push/pull都比较麻烦。

===

删除大文件方法
  • 方法很简单,就是先找到大文件对象再删除。

  • 先清理当前working tree。

      commit、stash、checkout都ok
  • 对仓库进行gc操作
    git gc
  • 运行count-objects 查看空间使用,size-pack 是以千字节为单位表示的 packfiles 的大小。
    git count-objects -v
  • 运行底层命令 git verify-pack 以识别大对象,对输出的第三列信息即文件大小进行排序.
    git verify-pack -v .git/objects/pack/***.idx | sort -k 3 -n | tail -3
  • 使用 rev-list 命令,传入 --objects选项,它会列出所有 commit SHA 值,blob SHA 值及相应的文件路径,这样查看 blob 的文件名。
    git rev-list --objects --all | grep ${SHA}
  • 将该文件从历史记录的所有 tree 中移除。
    git log --pretty=oneline --branches -- ${FILE_PATH}
  • 用 filter-branch 命令重写从 646784 开始的所有 commit 才能将文件从 Git 历史中完全移除。
    git filter-branch --index-filter 'git rm --cached --ignore-unmatch ${FILE_PATH}' -- ${MD5}.. 注:--index-filter 选项类似于 --tree-filter 选项,但这里不是传入一个命令去修改磁盘上签出的文件,而是修改暂存区域或索引。 不能用 rm file 命令来删除一个特定文件,而是必须用git rm - -cached 来删除它 ── 即从索引而不是磁盘删除它。 这样做是出于速度考虑 ── 由于 Git 在运行你的 filter 之前无需将所有版本签出到磁盘上,这个操作会快得多。 也可以用 --tree-filter 来完成相同的操作。 git rm 的 --ignore-unmatch 选项指定当你试图删除的内容并不存在时不显示错误。最后,因为你清楚问题是从哪个 commit 开始的,使用 filter-branch 重写自 指定这个 commit 开始的所有历史记录。不这么做的话会重写所有历史记录,花费不必要的更多时间。
  • 现在历史记录中已经不包含对那个文件的引用了。不过 reflog 以及运行 filter-branch 时 Git 往.git/refs/original 添加的一些 refs 中仍有对它的引用,因此需要将这些引用删除并对仓库进行 repack 操作。在进行 repack 前需要将所有对这些 commits 的引用去除。
    rm -Rf .git/refs/original rm -Rf .git/logs/ git gc 注意,本操作会删除本地当前库的操作历史,请确认后完成
  • 查看空间使用
    git count-objects -v
  • 接下来就是对库进行分支操作,以push
  • 如果真的要完全把这个对象删除,可以运行 git prune 命令。

转载于:https://www.cnblogs.com/suanec/p/9207803.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值