git查找大文件并删除
git查找大文件,并从历史记录中删除。大概有几种方法。如果出现错误提交,最好在没有推送到远程前,赶紧删掉。就算推到远程,也尽快恢复。
大概两种方法。分几个部分看。
方式一
测试创建、并推送一些记录。
git
echo test_git
git clone http://...../test_git.git
cd test_git
ls
# 创建提交记录
for n in `seq 1 10`;do
echo "$n$n$n$n$n" >> $n.txt
git add .
git commit -am "$n:add $n.txt"
git push
done
git log --oneline
# 选择其中一个节点,如果要删除某个点,要在其前1个点执行
git rebase -i 9303e8f
# 然后编辑,drop 代表删除。比如删除该节点后面的一个节点,再看
git log --oneline
# 然后发现上面的节点确实删除了
# 去掉git的保护分支
git push -f
git push -f --all
方式2
1、查找最大的文件
git rev-list --all | xargs -rL1 git ls-tree -r --long | sort -uk3 | sort -rnk4 | head -10
# 由于提交历史已有8000+,很长时间后,找到如下
# 100644 blob 0800a0c5f547627750412b8f5ed9026c74235ba6 1984831488 geoserver/osm-lowres.gpkg
2、根据最大文件的路径 {filepath},修改此文件的commit历史:
git filter-branch --tree-filter "rm -f {filepath}" -- --all
3、强制提交到远程分支:
git push -f --all
试过,大文件还在。
方式3
1、实际上到下面文件能找到一个最大的文件
.git\objects\pack
能找到大文件 但是不知道,对应哪次提交。
git verify-pack -v .git/objects/pack/pack-5794788dfaa1755461cb7dc301649cab222b4006.pack | sort -k 3 -n | tail -3
2.查询大文件的文件名
git rev-list --objects --all | grep 0800a0c5f547627750412b8f5ed9026c74235ba6
# 输出如下:
# 0800a0c5f547627750412b8f5ed9026c74235ba6 geoserver/osm-lowres.gpkg
3.将该文件从历史记录的所有 tree 中移除
git filter-branch --index-filter 'git rm --cached --ignore-unmatch geoserver/osm-lowres.gpkg'
注意:上面文件命令 geoserver/osm-lowres.gpkg 前面并没有 / 号
4.然后再执行如下语句:
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
试过,大文件还在。
方式4:
另外一篇文章:
首先来看下.git目录:
├── HEAD
├── branches
├── index
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 88
│ │ └── 23efd7fa394844ef4af3c649823fa4aedefec5
│ ├── 91
│ │ └── 0fc16f5cc5a91e6712c33aed4aad2cfffccb73
│ ├── 9f
│ │ └── 4d96d5b00d98959ea9960f069585ce42b1349a
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
用于GitWeb程序
配置特定于该仓库的设置
放置客户端或服务端的hook脚本
指明当前处于哪个分支
Git对象存储目录
Git引用存储目录
放置分支引用的目录
每次 都会生成一个Git对象,称为blob 对象,存放在objects目录下。
这个blob 对象里保存的是什么呢?
Git在add文件时,会把文件完整的保存成一个新的blob 对象。通过 打包或者每次 的时候Git都会自动执行一次打包过程,将Blob对象合并成一个包文件,同时会生成一个索引文件,索引文件中包含了每个Blob对象在包文件中的偏移信息,Git在打包的过程中使用了增量编码方案,只保存Blob对象的不同版本之间的差异,这使得仓库会瘦身。
既然Git会对Blob对象进行合并优化,那么objects文件夹为什么还会那么大呢?
因为当Blob对象在合并时不能对.a进行差异化比较,所以每次在添加.a文件时,都会保存一份.a文件,用于后续代码还原时使用。
所以当频繁更换.a文件时,objects下的pack文件会越来越大。虽然这个.a文件后续可能用不到删除了,但是pack中的这个.a文件的缓存还是会一直存在。
删除pack中无用的大文件缓存
首先先找出git中最大的文件:
git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
执行结果:
第一行的字母其实相当于文件的id,用以下命令可以找出id对应的文件名:
git rev-list –objects –all | grep 8f10eff91bb6aa2de1f5d096ee2e1687b0eab007
找到最大的几个文件后,怎么删除呢?
能够胜任这个任务的命令叫做 filter-branch:
git filter-branch –force –prune-empty –index-filter ‘git rm -rf –cached –ignore-unmatch XXX.framework’ –tag-name-filter cat – –all
等命令执行完后,要提交到远程:
git push –force –all
链接:https://www.jianshu.com/p/4f2ccb48da77
其他: