我想浏览包含标签的存储库日志。到目前为止,我可以打印所有提交的所有SHA,包括带有revwalk的标签。但是,每次我想使用commit oid提取标记信息时我都会收到错误
“请求的类型与ODB中的类型不匹配”
我可以看到revwalk报告的标签SHA包含git show-ref --tags
报告的SHA所以我不知道为什么标签查找不起作用。
以下是我使用的简化代码:
int error = 0;
git_oid oid;
git_revwalk *walk;
error = git_revwalk_new(&walk, m_repo);
git_revwalk_sorting(walk,
GIT_SORT_TOPOLOGICAL |
GIT_SORT_TIME);
git_revwalk_push_head(walk);
//git_revwalk_hide_glob(walk, "tags/*"); -- I want to see tags so I commented this one
while(git_revwalk_next(&oid, walk) == 0)
{
git_commit *commit;
char oidstr[10] = {0};
if(git_commit_lookup(&commit, m_repo, &oid)==0)
{
git_tag *tag = NULL;
int error = git_tag_lookup(&tag, m_repo, &oid);
if(error==0)
{
wxString tname(git_tag_name(tag));
data.push_back("["+tname+"] "+cltStr);
}
else
{
//It always land here with error no -3 and message: The requested type does not match the type in ODB
}
git_tag_free(tag);
const git_signature *author = git_commit_author(commit);
}
git_commit_free(commit);
}
git_revwalk_free(walk);
TL; DR
当我有git_tag对象时,我可以获得目标提交。现在我有目标提交,那么如何获得该提交下的标记?类似于git tag --points-at commit_SHA
更新
卡洛斯回答之后是我的新代码。现在的挑战是如何获得git_tag *。如你所见,我有git_reference *(名为ref),但我不知道如何将其转换为git_tag *
git_reference_iterator *iter = NULL;
git_reference *ref = NULL;
git_reference_iterator_glob_new(&iter, m_repo, "refs/tags/*");
while(git_reference_next(&ref, iter) == 0)
{
git_object *target = NULL;
git_object *obj;
const git_oid *targetId = git_reference_target(ref);
git_object_lookup(&obj, m_repo, targetId, GIT_OBJ_ANY);
git_object_peel(&target, obj, GIT_OBJ_COMMIT);
if(git_oid_equal(git_commit_id(commit), git_commit_id((git_commit*)target))==1)
{
//tag found
//how do I get a git_tag* here?
}
git_object_free(obj);
git_reference_free(ref);
git_object_free(target);
}
答案 0 :(得分:1)
带注释的标记是它自己的对象,它作为对象图的根存在。 I.E.他们指向对象,但没有任何东西指向他们[0]所以如果你想找出反向映射,你需要自己保留列表。这就是git tag --points-at
反向映射的作用:获取标签列表及其指向的内容,然后在该列表中查找您感兴趣的ID。
使用libgit2,您可以使用引用迭代器查看refs/tags/
下的任何内容(git_reference_iterator_glob_new(&iter, repo, "refs/tags/*"))
并获取引用的目标(git_reference_target()
),使用git_object_peel()
进入提交(或您感兴趣的任何其他对象类型),然后将该对象的id与您正在寻找的ID进行比较。
就问题中的代码而言,git_tag_lookup
与所有其他对象查找函数一样,查找您要求它的注释标记(git_tag
对象)。如果你传入一个提交的id,那么它将加载该提交并看到类型不匹配并给出这个错误。
[0]虽然标签可以指向其他标签,但这与此案例无关
<强>更新强>
更新后的代码需要做的是做你以前做过的事情。使用git_tag_lookup()
查找git_tag
对象,并将参考目标作为要查找的ID传递。但我们知道并非所有标记引用都指向标记对象。在许多项目中,标签直接指向提交。
您可以再次使用git_object_peel()
来尝试获取标记(GIT_OBJ_TAG
),如果没有带标注的标记,则会返回错误。
但是你还应该注意,如果你试图复制git tag --points-at
它不关心链中是否有注释标签。只要特定的标记引用可以解析为您提供的提交,它就会返回该结果。