使用git filter-branch删除没有使用的大文件

原创
2019/05/31 14:03
阅读数 1.7K

使用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 <SHA>
Pods/opencv2/sdks/1.0.0/opencv2.framework/Versions/A/opencv2

到这里,我就查出了我的.git为什么这么大:把Pods提交上去了。做iOS开发的都知道这个是三方库存的地方,不用提交到git。

3 查出文件提交commit记录

$ git log --pretty=oneline --branches -- <file_path>

4 删除文件

遍历所有提交: commit多了会比较慢

$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch <file>' --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 <file>' -- <commit_id>

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 <file>' 使用带有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=<time> Prune entries older than the specified time. 修剪早于指定时间的条目。

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=<date> Prune loose objects older than date 修剪比日期更早的松散物体
展开阅读全文
Git
打赏
0
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
0
分享
返回顶部
顶部