9 const char *tree_type
= "tree";
11 static int read_one_entry(const 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_desc desc
;
86 desc
.buf
= tree
->buffer
;
87 desc
.size
= tree
->size
;
92 const unsigned char *sha1
;
94 sha1
= tree_entry_extract(&desc
, &name
, &mode
);
95 update_tree_entry(&desc
);
97 if (!match_tree_entry(base
, baselen
, name
, mode
, match
))
100 switch (fn(sha1
, base
, baselen
, name
, mode
, stage
)) {
103 case READ_TREE_RECURSIVE
:
110 int pathlen
= strlen(name
);
113 newbase
= xmalloc(baselen
+ 1 + pathlen
);
114 memcpy(newbase
, base
, baselen
);
115 memcpy(newbase
+ baselen
, name
, pathlen
);
116 newbase
[baselen
+ pathlen
] = '/';
117 retval
= read_tree_recursive(lookup_tree(sha1
),
119 baselen
+ pathlen
+ 1,
130 int read_tree(struct tree
*tree
, int stage
, const char **match
)
132 return read_tree_recursive(tree
, "", 0, stage
, match
, read_one_entry
);
135 struct tree
*lookup_tree(const unsigned char *sha1
)
137 struct object
*obj
= lookup_object(sha1
);
139 struct tree
*ret
= xcalloc(1, sizeof(struct tree
));
140 created_object(sha1
, &ret
->object
);
141 ret
->object
.type
= tree_type
;
145 obj
->type
= tree_type
;
146 if (obj
->type
!= tree_type
) {
147 error("Object %s is a %s, not a tree",
148 sha1_to_hex(sha1
), obj
->type
);
151 return (struct tree
*) obj
;
154 static int track_tree_refs(struct tree
*item
)
157 struct object_refs
*refs
;
158 struct tree_desc desc
;
160 /* Count how many entries there are.. */
161 desc
.buf
= item
->buffer
;
162 desc
.size
= item
->size
;
165 update_tree_entry(&desc
);
168 /* Allocate object refs and walk it again.. */
170 refs
= alloc_object_refs(n_refs
);
171 desc
.buf
= item
->buffer
;
172 desc
.size
= item
->size
;
176 const unsigned char *sha1
;
179 sha1
= tree_entry_extract(&desc
, &name
, &mode
);
180 update_tree_entry(&desc
);
182 obj
= &lookup_tree(sha1
)->object
;
184 obj
= &lookup_blob(sha1
)->object
;
185 refs
->ref
[i
++] = obj
;
187 set_object_refs(&item
->object
, refs
);
191 int parse_tree_buffer(struct tree
*item
, void *buffer
, unsigned long size
)
193 if (item
->object
.parsed
)
195 item
->object
.parsed
= 1;
196 item
->buffer
= buffer
;
199 if (track_object_refs
)
200 track_tree_refs(item
);
204 struct tree_entry_list
*create_tree_entry_list(struct tree
*tree
)
206 struct tree_desc desc
;
207 struct tree_entry_list
*ret
= NULL
;
208 struct tree_entry_list
**list_p
= &ret
;
210 desc
.buf
= tree
->buffer
;
211 desc
.size
= tree
->size
;
216 const unsigned char *sha1
;
217 struct tree_entry_list
*entry
;
219 sha1
= tree_entry_extract(&desc
, &path
, &mode
);
220 update_tree_entry(&desc
);
222 entry
= xmalloc(sizeof(struct tree_entry_list
));
226 entry
->directory
= S_ISDIR(mode
) != 0;
227 entry
->executable
= (mode
& S_IXUSR
) != 0;
228 entry
->symlink
= S_ISLNK(mode
) != 0;
232 list_p
= &entry
->next
;
237 void free_tree_entry_list(struct tree_entry_list
*list
)
240 struct tree_entry_list
*next
= list
->next
;
246 int parse_tree(struct tree
*item
)
252 if (item
->object
.parsed
)
254 buffer
= read_sha1_file(item
->object
.sha1
, type
, &size
);
256 return error("Could not read %s",
257 sha1_to_hex(item
->object
.sha1
));
258 if (strcmp(type
, tree_type
)) {
260 return error("Object %s not a tree",
261 sha1_to_hex(item
->object
.sha1
));
263 return parse_tree_buffer(item
, buffer
, size
);
266 struct tree
*parse_tree_indirect(const unsigned char *sha1
)
268 struct object
*obj
= parse_object(sha1
);
272 if (obj
->type
== tree_type
)
273 return (struct tree
*) obj
;
274 else if (obj
->type
== commit_type
)
275 obj
= &(((struct commit
*) obj
)->tree
->object
);
276 else if (obj
->type
== tag_type
)
277 obj
= ((struct tag
*) obj
)->tagged
;
281 parse_object(obj
->sha1
);