# Git 2.24发布,新增feature宏、启用commit-graph和filter-repo等

日前Git官方邮件组宣布发布Git客户端新版本2.24,该版本包含了来自78个贡献者的功能增加和bug修复。其中带来一些激动人心的功能,比如特性宏,commit-graph,新可选全新的仓库历史重写工具filter-repo等。本文虫虫就带大家抢先尝鲜。

feature宏(feature.*)

从很开始,Git就附带一个配置子系统,可让我们配置不同的全局、用户级或者特定仓库级的设置。比如,我们第一次在电脑上做git 提交时,git会提醒要设置user.name和user.email。

实际上,git config可以做很多事情,从配置用户名称(user.name,user.email,author.name,author.email,committer.name,committer.email),设置文件断行符(ore.safecrlf)以及配置git命令别名(alias.*),git Diff的算法(diff.algorithm)等等。

一般情况下配置某些行为只需要配置一次即可,例如启用或禁用上面提到的这些参数。但是如果你不能确切的知道要更改哪些配置值时该怎么办?例如,假设你想尝试Git的最新功能,却没有发现新的可配置选项。在Git 2.24中,可以选择使用feature宏功能——一种包含许多其他功能的Git配置。这些是由Git的开发人员手动选择的,通过它可以选择加入某个功能或根据存储库的特性采用一些设置。

比如,有一个特别大的存储库,我们发现运行有些缓慢。通过参考各种文档,可能会找到答案,比如将index.version设置为4可能会有用。但是该探索的过程可能非常费劲,还不一定找得到最优的答案。但是现在你有了另外一种选择:通过下面方式启用feature.manyFiles:

这样,你就选择了Git最流畅体验的功能。通过配置该选项,表示愿意采用Git开发人员认为可以加速仓库的各种设置(包括index.version和core.untrackedCache分别启用路径前缀压缩和不跟踪的缓存)。

该配置项目以feature.开头,修改一组其他配置设置的默认值。这些组由Git开发人员社区创建,作为建议的默认值,可能会随时更改。目前feature宏功能只包括feature.experimental和feature.manyFiles,以后可能会新添加新的宏。feature.manyFiles上面已经介绍过了,feature.experimental则会默认开启以下配置:

在构造pack-file时使用了一种新算法,该算法可以提高多文件仓库时的git push性能。

可以一次跳过更多提交,从而减少往返次数,从而可以缩短获取协商的时间。

在每个从远程下载包文件的git fetch命令之后写入一个提交图。使用--split选项,大多数执行将在现有提交图文件之上创建一个非常小的提交图文件。有时,这些文件将合并,并且写入可能需要更长的时间。拥有更新的提交图文件可以提高很Git命令的性能,包括git merge-base,git push -f和git log --graph等。

默认启用提交图

在git 2.23中git引入了提交图。自从Git 2.19引入以来,此功能一直受到关注。启用提交图后可以将提交加载的性能提高一个数量级。

在Git 2.24中,默认会启用提交图,这样下次运行git gc时,你的仓库将有所改进。之前,此功能是在实验性core.commitGraph配置启用,但经过大量测试,已经可以默认启用。

除了作为新标准之外,这里还有一些提交图其他的改进:

所有提交图子命令(例如git commit-graph write,git commit-graph verify等)都支持-[no-] progress。现在,这些命令的进度表将以通常的方式运行:默认情况下仅写入终端,并遵循-[no-] progress来覆盖。

引入了一个新的配置值,用于在获取时自动更新提交图文件,该配置值利用提交图链将部分历史记录写入提交图链中,以供以后压缩。所以,每次从远程仓获取新提交时,都可以保证它们立即在提交图中,不必等下一次的auto-gc。功能可以通过设置fetch.writeCommitGraph为true来试用。

修复了许多错误,以改善commit-graph命令的性能和可靠性,尤其是在面对损坏的存储库时。

commit-graph命令现在还支持Git的最新跟踪机制trace2。

历史重写工具filter-repo

如果想对存储库的历史记录执行复杂的操作(例如从存储库的历史记录中删除文件或提取与一个目录有关的历史记录),可以试用git filter-branch。

git filter-branch是一个历史悠久的且功能强大的重写历史记录的工具。但是,,git filter-branch使用非常复杂,而且操作特别慢,并且经常会导致很多意想不到的误操作导致仓库库损坏和数据丢失。

Git 2.24发布,新增feature宏、启用commit-graph和filter-repo等

git filter-branch已经太老(12年前git 1.5.3引入)需要注入新鲜血液。

好消息是,Git 2.24中 Git项目新推荐一个更好的独立工具git filter-repo(github/newren/git-filter-repo)。git filter-repo可以避免用户在使用git filter-branch遇到的很多坑。git filter-repo无需按顺序重新处理每个提交,而是对历史记录进行高效的流表示,可以更高效地运作。该工具功能极其强大,其所有功能都具有详细的文档。下面是有关如何使用git filter-repo的一些要点:

git filter-repo --analyze提供了易于理解的度量选择,用于分析存储库的大小。这包括每种对象有多少个,文件和目录最大,扩展名占用最多空间,等等。当然,你可以试用同类的其他工具比如git size(github/github/git-sizer)。

可以使用--path-{glob,regex}和类似的选项来过滤存储库的历史记录,使其仅包含某些路径。

可以对历史记录以及大于固定阈值的blob对象执行"查找和替换"操作。

重写历史记录时,所有重写的提交(连同其祖先)将获得一个新的SHA-1来识别它们。默认情况下,git filter-repo会更新对这些SHA-1的所有其他引用,就像其他引用它们的提交消息一样。同样,git filter-repo也可以使用.mailmap选项来重写贡献者名称的。

最后,git filter-repo是可扩展的,它提供了一个灵活的接口,用于在Python中指定回调(例如,当git filter-repo遇到blob/tree/commit,新文件类型等时调用一个函数),以及完全定义新的子命令。详见其github官方仓库。

git filter-branch将在一段时间内仍包含在Git的常规发行版中。git filter-repo是对存储库的历史记录进行复杂修改的另一种方法,为Git官方建议软件。

更多功能

--end-of-options

大家可能已经知道,许多Git命令都使用一个或多个可选引用名称作为参数。例如,不带参数的git log将显示从当前已签出分支可以访问的所有内容的日志,但是git log my-feature ^master则只会显示my-feature上的内容,而不会显示master上的内容。

但是,如果分支称名为--super-dangerous-option,我们不能直接调用git log,该分支名会被解释为一个有破坏性的选项,从而导致危险操作。可以通过调用git log 'refs/heads/--super-dangerous-option'消除歧义,但是如果是在脚本中调用,则可能不知道所获取参数属于哪个名称空间。

Git 2.24中通过使用--end-of-options提供了一种防止这种选项注入攻击的新方法。当Git命令添加此选项后,其后的所有参数将会当做git操作对象而不是选项。

因此,前面提到例子,可以使用一下命令行:

避免使用--为对象名是git中的一个共识,因为git选项中广泛使用的它做为选项,用于将引用名称与文件分开,可以使用:

以获取特定文件范围内修改的历史记录。

--rebase-merges改进

git rebase的--rebase-merges选项允许用户在保留历史结构的同时执行rebase。但是,当Git遇到一个合并点时,它将如何统一这两个历史?默认情况下,它使用内部称为"递归"的策略,很可能是当前正在使用的合并策略。

可能不知道可以告诉Git使用哪种合并策略,而选择另一种合并策略可能会导致不同的结果。新版本中git rebase --rebase-merges支持git rebase的--strategy和--strategy-option选项,因此可以在保留历史记录的结构性的同时保留其结构完整性并指定自己的合并解析策略。

pre-merge-commitGit支持许多钩子,它们是特殊名称的可执行文件,可以以在git工作流程中的各个点执行。例如,在运行git push之后但在实际执行推送之前会调用pre-push钩子。

新版本中新添加了一个钩子,用来允许调用者在执行合并之后但在写入结果提交之前与Git进行交互。可以在.git/hooks/pre-merge-commit文件中加入自己的执行逻辑,以实现这种情况的脚本调用。

部分克隆优化

之前,git引入了部分克隆。对于那些不了解Git部分克隆人,官方说明中现在加入了详细文档。克隆仓库库时,用户可以使用过滤器来指定仅希望使用某些对象。这样做时,会将用户克隆的远程对象指定为"Promisor",这样如果用户在请求时候终端,可以可以承诺稍后继续请求剩余对象(断点续传)。

之前,Git仅支持一个远程Promisor。最新的git 2.24版本可以支持多个远程Promisor。这样用户可以配置少数几个地理上"近距离"远程仓,不必要所有的远程仓库都必须具有所有对象。

命令行补全

最后要介绍的是一个最实用的功能Git的命令行补全。​可以在每个命令配置中自动补全引擎自动补全配置变量。

Git具有可以找到gitconfig文件的位置的层次结构:存储库(通过.git/ config),主目录等等。但是,Git还支持顶级-c标志来为每个命令指定配置变量。比如:

该命令行用于在git add时候(以及其他可能调用git add的一部分其他命令)禁用Git的自动CRLF转换。如果忘记了设置Git的命令行完成引擎的变量名称 Git 2.24中提供配置变量名称的自动补全列表。因此,如果忘记了-c ...中间的位置,则只需按Tab。

你可能感兴趣的:(# Git 2.24发布,新增feature宏、启用commit-graph和filter-repo等)