gout

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

reference.c (2273B)


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