BFG Repo-Cleaner 是什么?
BFG Repo-Cleaner 是一个用于清理 Git 仓库历史的强大工具,它是 git-filter-branch 的替代品,主要用于处理以下场景:
- 删除仓库中的超大文件
- 移除密码、证书等敏感数据
- 清理特定文件或文件夹
相比于 git-filter-branch,BFG 具有以下优势:
- 更快速:处理速度是 git-filter-branch 的 10-720 倍。
- 更简单:专注于特定的清理任务,使用方式直观。
- 更优雅:基于 Scala 语言开发,相比 Bash 脚本更易于维护和扩展。
BFG Repo-Cleaner 安装要求
- Java 运行环境(Java 8 或更高版本)。
- BFG jar 文件(包含了所有依赖,无需额外安装)。
BFG Repo-Cleaner 使用步骤
1. 克隆仓库
首先需要使用 --mirror
标志克隆一个仓库的完整副本:
git clone --mirror git://example.com/some-big-repo.git
注意:这会创建一个裸仓库,虽然看不到普通的文件,但包含了完整的 Git 数据库。建议在此时创建备份。
2. 运行 BFG 清理
根据需求使用不同的命令清理仓库。以下是几个常用示例:
删除大文件:
java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git
删除特定文件:
java -jar bfg.jar --delete-files id_{dsa,rsa} my-repo.git
替换敏感信息:
java -jar bfg.jar --replace-text passwords.txt my-repo.git
3. 清理垃圾数据
BFG 更新完提交后,需要使用 git gc 命令清理不需要的数据:
cd some-big-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
4. 推送更新
确认仓库状态无误后,推送更新到远程:
git push
5. 删除旧副本
建议所有用户放弃旧的仓库副本,并克隆新的干净数据。最好删除所有旧副本,因为它们包含您不想冒险推回新清理仓库的脏历史记录。
BFG Repo-Cleaner 使用案例详解
1. 删除大文件
删除所有大于 50MB 的文件:
bfg --strip-blobs-bigger-than 50M my-repo.git
2. 删除敏感文件
删除所有名为 ‘id_rsa’ 或 ‘id_dsa’ 的文件:
bfg --delete-files id_{dsa,rsa} my-repo.git
3. 替换敏感信息
使用文件列表替换所有密码:
bfg --replace-text passwords.txt my-repo.git
4. 删除特殊文件夹
移除所有 .git 文件夹(从其他版本控制系统迁移时常用):
bfg --delete-folders .git --delete-files .git --no-blob-protection my-repo.git
BFG 的性能优势与工作原理
BFG 比 git-filter-branch 快得多,主要归功于以下几个方面:
- 高效的文件处理:BFG 利用 Git 的特性,每个文件和文件夹只处理一次,而 git-filter-branch 则会遍历每个提交的完整文件层次结构。
- 多核并行处理:BFG 默认使用多核处理,将清理仓库的工作分散到机器中的每个核心。
- 单进程操作:所有操作都在 JVM 的单个进程中进行,避免了 git-filter-branch 所需的频繁的 fork 和 exec 操作。
重要注意事项
- 保护当前文件
- 默认情况下,BFG 不会修改主分支(master 或 HEAD)最新提交的内容。
- 这是为了防止破坏当前可能部署在生产环境的代码。
- 建议先手动修改最新提交中的敏感信息,再使用 BFG 清理历史记录。
- blob 保护机制
- 如果受保护的提交中包含"坏"数据,即使在早期提交中被删除,它仍会保留在仓库中。
- 可以使用
--no-blob-protection
标志关闭保护(不推荐)。
- 清理后操作
- 清理完成后,建议所有开发者重新克隆仓库。
- 旧的克隆版本包含脏数据,可能会意外推送回仓库。
- 提交 ID 更改
- 清理历史记录后,提交 ID 会发生更改,尽管文件系统树的 SHA-1 ID 将保持不变。
结语
BFG Repo-Cleaner 是一个高效、易用的 Git 仓库清理工具,特别适合处理大文件删除和敏感信息清理的场景。它的高性能和简单的命令使得维护 Git 仓库历史变得更加容易。在使用时要注意备份数据,并确保理解保护机制的作用,以避免意外损失重要信息。