shallow.con commit allow cloning a repository "shallowly" (016e6cc)
   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{
  46        int i = 0, cur_depth = 0;
  47        struct commit_list *result = NULL;
  48        struct object_array stack = {0, 0, NULL};
  49        struct commit *commit = NULL;
  50
  51        while (commit || i < heads->nr || stack.nr) {
  52                struct commit_list *p;
  53                if (!commit) {
  54                        if (i < heads->nr) {
  55                                commit = (struct commit *)
  56                                        heads->objects[i++].item;
  57                                if (commit->object.type != OBJ_COMMIT) {
  58                                        commit = NULL;
  59                                        continue;
  60                                }
  61                                commit->util = xcalloc(1, sizeof(int));
  62                                cur_depth = 0;
  63                        } else {
  64                                commit = (struct commit *)
  65                                        stack.objects[--stack.nr].item;
  66                                cur_depth = *(int *)commit->util;
  67                        }
  68                }
  69                parse_commit(commit);
  70                cur_depth++;
  71                for (p = commit->parents, commit = NULL; p; p = p->next) {
  72                        if (!p->item->util) {
  73                                int *pointer = xmalloc(sizeof(int));
  74                                p->item->util = pointer;
  75                                *pointer =  cur_depth;
  76                        } else {
  77                                int *pointer = p->item->util;
  78                                if (cur_depth >= *pointer)
  79                                        continue;
  80                                *pointer = cur_depth;
  81                        }
  82                        if (cur_depth < depth) {
  83                                if (p->next)
  84                                        add_object_array(&p->item->object,
  85                                                        NULL, &stack);
  86                                else {
  87                                        commit = p->item;
  88                                        cur_depth = *(int *)commit->util;
  89                                }
  90                        } else
  91                                commit_list_insert(p->item, &result);
  92                }
  93        }
  94
  95        return result;
  96}
  97