我想获得自上一个标记以来提交的数量。使用常规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/*");
。
答案 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个父母(这将是一种罕见的情况,但您会发现所有野外各种奇怪的东西。)