我想浏览包含标签的存储库日志。到目前为止,我可以打印出所有提交的所有 SHA,包括带有 revwalk 的标签。但是,每次我想使用提交 oid 提取标签信息时,我都会收到错误
"The requested type does not match the type in 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);
长话短说
当我有 git_tag 对象时,我可以获得目标提交。现在我有了目标提交,那么如何获取该提交下的标签呢?类似于 git tag --points-at commit_SHA
更新
在 Carlos 的回答之后是我的新代码。现在的挑战是如何获得 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);
}
最佳答案
带注释的标签是它自己的对象,它作为对象图的根存在。 IE。它们指向对象,但没有任何东西指向它们[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
,它并不关心链中是否有带注释的标签。只要可以将特定标记引用解析为您提供的提交,它就会返回该结果。
关于c - 从 revwalk 提交中获取带注释的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36528576/