Git 2.50 发布

6/17/2025 11:57:31 PM
0

开源 Git 项目刚刚发布了 Git 2.50,其中包含来自 98 个贡献者的功能和错误修复,其中 35 个是新的。

Git 2.50 通过一个新选项解决了这两个问题:.它不是指定输出包的最大大小,而是确定哪些现有的 cruft 包有资格进行组合。这对于在多个 cruft 包中积累了许多无法访问的对象的存储库特别有用。使用这个新选项,您可以通过将现有 Cruft Pack 组合在一起,随着时间的推移逐渐减少存储库中的 cruft 包数量。

--combine-cruft-below-size

引入增量多包索引,提升操作性能。

ORT合并引擎取代了旧的递归合并引擎。

如果您曾经围绕存储库的对象编写过脚本,您可能熟悉 git cat-file,这是 Git 专门构建的工具,用于列出对象并打印其内容。git cat-file 有很多模式,比如 --batch(用于打印对象的内容)或 --batch-check(用于打印对象的某些信息而不打印它们的内容)。

通常,将特定类型的所有对象的集合转储到存储库中是很有用的。对于提交,git rev-list 可以很容易地枚举一组提交。但是,比如说,对象树呢?过去,要从对象列表中筛选出仅树对象,您可能编写了如下内容:

$ git cat-file --batch-check='%(objecttype) %(objectname)' \ --buffer <in | perl -ne 'print "$1\n" if /^tree ([0-9a-f]+)/'

Git 2.50 将部分克隆中使用的 Git 对象过滤机制带到了 git cat-file,因此上面的内容可以更简洁地重写如下:

$ git cat-file --batch-check='%(objectname)' --filter='object:type=tree' <in

当我们讨论这个话题时,让我们讨论一个鲜为人知的 git cat-file 命令行选项:--allow-unknown-type。此 unane 选项用于类型不是 blob、tree、commit 或 tag 的对象。这是一个可以追溯到十多年前的怪癖,它允许 git hash-object 写入任意类型的对象。从那以后,这个功能就很少用了。事实上, git cat-file -p --allow-unknown-type 甚至无法打印出这些对象之一的内容!

该版本使 --allow-unknown-type 选项无提示地执行任何作,并首先删除了对 git hash-object 写入未知类型的对象的支持。

git maintenance 命令在这个版本中也学到了很多新技巧。它现在可以执行一些新的不同类型的任务,例如 worktree-prune、rerere-gc 和 reflog-expire。worktree-prune 镜像了 Git gc 删除过时或损坏的 Git 工作树的功能。rerere-gc 还镜像了通过 git gc 公开的现有功能,以使以前记录的合并冲突解决中的旧 rerere 条目过期。最后,reflog-expire 可用于从 reflog 中删除过时的无法访问的对象。

git maintenance 还为现有的 Loose-Objects 任务提供了新的配置。此任务将删除已打包的挥之不去的松散对象,然后为剩余的任何松散对象创建新的包。这些包的大小以前固定为最大 50,000,现在可以通过 maintenance.loose-objects.batchSize 配置进行配置。

如果你曾经需要恢复一些丢失的工作,你可能熟悉 Git 的 reflog 功能,它允许你跟踪引用随时间的变化。例如,您可以通过执行 git show main@{2}(显示最近两次更新之前的 main)或 main@{1.week.ago})(显示分支副本一周前的位置)来返回并重新访问仓库 main 分支的早期版本。

引用日志条目会随着时间的推移而累积,如果需要清理它们,你可以使用 git reflog expire。但是如何删除整个分支的 reflog 呢?如果你还没有运行 Git 2.50 并认为“肯定是 git reflog delete”,那你就错了!在 Git 2.50 之前,删除分支的整个 reflog 的唯一方法是执行 git reflog expire $BRANCH --expire=all 。

在 Git 2.50 中,引入了一个新的 delete 子命令,因此您可以使用更自然的 git reflog delete $BRANCH 完成与上述相同的作。

说到引用,Git 2.50 还受到了一些关于如何在整个代码库中处理和使用引用的关注。当使用低级 git update-ref 命令时,Git 过去常常花时间检查建议的 refname 是否也可以是一个有效的对象 ID,这使得它的查找变得模糊。由于 update-ref 是一个如此低级的命令,因此不再进行此检查,从而为依赖 update-ref 实现其功能的更高级别的命令提供一些性能优势。

Git 2.50 还学会了如何缓存建议的引用名称的任何前缀是否已经存在(例如,如果 refs/heads/foo/bar 或 refs/heads/foo 已经存在,则无法创建引用 ref/heads/foo/bar/baz)。

最后,为了进行这些检查,Git 过去常常为每个单独的前缀创建一个新的引用迭代器。Git 2.50 的参考后端学会了如何 “寻找” 现有的迭代器,通过在检查每个可能的前缀时能够重用相同的迭代器来节省时间。

如果您曾经不得不修改 Git 的低级 curl 配置,您可能熟悉 Git 用于调整 HTTP 连接的配置选项 ,例如 http.lowSpeedLimit 和 http.lowSpeedTime,它们用于终止传输数据速度太慢的 HTTP 连接。

在微调 Git 以在复杂的网络环境中工作时,这些选项可能很有用。但是,如果您想调整 Git 的 TCP Keepalive 行为怎么办?这对于控制在终止最近未发送数据的连接之前发送 keepalive 探测的时间和频率以及发送的数量非常有用。

在 Git 2.50 之前,这是不可能的,但此版本引入了三个新的配置选项:http.keepAliveIdle、http.keepAliveInterval 和 http.keepAliveCount,可用于控制 curl 的 TCP 探测的细粒度行为(前提是您的作系统支持它)。

Git 是众所周知的可移植性,可以在各种作系统和环境上运行,依赖项非常少。多年来,Git 的各个部分都是用 Perl 编写的,包括一些命令,比如 git add -i 的原始实现 。如今,很少有剩余的 Git 命令是用 Perl 编写的。

此版本通过将 Perl 作为测试套件和文档工具链的依赖项删除,减少了 Git 对 Perl 的使用。Git 测试套件中的许多 Perl 单行代码被重写为使用其他 Shell 函数或内置函数,还有一些被重写为微型 C 程序。对于 Perl 上剩余的少数硬依赖项,在没有正常工作 Perl 的系统上将跳过这些测试。

此版本还对 git rebase -i 进行了一个小的装饰性更新。开始变基时,您的 $EDITOR 可能会显示如下所示的内容:

pick c108101daa foo

pick d2a0730acf bar

pick e5291f9321 baz

你可以将该列表编辑为 break、reword 或 exec (以及许多其他作),Git 会很乐意执行你的 rebase。但是如果你更改了 rebase 的 TODO 脚本中的提交信息,它们实际上不会改变!

这是因为 TODO 脚本中显示的提交消息只是为了帮助你识别你正在变基的提交。(如果你想重写过程中的任何提交信息,你可以改用 reword 命令)。为了澄清这些消息是装饰性的,Git 现在会在它们前面加上一个 # 注释字符,如下所示:

pick c108101daa # foo

pick d2a0730acf # bar

pick e5291f9321 # baz

Git 2.50 现在在服务器上执行填充获取时,包括从 *.bundle 中通告它知道的所有引用,从而使启用 bundle-uri 的克隆更快。

最后但并非最不重要的一点是,git add -p(和 git add -i)现在在稀疏检出中工作得更顺畅了,因为不再需要扩展稀疏索引 。这是在逐步为与索引交互的 Git 命令添加稀疏索引兼容性的漫长工作之后的又一漫长的工作。

关注“AppFuns”微信公众号,发现更多有趣的产品
全部评论(0)