gout

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

reference.c (2317B)


      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   git_reference_peel(&obj, git_ref, GIT_OBJECT_ANY);
     55   const git_oid* id = git_object_id(obj);
     56   git_object_free(obj);
     57   if (!id) {
     58     errx(1, "git_object_id");
     59   }
     60   ref->commit = gitcommit_create(id, repo);
     61 
     62   git_reference_free(git_ref);
     63   return ref;
     64 }
     65 
     66 void gitreference_free(GitReference* ref) {
     67   if (!ref) {
     68     return;
     69   }
     70   free(ref->shorthand);
     71   ref->shorthand = NULL;
     72   gitcommit_free(ref->commit);
     73   ref->commit = NULL;
     74   free(ref);
     75 }
     76 
     77 int gitreference_compare(const void* a, const void* b) {
     78   GitReference* r1 = *(GitReference**)a;
     79   GitReference* r2 = *(GitReference**)b;
     80   int r = (r1->type == kReftypeTag) - (r2->type == kReftypeTag);
     81   if (r != 0) {
     82     return r;
     83   }
     84 
     85   time_t t1 = r1->commit->author_time;
     86   time_t t2 = r2->commit->author_time;
     87   if (t1 > t2) {
     88     return -1;
     89   }
     90   if (t1 < t2) {
     91     return 1;
     92   }
     93   return strcmp(r1->shorthand, r2->shorthand);
     94 }