【问题标题】:Efficient retrieval of releases that contain a commit有效检索包含提交的版本
【发布时间】:2012-06-05 00:08:43
【问题描述】:

在命令行中,如果我输入

git tag --contains {commit}

要获取包含给定提交的发布列表,每次提交大约需要 11 到 20 秒。由于目标代码库存在超过 300,000 次提交,因此要为所有提交检索此信息需要花费很多时间。

但是,gitk 显然在检索这些数据方面做得很好。根据我的搜索,它为此使用了缓存。

我有两个问题:

  1. 如何解释这种缓存格式?
  2. 有没有办法从git 命令行工具获取转储以生成相同的信息?

【问题讨论】:

  • 实现您自己的 cli 缓存功能对您有用吗?如果是这样,我想我可以为此提出一些想法。
  • 是的,这对我有用。

标签: git


【解决方案1】:

您几乎可以直接从git rev-list 获得此信息。

latest.awk:

BEGIN { thiscommit=""; }
$1 == "commit" {
    if ( thiscommit != "" )
        print thiscommit, tags[thiscommit]
    thiscommit=$2
    line[$2]=NR
    latest = 0;
    for ( i = 3 ; i <= NF ; ++i ) if ( line[$i] > latest ) {
        latest = line[$i];
        tags[$2] = tags[$i];
    }
    next;
}
$1 != "commit"  { tags[thiscommit] = $0; }
END { if ( thiscommit != "" ) print thiscommit, tags[thiscommit]; }

一个示例命令:

git rev-list --date-order --children --format=%d --all | awk -f latest.awk

您也可以使用--topo-order,您可能必须在$1!="commit" 逻辑中清除不需要的引用。

根据您想要的传递性以及列表的明确程度,累积标签可能需要字典。这是一个获得所有提交的所有参考的明确列表:

all.awk:

BEGIN {
    thiscommit="";
}
$1 == "commit" {
    if ( thiscommit != "" )
        print thiscommit, tags[thiscommit]
    thiscommit=$2
    line[$2]=NR
    split("",seen);
    for ( i = 3 ; i <= NF ; ++i ) {
        nnew=split(tags[$i],new);
        for ( n = 1 ; n <= nnew ; ++n ) {
            if ( !seen[new[n]] ) {
                tags[$2]= tags[$2]" "new[n]
                seen[new[n]] = 1
            }
        }
    }
    next;
}
$1 != "commit"  {
    nnew=split($0,new,", ");
    new[1]=substr(new[1],3);
    new[nnew]=substr(new[nnew],1,length(new[nnew])-1);
    for ( n = 1; n <= nnew ; ++n )
        tags[thiscommit] = tags[thiscommit]" "new[n]

}
END { if ( thiscommit != "" ) print thiscommit, tags[thiscommit]; }

all.awk 花了几分钟来完成 322K 的 linux 内核 repo 提交,大约每秒 1000 次或类似的东西(大量重复的字符串和冗余处理)所以你可能想用 C++ 重写它,如果你'真的在追求完整的交叉产品......但我不认为 gitk 表明,只有最近的邻居,对吧?

【讨论】:

  • 所以向我们非 awk 用户澄清一下:这些脚本的作用与 git tag --contains {commit} 完全相同?
  • rev-list 的 %d 显示所有 ref 不只是标签所以 all.awk 获取所有标签和分支不仅仅是标签,但除此之外,all.awk 是一个批处理 --contains ...顺便说一句,学习 awk 不需要两个小时。
猜你喜欢
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 2013-08-06
  • 2015-04-14
  • 2019-03-30
  • 1970-01-01
  • 2017-05-08
  • 2013-04-24
相关资源
最近更新 更多