8 const char *tree_type
= "tree";
10 static int read_one_entry(const unsigned char *sha1
, const char *base
, int baselen
, const char *pathname
, unsigned mode
, int stage
)
14 struct cache_entry
*ce
;
17 return READ_TREE_RECURSIVE
;
19 len
= strlen(pathname
);
20 size
= cache_entry_size(baselen
+ len
);
21 ce
= xcalloc(1, size
);
23 ce
->ce_mode
= create_ce_mode(mode
);
24 ce
->ce_flags
= create_ce_flags(baselen
+ len
, stage
);
25 memcpy(ce
->name
, base
, baselen
);
26 memcpy(ce
->name
+ baselen
, pathname
, len
+1);
27 hashcpy(ce
->sha1
, sha1
);
28 return add_cache_entry(ce
, ADD_CACHE_OK_TO_ADD
|ADD_CACHE_SKIP_DFCHECK
);
31 static int match_tree_entry(const char *base
, int baselen
, const char *path
, unsigned int mode
, const char **paths
)
38 pathlen
= strlen(path
);
39 while ((match
= *paths
++) != NULL
) {
40 int matchlen
= strlen(match
);
42 if (baselen
>= matchlen
) {
43 /* If it doesn't match, move along... */
44 if (strncmp(base
, match
, matchlen
))
46 /* The base is a subdirectory of a path which was specified. */
50 /* Does the base match? */
51 if (strncmp(base
, match
, baselen
))
57 if (pathlen
> matchlen
)
60 if (matchlen
> pathlen
) {
61 if (match
[pathlen
] != '/')
67 if (strncmp(path
, match
, pathlen
))
75 int read_tree_recursive(struct tree
*tree
,
76 const char *base
, int baselen
,
77 int stage
, const char **match
,
80 struct tree_desc desc
;
81 struct name_entry entry
;
86 init_tree_desc(&desc
, tree
->buffer
, tree
->size
);
88 while (tree_entry(&desc
, &entry
)) {
89 if (!match_tree_entry(base
, baselen
, entry
.path
, entry
.mode
, match
))
92 switch (fn(entry
.sha1
, base
, baselen
, entry
.path
, entry
.mode
, stage
)) {
95 case READ_TREE_RECURSIVE
:
100 if (S_ISDIR(entry
.mode
)) {
103 unsigned int pathlen
= tree_entry_len(entry
.path
, entry
.sha1
);
105 newbase
= xmalloc(baselen
+ 1 + pathlen
);
106 memcpy(newbase
, base
, baselen
);
107 memcpy(newbase
+ baselen
, entry
.path
, pathlen
);
108 newbase
[baselen
+ pathlen
] = '/';
109 retval
= read_tree_recursive(lookup_tree(entry
.sha1
),
111 baselen
+ pathlen
+ 1,
122 int read_tree(struct tree
*tree
, int stage
, const char **match
)
124 return read_tree_recursive(tree
, "", 0, stage
, match
, read_one_entry
);
127 struct tree
*lookup_tree(const unsigned char *sha1
)
129 struct object
*obj
= lookup_object(sha1
);
131 return create_object(sha1
, OBJ_TREE
, alloc_tree_node());
133 obj
->type
= OBJ_TREE
;
134 if (obj
->type
!= OBJ_TREE
) {
135 error("Object %s is a %s, not a tree",
136 sha1_to_hex(sha1
), typename(obj
->type
));
139 return (struct tree
*) obj
;
143 * NOTE! Tree refs to external git repositories
144 * (ie gitlinks) do not count as real references.
146 * You don't have to have those repositories
147 * available at all, much less have the objects
148 * accessible from the current repository.
150 static void track_tree_refs(struct tree
*item
)
153 struct object_refs
*refs
;
154 struct tree_desc desc
;
155 struct name_entry entry
;
157 /* Count how many entries there are.. */
158 init_tree_desc(&desc
, item
->buffer
, item
->size
);
159 while (tree_entry(&desc
, &entry
)) {
160 if (S_ISDIRLNK(entry
.mode
))
165 /* Allocate object refs and walk it again.. */
167 refs
= alloc_object_refs(n_refs
);
168 init_tree_desc(&desc
, item
->buffer
, item
->size
);
169 while (tree_entry(&desc
, &entry
)) {
172 if (S_ISDIRLNK(entry
.mode
))
174 if (S_ISDIR(entry
.mode
))
175 obj
= &lookup_tree(entry
.sha1
)->object
;
177 obj
= &lookup_blob(entry
.sha1
)->object
;
178 refs
->ref
[i
++] = obj
;
180 set_object_refs(&item
->object
, refs
);
183 int parse_tree_buffer(struct tree
*item
, void *buffer
, unsigned long size
)
185 if (item
->object
.parsed
)
187 item
->object
.parsed
= 1;
188 item
->buffer
= buffer
;
191 if (track_object_refs
)
192 track_tree_refs(item
);
196 int parse_tree(struct tree
*item
)
198 enum object_type type
;
202 if (item
->object
.parsed
)
204 buffer
= read_sha1_file(item
->object
.sha1
, &type
, &size
);
206 return error("Could not read %s",
207 sha1_to_hex(item
->object
.sha1
));
208 if (type
!= OBJ_TREE
) {
210 return error("Object %s not a tree",
211 sha1_to_hex(item
->object
.sha1
));
213 return parse_tree_buffer(item
, buffer
, size
);
216 struct tree
*parse_tree_indirect(const unsigned char *sha1
)
218 struct object
*obj
= parse_object(sha1
);
222 if (obj
->type
== OBJ_TREE
)
223 return (struct tree
*) obj
;
224 else if (obj
->type
== OBJ_COMMIT
)
225 obj
= &(((struct commit
*) obj
)->tree
->object
);
226 else if (obj
->type
== OBJ_TAG
)
227 obj
= ((struct tag
*) obj
)->tagged
;
231 parse_object(obj
->sha1
);