以下摘自Jenkins日志:
00:00:03.135 > git fetch --tags --progress git@github.com:some_org/some_repo.git +refs/heads/*:refs/remotes/origin/*
00:03:49.659 > git rev-parse origin/master^{commit} # timeout=10
我对此超时的原因感到困惑,因为在同一台计算机上使用同一用户运行git fetch
大约需要5到10秒。
我使用的是最新的(在撰写本文时)Git版本(2.1.2)和最新版本的gitplugin。
思想?
答案 0 :(得分:5)
至少在我们的案例中,问题是git版本。 我们从1.9升级到2.1.2,问题得到了解决。 当我第一次发布问题时,我的错误印象是升级已经发生..
答案 1 :(得分:3)
注意:Git获取速度应该会随着Git 2.2+(2014年11月)再次提高
请参阅commit cbe7333,Jeff King(peff
):
is_refname_available
我们的文件系统引用存储不允许D / F(目录/文件)冲突;因此,如果存在“
refs/heads/a/b
”,则不允许存在“refs/heads/a
”(反之亦然)。
对于松散的引用,这自然会失败,其中文件系统强制执行条件。但 对于打包参考,我们必须自己做检查。我们通过迭代整个packed-refs命名空间并检查每个名称是否产生冲突来实现。如果你有非常多的引用,这是非常低效的,因为你最终与ref树的不感兴趣的位进行了大量的比较(例如,我们知道所有的“
refs/tags
“在上面的示例中无趣,但我们检查其中的每个条目。”相反,让我们利用这样一个事实,即我们将打包的refs存储为
ref_entry
结构的trie。
当我们走过树时,我们可以找到建议的refname
的每个组成部分,在我们去的时候检查D / F冲突。对于refname
深度N
(即上例中为4),我们只需要访问N
个节点。在每次访问时,我们都可以对该级别的M
名称进行二分搜索,总复杂度为O(N lg M)
。 (当然,“M
”在每个级别都有所不同,但我们可以将最坏情况下的“M
”作为约束。在一个病态案例中,将30,000个新的refs提取到一个拥有850万个refs的存储库中,这使得“git fetch”的运行时间从几十分钟缩短到~30秒。
这也可能有助于我们检查松散引用的较小情况(我们在重命名引用时执行),因为我们可以避免对不相关的松散目录进行磁盘访问。
请注意,我们添加的测试乍一看似乎是t3210中已有的冗余。然而,早期测试并不健全;他们在打开reflog的情况下运行, 这意味着我们实际上根本没有测试
is_refname_available
! 操作仍然会失败,因为reflog会遇到文件系统中的D / F冲突 要获得真正的测试,我们必须关闭reflogs(但我们不希望对整个脚本执行此操作,因为打开它们的目的是为了涵盖其他一些情况)。