gitout

A static git page generator
git clone https://git.bracken.jp/gitout.git
Log | Files | Refs | Submodules | README | LICENSE

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 }