我有一组提交SHA1,没有特别的顺序。我想将此set管道传递给命令,并按拓扑顺序返回这些提交。
以下是这样做的一种方式:
git rev-list --all --topo-order | grep --file SET_OF_SHA1S
您可以想象,这是一种非常缓慢的方式,因为git rev-list
必须打印出所有提交SHA1,而不仅仅是我的集合中的那些。
有更好更快的方法吗?
我的测试框架测试某些Git提交并将结果存储在数据库中。我正在编写一个总结这些结果的网页,按顺序显示结果会很不错。按提交日期排序并不理想,因为某些重新提交的提交将具有完全相同的提交日期。
答案 0 :(得分:5)
这是加快速度的一种方法:
git rev-list --topo-order $(cat SET_OF_SHA1S) \
| grep --file SET_OF_SHA1S --max-count $(wc -l SET_OF_SHA1S)
的优化:
rev-list
列出从您的SHA1集中可以访问的所有提交。rev-list
打印出包含您感兴趣的SHA1集的足够提交,请告诉grep
停止使用--max-count
参数进行grepping。 grep
将依次关闭其输入,rev-list
将不必要地打印出更多的SHA1。答案 1 :(得分:4)
您可以使用 As {{ 3}},这不起作用。 git文档获得了新文本(间接)注意到这个问题,如git版本2.4。 (我认为这是--no-walk
来阻止git转储除您提供的SHA-1以外的任何SHA-1,并使用--topo-order
强制执行正确的命令。git rev-list
中的一个错误,它应该加载足够的提交图来进行拓扑排序,然后以正确的顺序输出用户指定的修订ID。)
因此我的原始脚本(此处留下)也不起作用。可以通过从生成临时文件--no-walk
的步骤中删除$TF2
,然后使用$TF1
的内容来提取和打印有趣的"来使其工作。来自$TF2
(已排序)订单的修订。
这或多或少是Mort pointed out in a comment所做的。
[原始答案,有缺陷的剧本,下面]
我不确定我在使用这段代码做了什么,但很久以前,我写了一个脚本来检查所提供的参数是否按地形顺序排列:
#! /bin/sh
#
# check a list of IDs to see if they're in "topo order"
usage()
{
echo "usage: $0 id [...]"
}
case $# in
0) usage 1>&2; exit 1;;
esac
TF1=$(mktemp)
TF2=$(mktemp)
trap "rm -f $TF1 $TF2; exit" 0 1 2 3 15
# parse the arguments into one file
git rev-parse $@ > $TF1 || exit 1
# and topo-sort the arguments into another
git rev-list --topo-order --no-walk --reverse $@ > $TF2 || exit 1
# If the list is in the correct order the files will be the same
cmp -s $TF1 $TF2 || {
# If the files differ, it's possible that some argument(s) name
# the same rev...
[ $(wc -l < $TF1) -eq $(wc -l < $TF2) ] || {
echo "ERROR: there are repeats in $@"
# finding them is a pain, we don't bother trying
exit 1
}
echo "ERROR: $@ NOT in topo order"
echo "use instead:"
# read the topo-ordered raw IDs
while read sha1; do
# and find the (single) arg in $@ that names this one
for i; do
if [ $(git rev-parse $i) = $sha1 ]; then
printf ' %s' $i
break
fi
done
done < $TF2
echo
exit 1
}
echo "$@ in topo order"
exit 0
我认为我想要的是发出相同的参数名称,例如,如果你说git-check-topo v1.7 1234567 branchX
它会告诉你使用(字面意思)branchX v1.7 1234567
,如果这就是让你获得正确顺序的原因,而不仅仅是显示原始的SHA-1。
为了您的目的,一个简单的:
git rev-list --topo-order --no-walk $@
我认为(根据需要使用或不使用--reverse
)。
答案 2 :(得分:1)
加快git rev-list --topo-order
速度的另一种方法是使用Git 2.20(2018年第四季度)
请参见commit 561b583,commit b454241,commit 5284fc5,commit f0d9cc4,commit d6b4071,commit 4b47a9a,commit aca4240(2018年11月1日)由Derrick Stolee (derrickstolee
)。
(由Junio C Hamano -- gitster
--在commit 62ca33e中合并,2018年11月18日)
revision.c
:基于世代的拓扑顺序算法
当前的--topo-order
算法要求在输出第一个值之前先遍历所有可到达的提交,并对它们进行拓扑排序。
此补丁引入了新算法,该算法使用存储的世代号 逐步进入拓扑顺序,在我们进行时输出提交。
这样可以大大减少编写固定数量的提交的计算时间,例如在使用“-n <N>
”进行限制或填充寻呼机的第一页时。在本地测试中,我在Linux系统信息库中以以下三种模式使用了以下Git命令:
HEAD~1
,没有提交图,HEAD~1
和提交图,以及- 带有提交图的HEAD。
这允许比较通过从提交图解析提交而获得的收益,然后再通过限制遍历的提交集来再次获得收益。
Test: git rev-list --topo-order -100 HEAD HEAD~1, no commit-graph: 6.80 s HEAD~1, w/ commit-graph: 0.77 s HEAD, w/ commit-graph: 0.02 s
查看commit b454241中的所有详细信息。
注意:如commit d6b4071中所述:
rev-list命令对Git的功能至关重要。
以下是一些重要的rev-list操作类型:
- 基本:
git rev-list --topo-order HEAD
- 范围:
git rev-list --topo-order compare..HEAD
- 祖先:
git rev-list --topo-order --ancestry-path compare..HEAD
- 对称差异:
git rev-list --topo-order compare...HEAD