reference.c (2396B)
1 #include "git/reference.h" 2 3 #include <err.h> 4 #include <git2/object.h> 5 #include <git2/oid.h> 6 #include <git2/refs.h> 7 #include <git2/types.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <time.h> 11 12 #include "git/internal.h" 13 #include "utils.h" 14 15 struct GitReference { 16 RefType type; 17 const char* shorthand; 18 GitCommit* commit; 19 20 git_reference* ref; 21 }; 22 23 GitReference* gitreference_create(git_repository* repo, 24 git_reference* git_ref) { 25 GitReference* ref = ecalloc(1, sizeof(GitReference)); 26 27 // Set ref. 28 if (git_reference_type(git_ref) == GIT_REFERENCE_SYMBOLIC) { 29 git_reference* direct_ref = NULL; 30 git_reference_resolve(&direct_ref, git_ref); 31 git_reference_free(git_ref); 32 git_ref = direct_ref; 33 } 34 if (!git_reference_target(git_ref)) { 35 errx(1, "git_reference_target"); 36 } 37 ref->ref = git_ref; 38 39 // Set type. 40 if (git_reference_is_branch(ref->ref)) { 41 ref->type = kReftypeBranch; 42 } else if (git_reference_is_tag(ref->ref)) { 43 ref->type = kReftypeTag; 44 } else { 45 errx(1, "not a branch or tag"); 46 } 47 48 // Set shorthand. 49 ref->shorthand = git_reference_shorthand(ref->ref); 50 51 // Create a GitCommit from the object. 52 git_object* obj = NULL; 53 git_reference_peel(&obj, git_ref, GIT_OBJECT_ANY); 54 const git_oid* id = git_object_id(obj); 55 git_object_free(obj); 56 if (!id) { 57 errx(1, "git_object_id"); 58 } 59 ref->commit = gitcommit_create(id, repo); 60 return ref; 61 } 62 63 void gitreference_free(GitReference* ref) { 64 if (!ref) { 65 return; 66 } 67 git_reference_free(ref->ref); 68 ref->ref = NULL; 69 gitcommit_free(ref->commit); 70 ref->commit = NULL; 71 free(ref); 72 } 73 74 RefType gitreference_type(const GitReference* r) { 75 return r->type; 76 } 77 78 const char* gitreference_shorthand(const GitReference* r) { 79 return r->shorthand; 80 } 81 82 GitCommit* gitreference_commit(const GitReference* r) { 83 return r->commit; 84 } 85 86 int gitreference_compare(const void* a, const void* b) { 87 GitReference* r1 = *(GitReference**)a; 88 GitReference* r2 = *(GitReference**)b; 89 int r = git_reference_is_tag(r1->ref) - git_reference_is_tag(r2->ref); 90 if (r != 0) { 91 return r; 92 } 93 94 time_t t1 = gitcommit_author_time(r1->commit); 95 time_t t2 = gitcommit_author_time(r2->commit); 96 if (t1 > t2) { 97 return -1; 98 } 99 if (t1 < t2) { 100 return 1; 101 } 102 return strcmp(git_reference_shorthand(r1->ref), 103 git_reference_shorthand(r2->ref)); 104 }