Git维护小技巧

对 Git 仓库的维护通常是为了减少仓库的大小。如果你从另外一个版本控制系统导入了一个仓库,你可能需要在导入后清除掉不必要的文件。本文着重于从一个 Git 仓库中删除大文件,并且包含下列主题:

  • 理解从 Git 的历史记录中删除文件
  • 使用 BFG 重写历史记录
  • 可选,使用git filter-branch重写历史记录
  • 垃圾回收

本文中的步骤和工具使用的高级技术涉及破坏性操作。确保您在开始之前仔细读过并备份了你的仓库,创建一个备份最容易的方式是使用–mirror标志对你的仓库克隆,然后对整个克隆的文件进行打包压缩。有了这个备份,如果在维护期间意外损坏了您的仓库的关键元素,那么你可以通过备份的仓库来恢复。

请记住,仓库维护对仓库的用户可能会是毁灭性的。与你的团队或者仓库的关注者进行沟通会是一个不错的主意。确保每个人都已经检查了他们的代码,并且同意在仓库维护期间停止开发。

理解从 Git 的历史记录中删除文件

回想一下,克隆仓库会克隆整个历史记录——包括每个源代码文件的所有版本。如果一个用户提交了一个较大的文件,比如一个 JAR,则随后的每次克隆都会包含这个文件。即使用户最终在后面的某次提交中删除了这个文件,但是这个文件仍然存在于这个仓库的历史记录中。要想完全的从你的仓库中删除这个文件,你必须:

  • 从你的项目的当前的文件树中删除该文件;
  • 从仓库的历史记录中删除文件——重写Git 历史记录,从包含该文件的所有的提交中删除这个文件;
  • 删除指向旧的提交历史记录的所有reflog历史记录;
  • 重新整理仓库,使用git gc对现在没有使用的数据进行垃圾回收。

Git 的 “gc”(垃圾回收)将通过你的任何一个分支或者标签来删除仓库中所有的实际没用的或者以某种方式引用的数据。为了使其发挥作用,我们需要重写包含不需要的文件的所有 Git 仓库历史记录,仓库将不再引用它—— git gc 将会丢弃所有没用的数据。

重写存储库历史是一个棘手的事情,因为每个提交都依赖它的父提交,所以任何一个很小的改变都会改变它的每一个随后的提交的提交 ID。有两个自动化的工具可以做到这:

  1. BFG Repo Cleaner快速、简单且易于使用,需要 Java 6 或者更高版本的运行环境。
  2. 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 *.mp4

BFG 的速度要比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 of the object, compressed, inside the pack file. size  pack  SHA                                       location 592   580   e3117f48bc305dd1f5ae0df3419a0ce2d9617336  media/img/emojis.jar 550   169   b594a7f59ba7ba9daebb20447a87ea4357874f43  media/js/aui/aui-dependencies.jar 518   514   22f7f9a84905aaec019dae9ea1279a9450277130  media/images/screenshots/issue-tracker-wiki.jar 337   92    1fd8ac97c9fecf74ba6246eacef8288e89b4bff5  media/js/lib/bundle.js 240   239   e0c26d9959bd583e5ef32b6206fc8abe5fea8624  media/img/featuretour/heroshot.png 

大文件都是 JAR 文件,包的大小列是最相关的。aui-dependencies.jar被压缩到 169kb,但是emojis.jar只压缩到 500kb。emojis.jar就是一个待删除的对象。

运行 filter-branch

你可以给这个命令传递一个用于重写 Git 索引的过滤器。例如,一个过滤器可以可以将每个检索的提交删除。这个用法如下:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch  _pathname_ ' commitHASH

–index-filter选项可以修改仓库的索引,–cached选项从索引中而不是磁盘来删除文件。这样会更快,因为你不需要在运行这个过滤器前检查每个修订版本。git rm中的ignore-unmatch选项可以防止在尝试移走不存在的文件pathname的时候命令失败。通过指定一个提交 HASH 值,你可以从每个以这个 HASH 值开始的提交中删除pathname。要从开始处删除,你可以省略这个参数或者指定为HEAD。

如果你的大文件在不同的分支,你将需要通过名字来删除每个文件。如果大文件都在一个单独的分支,你可以直接删除这个分支本身。

选项 1:通过文件名删除文件

使用下面的步骤来删除大文件: 1、 使用下面的命令来删除你找到的第一个大文件:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

2、 重复步骤 1 找到剩下的每个大文件。 3、 在你的仓库里更新引用。filter-branch会为你原先的引用创建一个refs/original/下的备份。一旦你确信已经删除了正确的文件,你可以运行下面的命令来删除备份文件,同时可以让垃圾回收器回收大的对象:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

选项 2:直接删除分支

如果你所有的大文件都在一个单独的分支上,你可以直接删除这个分支。删除这个分支会自动删除所有的引用。

1、 删除分支。

$ git branch -D PROJ567bugfix

2、 从后面的分支中删除所有的 reflog 引用。

对不用的数据垃圾回收

1、 删除从现在到后面的所有 reflog 引用(除非你明确地只在一个分支上操作)。

$ git reflog expire --expire=now --all

2、 通过运行垃圾回收器和删除旧的对象重新打包仓库。

$ git gc --prune=now

3、 把你所有的修改推送回仓库。

$ git push --all --force

4、 确保你所有的标签也是当前最新的:

$ git push --tags --force

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/220768.html<

(0)
运维的头像运维
上一篇2025-04-14 17:37
下一篇 2025-04-14 17:38

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注