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

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

最近发现公司的iOS工程很大,.git文件夹足足2.5G,分析了下是以前把Pods目录上传到git了,以后忽略了这个文件夹,但是历史提交还在里面。优化后,减小到600M,这里把方法分析给你们node

参考资料

https://www.jianshu.com/p/780161d32c8egit

准备

查看当前文件大小,优化先后使用对比 $ 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多了会比较慢less

$ 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条目code

  • --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 验证数据库中对象的链接性和有效性orm

  • --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 修剪比日期更早的松散物体
相关文章
相关标签/搜索