blame.con commit blame: move origin-related methods to libgit (f5dd754)
   1#include "blame.h"
   2
   3void blame_origin_decref(struct blame_origin *o)
   4{
   5        if (o && --o->refcnt <= 0) {
   6                struct blame_origin *p, *l = NULL;
   7                if (o->previous)
   8                        blame_origin_decref(o->previous);
   9                free(o->file.ptr);
  10                /* Should be present exactly once in commit chain */
  11                for (p = o->commit->util; p; l = p, p = p->next) {
  12                        if (p == o) {
  13                                if (l)
  14                                        l->next = p->next;
  15                                else
  16                                        o->commit->util = p->next;
  17                                free(o);
  18                                return;
  19                        }
  20                }
  21                die("internal error in blame_origin_decref");
  22        }
  23}
  24
  25/*
  26 * Given a commit and a path in it, create a new origin structure.
  27 * The callers that add blame to the scoreboard should use
  28 * get_origin() to obtain shared, refcounted copy instead of calling
  29 * this function directly.
  30 */
  31struct blame_origin *make_origin(struct commit *commit, const char *path)
  32{
  33        struct blame_origin *o;
  34        FLEX_ALLOC_STR(o, path, path);
  35        o->commit = commit;
  36        o->refcnt = 1;
  37        o->next = commit->util;
  38        commit->util = o;
  39        return o;
  40}
  41
  42/*
  43 * Locate an existing origin or create a new one.
  44 * This moves the origin to front position in the commit util list.
  45 */
  46struct blame_origin *get_origin(struct commit *commit, const char *path)
  47{
  48        struct blame_origin *o, *l;
  49
  50        for (o = commit->util, l = NULL; o; l = o, o = o->next) {
  51                if (!strcmp(o->path, path)) {
  52                        /* bump to front */
  53                        if (l) {
  54                                l->next = o->next;
  55                                o->next = commit->util;
  56                                commit->util = o;
  57                        }
  58                        return blame_origin_incref(o);
  59                }
  60        }
  61        return make_origin(commit, path);
  62}