我有一个生产工具,它可以在一个大型仓库中调用git rev-list,每分钟10-30次。我看到git响应时间变化很大,从大约1秒到多达50秒(在超时机制放弃git请求之前)。
git rev-list --pretty=raw 2ef9fa0d0fa4c34d57103a0545b3cc96c2552e6f..f5daa48ebcd3cc95a0df683f8c3a3ad64def4a6e
目标是看两个提交是祖先/后代,如果是,那么两个中的哪个是祖先。我做了一次这个调用,如果我得到输出我有我的答案,如果没有输出,我交换提交位置再次运行。如果这次没有输出那么他们就不是彼此的祖先/后代。
还有另一种更有效的方法来查找此信息吗?如果涉及它,甚至建议在git之外的某些结构中对提交树进行建模。
感谢。
答案 0 :(得分:1)
看看git merge-base first-sha1 second-sha1
。如果结果是第三个sha1,则它们不是后代。否则,结果就是年长的祖先。
但是,如果您可以在更高级别描述一些工作流程,那么可能有一种更简单的方法,您可能不必依赖于此。我写了这篇关于每个特征分支的文章:http://dymitruk.com/blog/2012/02/05/branch-per-feature/它可能会给你一些想法。
答案 1 :(得分:0)
git merge-base(甚至是git rev-list
)在以下情况下甚至更快:
这是因为两者都是基于“承诺可以到达”的概念。
最近的更新打破了可及性算法,其中涉及到指向未提交对象的引用(例如标记),该问题已得到修复。
请commit 4067a64参阅commit b67f6b2,commit 6621c83(2018年9月21日),commit 6cc01743(2018年8月28日)和Derrick Stolee (derrickstolee
)(2018年7月20日)。
(由Junio C Hamano -- gitster
--在commit 0f7ac90中合并,2018年9月24日)
commit-reach
:使用can_all_from_reach
以前的
is_descendant_of
方法使用in_merge_bases()
来检查提交是否可以到达提供的列表中的任何提交。 这有两个性能问题:
在最坏的情况下,性能是二次方。
单个
in_merge_bases()
调用需要超出目标提交,才能找到可能是合并基础的完整边界提交集。
can_all_from_reach
方法避免了这种二次行为,并且可以使用世代号将搜索限制在目标提交以外。 需要进行一些小的原型调整才能停止使用commit-date
作为截止值,因为这种优化在这里不再适用。由于
in_merge_bases()
使用paint_down_to_common()
,因此is_descendant_of()
自然会找到截止点,以避免遍历整个提交图。 由于我们希望始终返回正确的结果,因此我们不能在min_commit_date
中使用can_all_from_reach
截止值。然后,我们依靠世代号来提供截止值。由于并非所有存储库都具有提交图文件,我们也不总是为提交图文件计算世代号,因此请创建一个新方法
generation_numbers_enabled()
来检查提交图文件,并查看文件中的第一次提交是否具有非零的世代号。 如果我们没有世代号,请对is_descendant_of()
使用旧的逻辑。使用“
test-tool reach is_descendant_of
”命令并使用以下输入来测量Linux存储库副本上的性能:A:v4.9 X:v4.10 X:v4.11 X:v4.12 X:v4.13 X:v4.14 X:v4.15 X:v4.16 X:v4.17 X.v3.0
请注意,此输入量身定制,以展示先前方法的二次性质,因为它将在对照v4.1进行检查之前计算v4.9与所有更高版本的合并基础。
Before: 0.26 s After: 0.21 s
由于我们先前在
ref_newer
方法中使用过is_descendant_of方法,因此我们在输入时也使用了'test-tool reach ref_newer
'来测量性能:A:v4.9 B:v3.19 Before: 0.10 s After: 0.08 s
通过使用父v3.19添加新的提交,我们测试了无法访问的情况 ref_newer:
Before: 0.09 s After: 0.08 s
在Git 2.20(2018年第四季度)之前,(实验性)提交图文件的生成到目前为止还相当安静,尽管在一个有意义的大型存储库中花费了大量的时间。
用户现在将看到进度输出。
请参见commit 6b89a34的commit 1f7f557(2018年9月19日)和commit 7b0f229,Ævar Arnfjörð Bjarmason (avar
)(2018年9月17日)。
帮助:马丁·阿格伦(MartinÅgren)。
(由Junio C Hamano -- gitster
--在commit 36d767d中合并,2018年10月16日)
使用Git 2.21(2019年第一季度),该进度将更加准确:
请参见commit 01ca387的Ævar Arnfjörð Bjarmason (avar
)(2018年11月19日)。
帮助者:Derrick Stolee (derrickstolee
)。
(由Junio C Hamano -- gitster
--在commit d4c9027中合并,2019年1月14日)
commit-graph
:拆分close_reachable()
进度输出修改7b0f229(“
commit-graph write
中添加的进度输出: 添加进度输出”,2018-09-17),以便它报告的总数 不再高于提交总数了。
请参见this thread,以获得指出该错误的错误报告。添加此内容时,我无意提供准确的计数,but just have some progress output to show the user the command wasn't hanging。但是,由于我们显示的是数字,所以让我们来制作 准确。 The progress descriptions were suggested by Derrick Stolee。
As noted in the original thread,即使在大型存储库(例如,
linux.git
。
在测试库中,我的提交次数超过了700万次 所有这些都将显示。其中两个不会出现很长时间,但是 noted in future-proofing这个人
并且(仍然是Git 2.21,Q1 2019),改进了在写入提交图文件时显示进度表的代码路径。
请参见commit 49bbc57,commit 890226c,commit e59c615,commit 7c7b8a7,commit d9b1b30,commit 2894473,commit 53035c4(2019年1月19日)由Ævar Arnfjörð Bjarmason (avar
)。
请参见commit 857ba92的commit 5af7417(2019年1月23日)和SZEDER Gábor (szeder
)(2019年1月19日)。
(由Junio C Hamano -- gitster
--在commit e5eac57中合并,2019年2月5日)
commit-graph
编写:添加中间进度将进度输出添加到“
Annotating[...]
”和“ “Computing[...]generation numbers
”。
在足够大的存储库上,这可能总共需要5-10秒。在我拥有的测试存储库中,拥有约700万次提交和约5000万个对象,我们现在将发出:
$ ~/g/git/git --exec-path=$HOME/g/git commit-graph write Finding commits for commit graph among packed objects: 100% (124763727/124763727), done. Loading known commits in commit graph: 100% (18989461/18989461), done. Expanding reachable commits in commit graph: 100% (18989507/18989461), done. Clearing commit marks in commit graph: 100% (18989507/18989507), done. Counting distinct commits in commit graph: 100% (18989507/18989507), done. Finding extra edges in commit graph: 100% (18989507/18989507), done. Computing commit graph generation numbers: 100% (7250302/7250302), done. Writing out commit graph in 4 passes: 100% (29001208/29001208), done.
在
linux.git
这样的中型存储库中,这些新进度条将没有时间像往常一样投入使用,我们仍然会发出类似以下的输出:$ ~/g/git/git --exec-path=$HOME/g/git commit-graph write Finding commits for commit graph among packed objects: 100% (6529159/6529159), done. Expanding reachable commits in commit graph: 815990, done. Computing commit graph generation numbers: 100% (815983/815983), done. Writing out commit graph in 4 passes: 100% (3263932/3263932), done.