BFG Repo-Cleaner(快速清除Git提交历史中的特定文件)
有些时候不小心上传了一些敏感文件(例如密码), 或者不想上传的文件(没及时或忘了加到.gitignore里的),而且上传的文件又特别大的时候, 这将导致别人clone你的代码或下载zip包的时候也必须更新或下载这些无用的文件,因此, 我们需要一个方法, 永久的删除这些文件(包括该文件的历史记录).
BFG是用Scala写的,像git-filter-branch
那样删除大的或麻烦的块,但是速度更快。
在GitHub上查看项目
$ bfg --strip-blobs-bigger-than 100M --replace-text banned.txt repo.git
git-filter-branch的另一种选择
BFG是git-filter-branch
之外的一种更简单、更快的方法,可以清除Git存储库历史中的不良数据:
- 删除 大文件
- 删除 密码、凭证 和其他 私人数据
git-filter-branch
命令非常强大,可以做BFG不能做的事情——但是BFG更适合上面的任务,因为:
- 快 : 快10 - 720倍
- 简单 : BFG并不是特别聪明,但专注于让上述任务变得简单
- 优美 : 如果需要,可以使用漂亮的Scala语言定制BFG。这至少在某些时候比Bash脚本要好。
使用
首先使用--mirror
标志克隆一个新的repo副本:
$ git clone --mirror git://example.com/some-big-repo.git
这是一个 bare 仓库,这意味着您的普通文件将不可见,但它是存储库Git数据库的完整副本,此时您应该备份它,以确保不会丢失任何东西。
现在你可以运行BFG来清理你的仓库:
$ java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git
BFG将更新您的提交以及所有分支和标记,使它们保持干净,但它不会物理删除不需要的东西。 检查存储库以确保您的历史记录已更新,然后使用标准的git gc
命令去除不需要的脏数据, git现在将这些脏数据视为多余的需求:
$ cd some-big-repo.git
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
最后,一旦您对您的仓库的更新状态感到满意,请把它重新推回去 (请注意,因为您的clone命令使用了--mirror标志,所以此推送将更新远程服务器上的所有引用):
$ git push
此时,您已经准备好让每个人都抛弃旧的repo副本,重新克隆新的原始数据。最好删除所有旧的克隆,因为它们会有肮脏的历史,您不想冒险将其推回到您新清理的repo中。
例子
在所有这些示例中,bfg
是java -jar bfg.jar
的别名。
删除所有名为'id_rsa'或'id_dsa'的文件:
$ bfg --delete-files id_{dsa,rsa} my-repo.git
删除所有大于50兆字节的blob:
$ bfg --strip-blobs-bigger-than 50M my-repo.git
将文件*(前缀行'regex:'或'glob:'如果需要)*中列出的所有密码替换为' *** remove *** ',无论它们在您的存储库中的任何地方:
$ bfg --replace-text passwords.txt my-repo.git
删除Git中所有名为'.git'的文件夹或文件—保留的文件名。当从Mercurial等其他源代码控制系统迁移到Git时,这些常常会成为一个问题:
$ bfg --delete-folders .git --delete-files .git --no-blob-protection my-repo.git
对于进一步的命令行选项,您可以不带任何参数运行BFG,它将输出如下所示。
你的当前文件是神圣的...
BFG对待你就像一个改过自新的酒鬼:你过去犯过一些错误,但现在你已经改过自新了。因此,BFG假定您的最新提交是一个好的提交,其中没有您希望从历史记录中删除的脏文件。BFG的这一假设保护了您的工作,并让您安心地知道BFG只是仅仅更改您的仓库历史记录,而不是干预项目的当前文件。
默认情况下,HEAD
分支是受保护的,虽然它的历史记录将被清除,但是最新的提交(这个'技巧')是protected commit(受保护的提交),它的文件层次结构将不会被改变。
如果你想保护几个分支或标签的tips(提示)
(不只是HEAD'头部'),只需为BFG命名:
$ bfg --strip-biggest-blobs 100 --protect-blobs-from master,maint,next repo.git
注意:
- 清理Git repos就是要彻底根除历史上的坏东西。如果某个坏的文件(比如10MB的文件,当您指定
--strip-blobs-bigger-than 5M
)在受保护的提交中,那么它不会被删除—它将保存在您的存储库中,即使BFG从以前的提交中删除了它。如果你想让BFG删除一些东西,你需要确保你的当前提交是干净的。 - 请注意,尽管这些受保护的提交中的文件不会被更改,但是当这些提交从早期的脏提交继续进行时,它们的提交ids 将 更改,以反映更改的历史—只有文件系统树的SHA-1 id 将保持不变。
更快...
BFG 10 - 720x 比git-filter-branch
更快,将过夜作业提升到不到10分钟的作业。
要求
-
Java 运行时环境 (Java 7 或更高 - BFG v1.12.3 最新的版本支持 Java 6)
-
就一个jar文件,Scala库和所有其他依赖项全部被打包到 downloadable jar.
链接...
- 使用BFG重写Git项目历史 - Guardian的博客文章
- GitMinutes 播客采访
- Git的应该更快...使用Scala - 为2014年的《ScalaDays》,《the later Parleys *Presentation of the Day》做演讲
- InfoQ interview
- Questions tagged
git-rewrite-history
在 Stack Overflow
许可
BFG是自由软件:您可以根据自由软件基金会发布的GNU通用公共许可证、许可证的第3版或(根据您的选择)任何后续版本的条款重新分发和/或修改它。
BFG的发行是希望它将是有用的,但没有任何保证;甚至没有隐含的适销性或适合某一特定用途的保证。有关更多细节,请参阅GNU通用公共许可证。