蚊章汇 - Atlassian.com
type: channel
link: https://linuxcn.bwsl.wang/author/604/
description: Atlassian.com
items: 如何瘦身 Git 仓库

如何瘦身 Git 仓库
type: item
date: 2017-05-30T18:24:00+08:00
description: 对 Git 仓库的维护通常是为了减少仓库的大小。如果你从另外一个版本控制系统导入了一个仓库，你可能需要在导入后清除掉不必要的文件。本文着重于从一个 Git 仓库中删除大文件，并且包含下列主题：理解从 Git 的历史记录中删除文件使用 BFG 重写历史记录可选，使用 git filter-branch 重写历史记录垃圾回收请格外小心.....本文中的步骤和工具使用的高级技术涉及破坏性操作。确保您在开始之前仔细读过并备份了你的仓库，创建一个备份最容易的方式是使用 --mirror 标志对你的仓库克隆，然后对整个克隆的文件进行打包压缩。有了这个备份，如果在维护期间意外损坏了您的仓库的关键元素，那么你可以通过备份的仓库来恢复。请记住，仓库维护对仓库的用户可能会是毁灭性的。与你的团队或者仓库的关注者进行沟通会是一个不错的主意。确保每个人都已经检查了他们的代码，并且同意在仓库维护期间停止开发。理解从 Git 的历史记录中删除文件回想一下，克隆仓库会克隆整个历史记录——包括每个源代码文件的所有版本。如果一个用户提交了一个较大的文件，比如一个 JAR，则随后的每次克隆都会包含这个文件。即使用户最终在后面的某次提交中删除了这个文件，但是这个文件仍然存在于这个仓库的历史记录中。要想完全的从你的仓库中删除这个文件，你必须：从你的项目的当前的文件树中删除该文件;从仓库的历史记录中删除文件——重写 Git 历史记录，从包含该文件的所有的提交中删除这个文件;删除指向旧的提交历史记录的所有 reflog 历史记录;重新整理仓库，使用 git gc 对现在没有使用的数据进行垃圾回收。Git 的 “gc”（垃圾回收）将通过你的任何一个分支或者标签来删除仓库中所有的实际没用的或者以某种方式引用的数据。为了使其发挥作用，我们需要重写包含不需要的文件的所有 Git 仓库历史记录，仓库将不再引用它—— git gc 将会丢弃所有没用的数据。重写存储库历史是一个棘手的事情，因为每个提交都依赖它的父提交，所以任何一个很小的改变都会改变它的每一个随后的提交的提交 ID。有两个自动化的工具可以做到这：BFG Repo Cleaner 快速、简单且易于使用，需要 Java 6 或者更高版本的运行环境。git filter-branch 功能强大、配置麻烦，用于大于仓库时速度较慢，是核心 Git 套件的一部分。切记，当你重写历史记录后，无论你是使用 BFG 还是使用 filter-branch，你都需要删除指向旧的历史记录的 reflog 条目，最后运行垃圾回收器来删除旧的数据。使用 BFG 重写历史记录BFG 是为将像大文件或者密码这些不想要的数据从 Git 仓库中删除而专门设计的，所以它有一一个简单的标志用来删除那些大的历史文件（不在当前的提交里面）：--strip-blobs-bigger-than$ java -jar bfg.jar --strip-blobs-than 100M 大小超过 100MB 的任何文件（不包含在你最近的提交中的文件——因为 BFG 默认会保护你的最新提交的内容）将会从你的 Git 仓库的历史记录中删除。如果你想用名字来指明具体的文件，你也可以这样做：$ java -jar bfg.jar --delete-files *.mp4BFG 的速度要比 git filter-branch 快 10-1000 倍，而且通常更容易使用——查看完整的使用说明和示例获取更多细节。或者，使用 git filter-branch 来重写历史记录filter-branch 命令可以对 Git 仓库的历史记录重写，就像 BFG 一样，但是过程更慢和更手动化。如果你不知道这些大文件在哪里，那么你第一步就需要找到它们：手动查看你 Git 仓库中的大文件Antony Stubbs 写了一个可以很好地完成这个功能的 BASH 脚本。该脚本可以检查你的包文件的内容并列出大文件。在你开始删除文件之前，请执行以下操作获取并安装此脚本：1、 下载脚本到你的本地的系统。2、 将它放在一个可以访问你的 Git 仓库的易于找到的位置。3、 让脚本成为可执行文件：$ chmod 777 git_find_big.sh 4、 克隆仓库到你本地系统。5、 改变当前目录到你的仓库根目录。6、 手动运行 Git 垃圾回收器：git gc --auto 7、 找出 .git 文件夹的大小$ du -hs .git/objects 45M .git/objects 注意文件大小，以便随后参考。8、 运行 git_find_big.sh 脚本来列出你的仓库中的大文件。$ git_find_big.sh All sizes are in kB's. The pack column is the size…