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

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

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