Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从revwalk commit获取带注释的标记_C_Libgit2 - Fatal编程技术网

从revwalk commit获取带注释的标记

从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

我想查看存储库日志,包括标签。到目前为止,我可以打印所有提交的所有SHA,包括带有revwalk的标记。但是,每次我想使用提交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;博士

当我有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圣。谢谢