我想得到自上一个标签以来提交的数量相同。使用常规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/*");
。
最有可能的情况是你有一个带注释的标签,修订版步行者不喜欢,因为它们不是提交对象,使得调用失败,并且不排除任意数量的标签。在本地测试,
if (git_revwalk_hide_glob(walk, "tags/*") < 0)
printf("error: %s\n", giterr_last()->message);
显示确切的错误消息。我打开qazxsw poi提醒我看看它。
解决它的一种方法是使用引用迭代器或foreach循环标记(这是revwalk代码为你做的)并剥离目标,例如使用an issue。
git_reference_peel
顺便说一下,如果在显示的提交中存在root提交,则代码会错误计算提交次数。你应该检查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);
}
父母排除合并,而不是< 2
,或者你要留下根提交,其中有0个父母(这将是一种罕见的情况,但你会在野外发现各种奇怪的事情) 。