使用libgit2获取自上一个标记以来的提交数量

时间:2014-01-30 15:23:37

标签: c libgit2

我想获得自上一个标记以来提交的数量。使用常规git可以找到相同的结果:

git rev-list --count HEAD ^$(git describe --tags --abbrev=0)

使用C api中的libgit2。

我的尝试受到http://ben.straub.cc/2013/10/02/revwalk/的启发。我删除了错误检查以缩短代码。

git_revwalk *walk;
git_revwalk_new(&walk, repo);
git_revwalk_sorting(walk,
    GIT_SORT_TOPOLOGICAL |
    GIT_SORT_TIME);
git_revwalk_push_head(walk);
git_revwalk_hide_glob(walk, "tags/*");

int i = 0;
git_oid oid;
while (git_revwalk_next(&oid, walk) == 0) {
    git_commit *c;

    git_commit_lookup(&c, repo, &oid);
    if(git_commit_parentcount(c) == 1)
        i++;
    git_commit_free(c);
}
return i;

问题是计数i太大了。我认为关键部分是git_revwalk_hide_glob(walk, "tags/*");

1 个答案:

答案 0 :(得分:4)

最可能的情况是你有修改标记,修订版步行者不喜欢,因为它们不是提交对象,使得调用失败并且不排除任意数量的标记。在本地测试,

if (git_revwalk_hide_glob(walk, "tags/*") < 0)
    printf("error: %s\n", giterr_last()->message);

显示了确切的错误消息。我已经开始an issue提醒我看一下。

解决这个问题的一种方法是使用引用迭代器或foreach循环遍历标记(这是revwalk代码为你做的)并剥离目标,例如使用git_reference_peel

git_reference_iterator_glob_new(&iter, repo, "refs/tags/*");
while (git_reference_next(&ref, iter) == 0) {
    git_object *obj;

    /* go down to a commit object */
    git_reference_peel(&obj, ref, GIT_OBJ_COMMIT);
    /* and hide that */
    git_revwalk_hide(walk, git_object_id(obj));

    git_object_free(obj);
    git_reference_free(ref);
}

顺便说一句,如果在显示的提交中存在root提交,您的代码会错误计算提交次数。您应该检查< 2个父母是否排除合并,而不是== 1,或者您要删除根提交,其中有0个父母(这将是一种罕见的情况,但您会发现所有野外各种奇怪的东西。)