The second batch
[git] / tree.c
1 #include "cache.h"
2 #include "cache-tree.h"
3 #include "tree.h"
4 #include "object-store.h"
5 #include "blob.h"
6 #include "commit.h"
7 #include "tag.h"
8 #include "alloc.h"
9 #include "tree-walk.h"
10 #include "repository.h"
11
12 const char *tree_type = "tree";
13
14 int read_tree_at(struct repository *r,
15                  struct tree *tree, struct strbuf *base,
16                  const struct pathspec *pathspec,
17                  read_tree_fn_t fn, void *context)
18 {
19         struct tree_desc desc;
20         struct name_entry entry;
21         struct object_id oid;
22         int len, oldlen = base->len;
23         enum interesting retval = entry_not_interesting;
24
25         if (parse_tree(tree))
26                 return -1;
27
28         init_tree_desc(&desc, tree->buffer, tree->size);
29
30         while (tree_entry(&desc, &entry)) {
31                 if (retval != all_entries_interesting) {
32                         retval = tree_entry_interesting(r->index, &entry,
33                                                         base, 0, pathspec);
34                         if (retval == all_entries_not_interesting)
35                                 break;
36                         if (retval == entry_not_interesting)
37                                 continue;
38                 }
39
40                 switch (fn(&entry.oid, base,
41                            entry.path, entry.mode, context)) {
42                 case 0:
43                         continue;
44                 case READ_TREE_RECURSIVE:
45                         break;
46                 default:
47                         return -1;
48                 }
49
50                 if (S_ISDIR(entry.mode))
51                         oidcpy(&oid, &entry.oid);
52                 else if (S_ISGITLINK(entry.mode)) {
53                         struct commit *commit;
54
55                         commit = lookup_commit(r, &entry.oid);
56                         if (!commit)
57                                 die("Commit %s in submodule path %s%s not found",
58                                     oid_to_hex(&entry.oid),
59                                     base->buf, entry.path);
60
61                         if (parse_commit(commit))
62                                 die("Invalid commit %s in submodule path %s%s",
63                                     oid_to_hex(&entry.oid),
64                                     base->buf, entry.path);
65
66                         oidcpy(&oid, get_commit_tree_oid(commit));
67                 }
68                 else
69                         continue;
70
71                 len = tree_entry_len(&entry);
72                 strbuf_add(base, entry.path, len);
73                 strbuf_addch(base, '/');
74                 retval = read_tree_at(r, lookup_tree(r, &oid),
75                                       base, pathspec,
76                                       fn, context);
77                 strbuf_setlen(base, oldlen);
78                 if (retval)
79                         return -1;
80         }
81         return 0;
82 }
83
84 int read_tree(struct repository *r,
85               struct tree *tree,
86               const struct pathspec *pathspec,
87               read_tree_fn_t fn, void *context)
88 {
89         struct strbuf sb = STRBUF_INIT;
90         int ret = read_tree_at(r, tree, &sb, pathspec, fn, context);
91         strbuf_release(&sb);
92         return ret;
93 }
94
95 int cmp_cache_name_compare(const void *a_, const void *b_)
96 {
97         const struct cache_entry *ce1, *ce2;
98
99         ce1 = *((const struct cache_entry **)a_);
100         ce2 = *((const struct cache_entry **)b_);
101         return cache_name_stage_compare(ce1->name, ce1->ce_namelen, ce_stage(ce1),
102                                   ce2->name, ce2->ce_namelen, ce_stage(ce2));
103 }
104
105 struct tree *lookup_tree(struct repository *r, const struct object_id *oid)
106 {
107         struct object *obj = lookup_object(r, oid);
108         if (!obj)
109                 return create_object(r, oid, alloc_tree_node(r));
110         return object_as_type(obj, OBJ_TREE, 0);
111 }
112
113 int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
114 {
115         if (item->object.parsed)
116                 return 0;
117         item->object.parsed = 1;
118         item->buffer = buffer;
119         item->size = size;
120
121         return 0;
122 }
123
124 int parse_tree_gently(struct tree *item, int quiet_on_missing)
125 {
126          enum object_type type;
127          void *buffer;
128          unsigned long size;
129
130         if (item->object.parsed)
131                 return 0;
132         buffer = read_object_file(&item->object.oid, &type, &size);
133         if (!buffer)
134                 return quiet_on_missing ? -1 :
135                         error("Could not read %s",
136                              oid_to_hex(&item->object.oid));
137         if (type != OBJ_TREE) {
138                 free(buffer);
139                 return error("Object %s not a tree",
140                              oid_to_hex(&item->object.oid));
141         }
142         return parse_tree_buffer(item, buffer, size);
143 }
144
145 void free_tree_buffer(struct tree *tree)
146 {
147         FREE_AND_NULL(tree->buffer);
148         tree->size = 0;
149         tree->object.parsed = 0;
150 }
151
152 struct tree *parse_tree_indirect(const struct object_id *oid)
153 {
154         struct repository *r = the_repository;
155         struct object *obj = parse_object(r, oid);
156         return (struct tree *)repo_peel_to_type(r, NULL, 0, obj, OBJ_TREE);
157 }