参考链接:


场景1:

最新的一个提交版本里面新增了敏感、较大、无意义的文件,需要进行清理。
1
2
3
4
5
6
7
8
9
10
11
1. 删除文件
$ git rm --cached ${文件绝对地址}
2. 增加到上述文件到 .gitignore
$ vim .gitignore
3. 修复最新提交版本
$ git commit --amend
4. 推送新版本到远端仓库
如果刚才版本已经推送到远端仓库:
$ git push -f
如果刚才版本只是在本地仓库:
$ git push

场景2:

历史版本里面存在敏感、较大、无意义的文件,需要进行清理。

使用 git filter-branch

git 原生提供的命令,如果没有的话,请先升级机器git版本。

  • 原理:
    扫描代码库所有版本
    如果某个版本里面发现了指定的文件OR目录:
    如果此版本包含要清理的文件OR目录 和 其它变更的话,对此版本进行删除指定文件OR目录(保留其它变更),并生成新的版本。同时后面的版本会变基到新版本。
    如果此版本只包含要清理的文件OR目录变更的话,那么此版本会被清除。同时后面的版本会变基到上一个版本。
    如果版本没有包含指定文件OR目录,那么继续遍历。
  • PS:
    1. 如果代码库历史比较多 OR 涉及到指定文件OR目录的版本比较多,那么命令执行会比较慢。
    2. 一般会导致代码库版本树变化,对于涉及开发同学,建议开始前提交本地修改变更到远端仓库,完成后本机重新clone代码库进行开发。
    3. 一般都在本地仓库根目录执行
    4. 执行命令后历史版本里面已经清理了文件, 但是我们的本地仓库里面仍然保留了这些objects, 等待垃圾回收(GC), 如果想立即回收本地仓库空间可以执行 git gc –prune=now.
1
2
3
4
5
6
7
8
9
10
1. 执行命令
$ git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch ${要清理的文件OR目录的绝对地址}' --prune-empty --tag-name-filter cat -- --all
2. 增加到上述文件OR目录到 .gitignore
$ vim .gitignore
3. 推送新版本到远端仓库
$ git push -f --all
$ git push -f --tags
4. 清理本地仓库残留的git objects
$ git reflog expire --expire=now --all
$ git gc --prune=now

使用 bfg-repo-cleaner

Roberto Tyley使用Scala语言写了 bfg-repo-cleaner工具。
可以简单理解为一个轻量级的 git filter-branch。
使用比较简单,功能比较强大,只需要下载最新的jar包,然后执行👇命令:

1
2
3
4
# 删除大于50M的文件
$ java -jar bfg.jar --no-blob-protection --strip-blobs-bigger-than 50M
# 删除指定文件
$ java -jar bfg.jar --no-blob-protection --delete-files ${要清理的文件的绝对地址}

PS:
1. bfg-repo-cleaner 有个protect功能,默认HEAD是受保护的。
受保护的分支最新版本如果涉及需要清理文件,那么并不会成功。
–no-blob-protection 关闭protect功能
–protect-blobs-from ${分支1},${分支2} 增加受保护的分支
2. 建议在本地仓库根目录执行。


场景3:

查找代码库里面较大文件方法:
- 如果当前版本还存在的文件,可以直接du排序来识别;
- 如果当前版本不存在,但是历史中出现过的大文件,可以按照下面步骤来查询。

1
2
1. 显示比较大的pack
$ du -ah .git/objects/pack

logo

1
2
2. 识别object,对输出的第三列信息即文件大小进行排序
$ git verify-pack -v .git/objects/pack/${pack-XXX.pack} | sort -k 3 -n | tail -5

logo

1
2
3. 识别object对应的文件
$ git rev-list --objects --all | grep ${👆获取的object}

logo