git filter-branch 命令修改删除提示记录,删除误提交的大文件.减小.git的大小
git找出记录里大小最大的文件
git仓库用久啦可能会很大,尤其是在你不经意间提交啦一个大文件,后来发现后赶紧把它删除掉啦,在你的源代码里是没有了并且源代码文件也不大,但是在 .git 这个文件夹里还是有它的记录啦大小也有,下面就说明一个解决方法使用git的一个很危险但又是最方便的一个命令
linux下可以直接在终端运行,windows下要在git base下运行不然会找不到文件路径如下图
首先使用下面查询git中前5名最大的文件
git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
输出结果如下,第一列为文件的id
记下上面的文件id使用下面命令查看对应文件的路径
git rev-list --objects --all | grep ed9253b5bbaaa6b0eb04db1dd9840121657b68f3
输出结果如下
filter-branch 遍历提交日志用指定的脚本进行一些处理
参数
--tree-filter 此选项会在每次检出项目时先执行指定的命令然后重新提交结果。
--msg-filter表示修改提交信息原提交信息从标准输入读入,新提交信息输出到标准输出
--prune-empty 表示如果修改后的提交如果为空则扔掉不要
--force 是忽略备份强制覆盖。不加这个选项第二次运行这个命令时会出错,意思是 git 上次做了备份,现在再要运行的话得处理掉上次的备份。
--all 。表示在所有分支上执行这些操作
git filter-branch使用起来有点危险,它可以分别检出每一个分支进行一些操作
从分支的提交日志中删除指定文件
从当前激活的分支最近30次提交中删除指定文件
git filter-branch --force --prune-empty --tree-filter 'git rm -f --cached --ignore-unmatch 文件路径' HEAD~30..HEAD
如果后面不加分支,就会遍历所有分支,文件路径就是相对git项目根目录的位置
如果出现下面的提示不能创建新的备份的话,就加上强制覆盖覆盖参数 --force
命令执行后如果看到下面似乎的进度,就说明脚本成功运行啦并且在处理相关操作
如果操作完成后没出现没有改变的情况,如下
WARNING: Ref 'refs/heads/master' is unchanged
可以尝试把上面命令中的--tree-filter换成 --index-filter再次运行命令
注:- -index-filter 选项类似于 - -tree-filter 选项,但这里不是传入一个命令去修改磁盘上签出的文件,而是修改暂存区域或索引。不能用 rm file 命令来删除一个特定文件,而是必须用git rm - -cached 来删除它 ── 即从索引而不是磁盘删除它。这样做是出于速度考虑 ── 由于 Git 在运行你的 filter 之前无需将所有版本签出到磁盘上,这个操作会快得多。也可以用 - -tree-filter 来完成相同的操作。git rm 的 - -ignore-unmatch 选项指定当你试图删除的内容并不存在时不显示错误。最后,因为你清楚问题是从哪个 commit 开始的,使用 filter-branch 重写自 64678 这个 commit 开始的所有历史记录。不这么做的话会重写所有历史记录,花费不必要的更多时间。
操作完成后,查看日志就会发现已经没有提交这个文件的日志记录啦,但是还有一个问题 .git 这个文件夹还是原来的大小,想减小它的大小就要对这个仓库进行分析重新打包,也就是清理垃圾。直接执行下面一些命令就ok
git rm -rf --ignore-unmatch .git/refs/original/ git reflog expire --expire=now --all git fsck --full --unreachable git repack -A -d git gc --aggressive --prune=now
最后强制推送到远端
git push origin master --force
注意如果远程仓库.git文件也是很大就得在远端进行同样的清理垃圾操作,