2019独角兽企业重金招聘Python工程师标准>>>
使用git filter-branch删除没有使用的大文件
最近发现公司的iOS工程很大,.git文件夹足足2.5G,分析了下是之前把Pods目录上传到git了,之后忽略了这个文件夹,可是历史提交还在里面。优化后,减少到600M,这里把方法分析给大家
参考资料
https://www.jianshu.com/p/780161d32c8e
准备
查看当前文件大小,优化前后使用对比 $ git count-objects -v -H
使用流程
1 查出已删除的大文件前3名的commit SHA值
$ git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -n | tail -3
2 commit SHA值查出文件路径
$ git rev-list --objects --all | grep
Pods/opencv2/sdks/1.0.0/opencv2.framework/Versions/A/opencv2
到这里,我就查出了我的.git为什么这么大:把Pods提交上去了。做iOS开发的都知道这个是三方库存的地方,不用提交到git。
3 查出文件提交commit记录
$ git log --pretty=oneline --branches --
4 删除文件
遍历所有提交: commit多了会比较慢
$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch ' --tag-name-filter cat -- --all
$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch Pods/' --tag-name-filter cat -- --all
我就是使用这个命令,全量删除Pods目录的
指定commit修改(配合步骤3使用)
$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch ' --
5 回收内存
$ rm -rf .git/refs/original/
$ git reflog expire --expire=now --all
$ git fsck --full --unreachable
$ git repack -A -d
$ git gc --aggressive --prune=now
6 提交变动
$ git push --force --all
命令解析
1. git filter-branch
Rewrite branches 重写分支
- -f --force git filter-branch refuses to start with an existing temporary directory or when there are already refs starting with refs/original/, unless forced. git filter-branch拒绝从现有的临时目录开始,或者当已经使用refs / original /开始refs时,除非被强制。
- --prune-empty Some filters will generate empty commits that leave the tree untouched 某些过滤器将生成空提交,使树保持不变
- --index-filter 'git rm -rf --cached --ignore-unmatch
' 使用带有git rm的--index-filter会产生明显更快的版本。与使用rm文件名一样,如果文件不在提交树中,则git rm --cached filename将失败。如果你想“完全忘记”一个文件,它在输入历史记录时无关紧要,所以我们还添加了--ignore-unmatch - --tag-name-filter This is the filter for rewriting tag names
- --tag-name-filter cat The original tags are not deleted, but can be overwritten
- -- --all filtered all refs
- -- tag 指定tag
2. git reflog expire --expire=now --all
Manage reflog information. reflog = reference log关联日志 git reflog expire The "expire" subcommand prunes older reflog entries. “expire”子命令修剪旧的reflog条目
- --all Process the reflogs of all references. 处理所有引用的reflog
- --expire=
3 git fsck --full --unreachable
Verifies the connectivity and validity of the objects in the database 验证数据库中对象的连接性和有效性
- --unreachable Print out objects that exist but that aren’t reachable from any of the reference nodes.
- --full
4 git repack -A -d
Pack unpacked objects in a repository 在存储库中打包解压缩的对象。 删除冗余的对象
- -a Instead of incrementally packing the unpacked objects, pack everything referenced into a single pack. 不是逐步打包解压缩的对象,而是将引用的所有内容打包到单个包中。
- -d After packing, if the newly created packs make some existing packs redundant, remove the redundant packs. 打包后,如果新创建的包使一些现有包冗余,请删除冗余包。 -A Same as -a, unless -d is used. Then any unreachable objects in a previous pack become loose, unpacked objects, instead of being left in the old pack. 与-a相同,除非使用-d。然后,前一个包中的任何无法访问的对象都会变成松散的解包对象,而不是留在旧包中。
5 git gc --aggressive --prune=now
Cleanup unnecessary files and optimize the local repository 清理不必要的文件并优化本地存储库
- --aggressive 此选项将导致git gc更积极地优化存储库,但代价是花费更多时间。
- --prune=
Prune loose objects older than date 修剪比日期更早的松散物体