58a7b20d793cbc71ab924d5f5aedf28cd01ca32a
   1#include "cache.h"
   2#include "commit.h"
   3
   4static int is_shallow = -1;
   5
   6int register_shallow(const unsigned char *sha1)
   7{
   8        struct commit_graft *graft =
   9                xmalloc(sizeof(struct commit_graft));
  10        struct commit *commit = lookup_commit(sha1);
  11
  12        hashcpy(graft->sha1, sha1);
  13        graft->nr_parent = -1;
  14        if (commit && commit->object.parsed)
  15                commit->parents = NULL;
  16        return register_commit_graft(graft, 0);
  17}
  18
  19int is_repository_shallow()
  20{
  21        FILE *fp;
  22        char buf[1024];
  23
  24        if (is_shallow >= 0)
  25                return is_shallow;
  26
  27        fp = fopen(git_path("shallow"), "r");
  28        if (!fp) {
  29                is_shallow = 0;
  30                return is_shallow;
  31        }
  32        is_shallow = 1;
  33
  34        while (fgets(buf, sizeof(buf), fp)) {
  35                unsigned char sha1[20];
  36                if (get_sha1_hex(buf, sha1))
  37                        die("bad shallow line: %s", buf);
  38                register_shallow(sha1);
  39        }
  40        fclose(fp);
  41        return is_shallow;
  42}
  43
  44struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
  45                int shallow_flag, int not_shallow_flag)
  46{
  47        int i = 0, cur_depth = 0;
  48        struct commit_list *result = NULL;
  49        struct object_array stack = {0, 0, NULL};
  50        struct commit *commit = NULL;
  51
  52        while (commit || i < heads->nr || stack.nr) {
  53                struct commit_list *p;
  54                if (!commit) {
  55                        if (i < heads->nr) {
  56                                commit = (struct commit *)
  57                                        heads->objects[i++].item;
  58                                if (commit->object.type != OBJ_COMMIT) {
  59                                        commit = NULL;
  60                                        continue;
  61                                }
  62                                commit->util = xcalloc(1, sizeof(int));
  63                                cur_depth = 0;
  64                        } else {
  65                                commit = (struct commit *)
  66                                        stack.objects[--stack.nr].item;
  67                                cur_depth = *(int *)commit->util;
  68                        }
  69                }
  70                parse_commit(commit);
  71                commit->object.flags |= not_shallow_flag;
  72                cur_depth++;
  73                for (p = commit->parents, commit = NULL; p; p = p->next) {
  74                        if (!p->item->util) {
  75                                int *pointer = xmalloc(sizeof(int));
  76                                p->item->util = pointer;
  77                                *pointer =  cur_depth;
  78                        } else {
  79                                int *pointer = p->item->util;
  80                                if (cur_depth >= *pointer)
  81                                        continue;
  82                                *pointer = cur_depth;
  83                        }
  84                        if (cur_depth < depth) {
  85                                if (p->next)
  86                                        add_object_array(&p->item->object,
  87                                                        NULL, &stack);
  88                                else {
  89                                        commit = p->item;
  90                                        cur_depth = *(int *)commit->util;
  91                                }
  92                        } else {
  93                                commit_list_insert(p->item, &result);
  94                                p->item->object.flags |= shallow_flag;
  95                        }
  96                }
  97        }
  98
  99        return result;
 100}
 101