9 const char *tree_type
= "tree";
11 static int read_one_entry(unsigned char *sha1
, const char *base
, int baselen
, const char *pathname
, unsigned mode
, int stage
)
15 struct cache_entry
*ce
;
18 return READ_TREE_RECURSIVE
;
20 len
= strlen(pathname
);
21 size
= cache_entry_size(baselen
+ len
);
22 ce
= xcalloc(1, size
);
24 ce
->ce_mode
= create_ce_mode(mode
);
25 ce
->ce_flags
= create_ce_flags(baselen
+ len
, stage
);
26 memcpy(ce
->name
, base
, baselen
);
27 memcpy(ce
->name
+ baselen
, pathname
, len
+1);
28 memcpy(ce
->sha1
, sha1
, 20);
29 return add_cache_entry(ce
, ADD_CACHE_OK_TO_ADD
|ADD_CACHE_SKIP_DFCHECK
);
32 static int match_tree_entry(const char *base
, int baselen
, const char *path
, unsigned int mode
, const char **paths
)
39 pathlen
= strlen(path
);
40 while ((match
= *paths
++) != NULL
) {
41 int matchlen
= strlen(match
);
43 if (baselen
>= matchlen
) {
44 /* If it doesn't match, move along... */
45 if (strncmp(base
, match
, matchlen
))
47 /* The base is a subdirectory of a path which was specified. */
51 /* Does the base match? */
52 if (strncmp(base
, match
, baselen
))
58 if (pathlen
> matchlen
)
61 if (matchlen
> pathlen
) {
62 if (match
[pathlen
] != '/')
68 if (strncmp(path
, match
, pathlen
))
76 int read_tree_recursive(struct tree
*tree
,
77 const char *base
, int baselen
,
78 int stage
, const char **match
,
81 struct tree_entry_list
*list
;
86 struct tree_entry_list
*current
= list
;
88 if (!match_tree_entry(base
, baselen
, current
->name
,
89 current
->mode
, match
))
92 switch (fn(current
->item
.any
->sha1
, base
, baselen
,
93 current
->name
, current
->mode
, stage
)) {
96 case READ_TREE_RECURSIVE
:
101 if (current
->directory
) {
103 int pathlen
= strlen(current
->name
);
106 newbase
= xmalloc(baselen
+ 1 + pathlen
);
107 memcpy(newbase
, base
, baselen
);
108 memcpy(newbase
+ baselen
, current
->name
, pathlen
);
109 newbase
[baselen
+ pathlen
] = '/';
110 retval
= read_tree_recursive(current
->item
.tree
,
112 baselen
+ pathlen
+ 1,
123 int read_tree(struct tree
*tree
, int stage
, const char **match
)
125 return read_tree_recursive(tree
, "", 0, stage
, match
, read_one_entry
);
128 struct tree
*lookup_tree(const unsigned char *sha1
)
130 struct object
*obj
= lookup_object(sha1
);
132 struct tree
*ret
= xcalloc(1, sizeof(struct tree
));
133 created_object(sha1
, &ret
->object
);
134 ret
->object
.type
= tree_type
;
138 obj
->type
= tree_type
;
139 if (obj
->type
!= tree_type
) {
140 error("Object %s is a %s, not a tree",
141 sha1_to_hex(sha1
), obj
->type
);
144 return (struct tree
*) obj
;
147 int parse_tree_buffer(struct tree
*item
, void *buffer
, unsigned long size
)
149 struct tree_desc desc
;
150 struct tree_entry_list
**list_p
;
153 if (item
->object
.parsed
)
155 item
->object
.parsed
= 1;
156 item
->buffer
= buffer
;
162 list_p
= &item
->entries
;
166 const unsigned char *sha1
;
167 struct tree_entry_list
*entry
;
169 sha1
= tree_entry_extract(&desc
, &path
, &mode
);
171 entry
= xmalloc(sizeof(struct tree_entry_list
));
174 entry
->directory
= S_ISDIR(mode
) != 0;
175 entry
->executable
= (mode
& S_IXUSR
) != 0;
176 entry
->symlink
= S_ISLNK(mode
) != 0;
177 entry
->zeropad
= *(const char *)(desc
.buf
) == '0';
180 update_tree_entry(&desc
);
182 if (entry
->directory
) {
183 entry
->item
.tree
= lookup_tree(sha1
);
185 entry
->item
.blob
= lookup_blob(sha1
);
189 list_p
= &entry
->next
;
192 if (track_object_refs
) {
193 struct tree_entry_list
*entry
;
195 struct object_refs
*refs
= alloc_object_refs(n_refs
);
196 for (entry
= item
->entries
; entry
; entry
= entry
->next
)
197 refs
->ref
[i
++] = entry
->item
.any
;
198 set_object_refs(&item
->object
, refs
);
204 int parse_tree(struct tree
*item
)
210 if (item
->object
.parsed
)
212 buffer
= read_sha1_file(item
->object
.sha1
, type
, &size
);
214 return error("Could not read %s",
215 sha1_to_hex(item
->object
.sha1
));
216 if (strcmp(type
, tree_type
)) {
218 return error("Object %s not a tree",
219 sha1_to_hex(item
->object
.sha1
));
221 return parse_tree_buffer(item
, buffer
, size
);
224 struct tree
*parse_tree_indirect(const unsigned char *sha1
)
226 struct object
*obj
= parse_object(sha1
);
230 if (obj
->type
== tree_type
)
231 return (struct tree
*) obj
;
232 else if (obj
->type
== commit_type
)
233 obj
= &(((struct commit
*) obj
)->tree
->object
);
234 else if (obj
->type
== tag_type
)
235 obj
= ((struct tag
*) obj
)->tagged
;
239 parse_object(obj
->sha1
);