2016-04-10 4 views
1

Ich möchte Repository-Protokolle einschließlich Tags gehen. Bisher kann ich alle SHA für alle Commits inklusive Tags mit Revwalk ausdrucken. Allerdings will jedes Mal, wenn ich die Tag-Informationen ziehen, die begehen mit oid ich Fehler bekommenGet Annotated Tags von Revwalk commit

„Der angeforderte Typ nicht die Art in ODB überein“

ich, dass der Tag SHA gemeldet sehen von Revwalk enthält die SHA gemeldet von git show-ref --tags Also ich weiß nicht, warum Tag-Lookup nicht funktioniert.

Hier ist der vereinfachte Code, die ich benutze:

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

Wenn ich bezwecken git_tag ich das Ziel verpflichten bekommen. Jetzt habe ich das Ziel-Commit, also wie bekomme ich die Tags unter diesem Commit? Etwas ähnliches wie git tag --points-at commit_SHA

UPDATE

Nach Carlos' Antwort hier ist mein neuer Code. Die Herausforderung besteht nun darin, wie ich den git_tag * bekomme. Wie man sehen kann ich git_reference * (benannt ref), aber ich weiß nicht, wie es zu konvertieren * 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); 
} 

Antwort

1

Ein kommentierte Tag seine eigene Aufgabe ist es, die als Wurzel des Objektgraphen existiert. I.E. Sie zeigen auf Objekte, aber nichts zeigt auf sie [0]. Wenn Sie also das umgekehrte Mapping herausfinden wollen, müssen Sie die Liste selbst behalten. Dies ist, was git tag --points-at umgekehrte Zuordnung tut: Nehmen Sie eine Liste von Tags und was sie zeigen und dann in dieser Liste nach der ID Sie interessiert sind.

Mit libgit2 können Sie dies tun, indem Sie eine Referenz-Iterator über alles unter refs/tags/() und nehmen Sie das Ziel der Referenz (git_reference_target()), verwenden Sie git_object_peel(), um zum Festschreiben (oder einem anderen Objekttyp, die Sie interessiert sind) und vergleichen Sie die ID dieses Objekts mit dem Sie sind Suche nach.

Soweit der Code in der Frage geht, sieht git_tag_lookup, wie jede andere Objekt-Lookup-Funktion, das annotierte Tag nach dem Sie es fragen (ein git_tag Objekt) Wenn Sie die ID eines Commits übergeben, wird das Commit geladen und festgestellt, dass die Typen nicht übereinstimmen und diesen Fehler enthalten.

[0] Obwohl Tags zu anderen Tags zeigen kann, das ist nicht relevant für diesen Fall

UPDATE

Was der aktualisierte Code braucht, ist zu tun, was Sie, bevor Sie wurden. Verwenden Sie git_tag_lookup(), um ein Objekt git_tag nachzuschlagen, und übergeben Sie das Referenzziel als ID, um nachzuschlagen. Wir wissen jedoch, dass nicht alle Tag-Referenzen auf ein Tag-Objekt verweisen. In vielen Projekten verweisen Tags direkt auf die Commits.

Sie können git_object_peel() erneut verwenden, um ein Tag (GIT_OBJ_TAG) zu erhalten, das einen Fehler zurückgibt, wenn es kein annotiertes Tag gibt.

Aber Sie sollten auch beachten, wenn Sie versuchen, git tag --points-at zu replizieren, dass es egal ist, ob es annotierte Tags in der Kette sind. Solange eine bestimmte Tag-Referenz zu dem Commit aufgelöst werden kann, das Sie angegeben haben, wird das Ergebnis zurückgegeben.

+0

Vielen Dank für detaillierte Antwort. Jetzt kann ich sehen. Können Sie jedoch erklären, was Peel genau macht? Ich habe versucht, es von Docs zu verstehen (in all diesen Tagen habe ich dieses Problem bekämpft), aber ich konnte es nicht in mein Gehirn bekommen. Nochmals vielen Dank! –

+0

Ich habe versucht, die ausgezeichnete Erklärung zu verstehen, aber bisher konnte ich das nicht. Können Sie ein einfaches, ungetestetes Beispiel schreiben, um Ihre Punkte zu verdeutlichen? Ich kann sie nicht kombinieren, um zu bekommen, was ich will. –

+0

Ich habe versucht, Ihre Kommentare jetzt anzuwenden Ich habe neuen Code und Herausforderung, siehe aktualisierten Beitrag. Vielen Dank –

Verwandte Themen