从revwalk commit获取带注释的标记
我想查看存储库日志,包括标签。到目前为止,我可以打印所有提交的所有SHA,包括带有revwalk的标记。但是,每次我想使用提交oid提取标记信息时,我都会得到一个错误 “请求的类型与ODB中的类型不匹配” 我可以看到revwalk报告的标签SHA包含git show ref--tags报告的SHA,所以我不知道为什么标签查找不起作用 以下是我使用的简化代码:从revwalk commit获取带注释的标记,c,libgit2,C,Libgit2,我想查看存储库日志,包括标签。到目前为止,我可以打印所有提交的所有SHA,包括带有revwalk的标记。但是,每次我想使用提交oid提取标记信息时,我都会得到一个错误 “请求的类型与ODB中的类型不匹配” 我可以看到revwalk报告的标签SHA包含git show ref--tags报告的SHA,所以我不知道为什么标签查找不起作用 以下是我使用的简化代码: int error = 0; git_oid oid; git_revwalk *walk; error = git_revwalk_n
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;博士
当我有git_标记对象时,我可以得到目标提交。现在我有了目标提交,那么如何获得该提交下的标记呢?类似于git标记的东西——指向commit\u SHA
更新
卡洛斯回答后,这是我的新密码。现在的挑战是如何获得git_标记*。如您所见,我有git_reference*(命名为ref),但我不知道如何将其转换为git_标记*
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],因此,如果您想找出反向映射,您需要自己保留该列表。这就是git标记所指向的的反向映射所做的:获取标记列表及其指向的内容,然后在该列表中查找您感兴趣的id 使用libgit2,您可以使用引用迭代器查看
refs/tags/
下的任何内容(git\u reference\u iterator\u glob\u new(&iter,repo,“refs/tags/*))
并获取引用的目标(git\u reference\u target()
),使用git\u object\u peel()
进行提交(或您感兴趣的任何其他对象类型),然后将该对象的id与您要查找的id进行比较
就问题中的代码而言,git_tag_lookup
,与其他所有对象查找函数一样,查找您要求它查找的带注释的标记(一个git_tag
对象)。如果您传入提交的id,它将加载该提交,并查看类型不匹配,并给出此错误
[0]虽然标记可以指向其他标记,但这与本例无关
更新
更新后的代码需要执行您以前所做的操作。使用git\u tag\u lookup()
查找git\u tag
对象,并将引用目标作为要查找的id传入。但我们知道,并非所有标记引用都指向标记对象。在许多项目中,标记直接指向提交
您可以再次使用git\u object\u peel()
尝试获取标记(git\u OBJ\u tag
),如果没有带注释的标记,该标记将返回错误
但您还应该注意,如果您试图复制
git标记--指向
,它并不关心链中是否有带注释的标记。只要特定的标记引用可以解析为您给出的提交,它就会返回该结果。非常感谢您提供的详细答案。现在我可以看到了。不过,您能解释一下果真如此?我试着从文档中理解它(在那些日子里,我一直在与这个问题作斗争)但我无法将它输入我的大脑。再次感谢你!我试图理解这个优秀的解释,但到目前为止我还无法理解。你能写一个简单的未经测试的例子来说明你的观点吗?我无法将它们结合起来得到我想要的。我已经尝试应用你的评论,现在我有了新的代码和挑战,请参阅更新的po圣。谢谢