首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在多个提交的存储库上加速` `git blame`

在多个提交的存储库上加速` `git blame`
EN

Stack Overflow用户
提问于 2019-09-08 06:52:24
回答 2查看 789关注 0票数 3

我正在尝试git blame以下文件(在我的本地机器上运行),因为它太慢了,无法生成GitHub的错误:

https://github.com/Homebrew/homebrew-core/blob/master/Formula/sqlite.rb

但是在本地运行它也非常慢,在我的机器上运行超过一分钟

存储库包含超过15万个提交。

有没有一种方法可以加快git blame命令的执行速度?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-08 10:32:15

根据Git标准,自制核心存储库相当大。一个250MB的存储库,对于4000个“公式”,提交了150,000个。这可能会影响性能。Github确实遇到了麻烦。

在我的2018年i7 Macbook上使用Git2.22.0时,git blame Formula/sqlite.rb大约需要45秒。虽然以Git标准来说速度很慢,但考虑到运行git blame的频率,这是可以接受的。

作为这个存储库的用户,没什么可做的。git blame必须向后搜索每个提交,以查看哪些提交更改了此文件。不幸的是,git blame似乎没有利用并行处理的优势。

有一些选择..。

就这个问题联系Github,希望他们能解决这个问题。

限制你回顾历史的时间:git blame --since=1.year in Formula/sqlite.rb

重新考虑在此存储库上需要快速git blame的任何进程。

缓存结果。

票数 1
EN

Stack Overflow用户

发布于 2020-05-03 03:57:56

在Git2.27 (Q2 2020)中,"git blame“学会利用存储在提交图文件中的"changed-paths”布隆过滤器,并在git log中引入。

参见Jeff King (peff)的commit 1b4c57f,commit 24b7d1e,commit fe88f9f (2020年4月23日)。

见Derrick Stolee (derrickstolee)的commit 0906ac2,commit b23ea97,commit 8918e37 (2020年4月16日)。

(由Junio C Hamano -- gitster合并,提交6d56d4c,2020年5月1日)

blame:使用changed-path布隆过滤器

签名者: Derrick Stolee

changed-path布隆过滤器有助于减少历史查询过程中所需的树解析次数。

在计算diff之前,我们可以询问过滤器是否在提交和它的第一个父级之间更改了路径。

如果筛选器说“不”,那么我们可以在不解析树的情况下继续进行操作。

如果过滤器说“可能”,那么我们解析树来发现答案实际上是“是”还是“否”。

在计算指责时,find_origin()中有一个部分计算提交和它的一个父级之间的差异。

当这是第一个父级时,我们可以在调用diff_tree_oid()之前检查布隆过滤器。

为了使这与指责机制一起工作,我们需要用初始路径初始化一个结构bloom_key。但是,如果检测到重命名,我们还需要向列表中添加更多的键。然后,我们检查这些键中是否有任何键在diff中回答“可能”。

如果用户使用"git blame -C“请求复制检测,那么有更多地方可以扩展”重要“文件集。我对这是如何在指责机制中发生的了解还不够。

因此,Bloom filter集成在此模式下被显式禁用。

稍后的更改可以通过对add_bloom_key()的适当调用(或多个调用)来扩展bloom_key数据。

一般来说,这是一个性能增强,不应该以任何方式改变'git blame‘的行为。

如果存储库有一个带有计算的更改路径布隆过滤器的提交图文件,那么他们应该注意到他们的'git blame‘命令的性能提高了。

以下是我通过指责Linux内核存储库中的一些路径发现的一些示例计时:

git blame arch/x86/kernel/topology.c >/dev/null`

前: 0.83s后: 0.24s

git blame kernel/time/time.c >/dev/null

前: 0.72s后: 0.24s

git blame tools/perf/ui/stdio/hist.c >/dev/null

前: 0.27s后: 0.11s

我特别寻找了“深度”路径,这些路径也被编辑了很多次。

与此相对的是,MAINTAINERS文件被编辑了多次,但它位于根树中。

这意味着相对于路径规范计算diff的成本非常小。下面是该命令的时间:

git blame MAINTAINERS >/dev/null

之前: 20.1s之后: 18.0s

这些计时是五个计时中最好的。

对于这两种情况,最坏的运行时间都在2.5分钟左右。

注意,在17,000+提交中,MAINTAINERS文件有18,740行。这恰好是这种更改提供的改进最少的情况之一。

MAINTAINERS文件没有改进,而其他示例的改进相对较小,这很容易解释。

指责机制需要计算行级差异,以确定每次提交更改了哪些行。这占了计算时间的很大一部分,而且这种更改并不会试图改进算法的这一部分。

MAINTAINERS文件很大,而且经常更改,因此需要花费一些时间来确定哪些行是由哪个commit更新的。相比之下,代码文件要小得多,计算Linux邮件列表中单个补丁的逐行差异所需的时间也更长。

除了"-C“集成之外,我相信在此补丁之后,从”git blame“的更改路径布隆过滤器中获得的好处不多。

不过,请确保使用Git2.29 (Q4 2020),因为有一个小错误:

见Edmundo Carmona Antoranz (eantoranz)提交的1302ad(2020年9月8日)。

(由Junio C Hamano -- gitster合并-在commit e1dd499,2020年9月18日)

blame.c:替换oideq!oidcmp实例

署名者: Edmundo Carmona Antoranz

0906ac2b ("blame:use changed-path Bloom filters",2020-04-16,Git v2.27.0-rc0 -- oideq()在批次#6中列出)引入了对oidcmp()的调用,该调用在14438c44中引入(“引入hasheq()oideq()",2018-08-28,Git v2.20.0-rc0 --合并在批次#1中列出)。

在Git2.29 (Q4 2020)中,"git commit-graph(man) write“学会了使用--max-new-filters选项限制从头开始计算的布隆过滤器的数量。

这将使git blame受益。

参见提交d356d5d,提交98bb796,提交59f0d50,提交97ffa4f (2020年9月17日),提交809e032 (2020年9月18日),提交9a7a9ed,提交312cff5 (2020年9月16日),以及Taylor Blau (ttaylorr)的commit b66d847,commit 24f951a,commit ab14d06,commit 025d529,commit 4f36440 (2020年9月9日)。

参见Derrick Stolee (derrickstolee)的commit b16a827 (2020年9月16日)。

(由Junio C Hamano -- gitster合并,提交288ed98,2020年9月29日)

builtin/commit-graph.c:引入‘--max-new-filter=’

帮助: Junio C Hamano

签名者:泰勒·布劳

引入命令行标志来指定“git commit-graph write”(Man)愿意从头开始计算的新布隆过滤器的最大数量。

在此补丁之前,使用'--changed-paths‘的提交图写入将为所有尚未计算的选定提交计算布隆过滤器(即,通过使用'--split’的前一次提交图写入,以便执行上卷或替换)。

由于各种原因,此行为可能会导致长得令人望而却步的提交图写入:

可能有很多过滤器的差异需要很长时间才能生成(例如,它们的变化次数接近最大值,差异本身需要很长时间,等等)。

老式的提交图(对带有太多条目的过滤器进行编码,因为根本没有计算过)导致我们浪费时间重新计算似乎没有计算过的过滤器,结果发现它们太大了。

这可能会使'git commit-graph write --changed-paths'(man)所需时间的上限变得相当不可预测。

要使此命令的行为更具可预测性,请引入“--max-new-filters=”,以允许从头开始计算至多“”布隆过滤器“。

这让“计算”已知的过滤器快速进行,同时限制了Git愿意完成的缓慢任务的数量。

git commit-graph现在的手册页中包括

使用--max-new-filters=选项,最多生成n新的布隆过滤器(如果指定了--changed-paths )。

如果n-1,则不强制执行任何限制。

只有出现在新层中的提交数才会计入此限制。

要追溯计算早期层上的布隆过滤器,建议使用--split=replace

使用Git2.31 (Q1 2021),在"git blame"(man)中进行优化

见Rafael Silva (raffs)提交的8e16efff(2021年2月17日)。

(由Junio C Hamano -- gitster合并,提交18decfd,2021年2月25日)

blame:删除不必要的get_commit_info()使用

签发人:拉斐尔·席尔瓦

审阅者: Taylor Blau

git blame(man)为--color-by-age时,将调用determine_line_heat()来选择如何根据提交的作者日期对输出进行着色。

它使用get_commit_info()将信息解析为commit_info结构,但是,这实际上是不必要的,因为determine_line_heat()调用者也执行同样的操作。

相反,让我们将determine_line_heat()更改为采用commit_info结构,并删除对get_commit_info()的内部调用,从而清理和优化代码路径。

开启Git的trace2接口,记录每次调用determine_line_heat()函数的执行时间:

trace2_region_enter("blame","determine_line_heat",the_repository);determine_line_heat(ent,&default_color);+ trace2_region_enter("blame","determine_line_heat",the_repository);

然后,在linux.git中为"kernel/fork.c“运行git blame,并对每个调用(大约1.3k个调用)的所有执行时间进行求和,结果是执行速度提高了2.6倍(最佳输出3):

从328c109303 (第八批,2021-02-12)构建的git =从328c109303构建的git = 42ms +此更改= 16ms

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57837986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档