8 const char *tree_type
= "tree";
10 static int read_one_entry(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
);
25 ce
->ce_mode
= create_ce_mode(mode
);
26 ce
->ce_flags
= create_ce_flags(baselen
+ len
, stage
);
27 memcpy(ce
->name
, base
, baselen
);
28 memcpy(ce
->name
+ baselen
, pathname
, len
+1);
29 memcpy(ce
->sha1
, sha1
, 20);
30 return add_cache_entry(ce
, ADD_CACHE_OK_TO_ADD
|ADD_CACHE_SKIP_DFCHECK
);
33 static int match_tree_entry(const char *base
, int baselen
, const char *path
, unsigned int mode
, const char **paths
)
40 pathlen
= strlen(path
);
41 while ((match
= *paths
++) != NULL
) {
42 int matchlen
= strlen(match
);
44 if (baselen
>= matchlen
) {
45 /* If it doesn't match, move along... */
46 if (strncmp(base
, match
, matchlen
))
48 /* The base is a subdirectory of a path which was specified. */
52 /* Does the base match? */
53 if (strncmp(base
, match
, baselen
))
59 if (pathlen
> matchlen
)
62 if (matchlen
> pathlen
) {
63 if (match
[pathlen
] != '/')
69 if (strncmp(path
, match
, pathlen
))
77 int read_tree_recursive(void *buffer
, unsigned long size
,
78 const char *base
, int baselen
,
79 int stage
, const char **match
,
83 int len
= strlen(buffer
)+1;
84 unsigned char *sha1
= buffer
+ len
;
85 char *path
= strchr(buffer
, ' ')+1;
88 if (size
< len
+ 20 || sscanf(buffer
, "%o", &mode
) != 1)
94 if (!match_tree_entry(base
, baselen
, path
, mode
, match
))
97 switch (fn(sha1
, base
, baselen
, path
, mode
, stage
)) {
100 case READ_TREE_RECURSIVE
:
107 int pathlen
= strlen(path
);
111 unsigned long eltsize
;
113 eltbuf
= read_sha1_file(sha1
, elttype
, &eltsize
);
114 if (!eltbuf
|| strcmp(elttype
, "tree")) {
115 if (eltbuf
) free(eltbuf
);
118 newbase
= xmalloc(baselen
+ 1 + pathlen
);
119 memcpy(newbase
, base
, baselen
);
120 memcpy(newbase
+ baselen
, path
, pathlen
);
121 newbase
[baselen
+ pathlen
] = '/';
122 retval
= read_tree_recursive(eltbuf
, eltsize
,
124 baselen
+ pathlen
+ 1,
136 int read_tree(void *buffer
, unsigned long size
, int stage
, const char **match
)
138 return read_tree_recursive(buffer
, size
, "", 0, stage
, match
, read_one_entry
);
141 struct tree
*lookup_tree(const unsigned char *sha1
)
143 struct object
*obj
= lookup_object(sha1
);
145 struct tree
*ret
= xmalloc(sizeof(struct tree
));
146 memset(ret
, 0, sizeof(struct tree
));
147 created_object(sha1
, &ret
->object
);
148 ret
->object
.type
= tree_type
;
152 obj
->type
= tree_type
;
153 if (obj
->type
!= tree_type
) {
154 error("Object %s is a %s, not a tree",
155 sha1_to_hex(sha1
), obj
->type
);
158 return (struct tree
*) obj
;
161 int parse_tree_buffer(struct tree
*item
, void *buffer
, unsigned long size
)
163 void *bufptr
= buffer
;
164 struct tree_entry_list
**list_p
;
167 if (item
->object
.parsed
)
169 item
->object
.parsed
= 1;
170 list_p
= &item
->entries
;
173 struct tree_entry_list
*entry
;
174 int len
= 1+strlen(bufptr
);
175 unsigned char *file_sha1
= bufptr
+ len
;
176 char *path
= strchr(bufptr
, ' ');
178 if (size
< len
+ 20 || !path
||
179 sscanf(bufptr
, "%o", &mode
) != 1)
182 entry
= xmalloc(sizeof(struct tree_entry_list
));
183 entry
->name
= strdup(path
+ 1);
184 entry
->directory
= S_ISDIR(mode
) != 0;
185 entry
->executable
= (mode
& S_IXUSR
) != 0;
186 entry
->symlink
= S_ISLNK(mode
) != 0;
187 entry
->zeropad
= *(char *)bufptr
== '0';
194 if (entry
->directory
) {
195 entry
->item
.tree
= lookup_tree(file_sha1
);
196 obj
= &entry
->item
.tree
->object
;
198 entry
->item
.blob
= lookup_blob(file_sha1
);
199 obj
= &entry
->item
.blob
->object
;
204 list_p
= &entry
->next
;
207 if (track_object_refs
) {
208 struct tree_entry_list
*entry
;
210 struct object_refs
*refs
= alloc_object_refs(n_refs
);
211 for (entry
= item
->entries
; entry
; entry
= entry
->next
)
212 refs
->ref
[i
++] = entry
->item
.any
;
213 set_object_refs(&item
->object
, refs
);
219 int parse_tree(struct tree
*item
)
226 if (item
->object
.parsed
)
228 buffer
= read_sha1_file(item
->object
.sha1
, type
, &size
);
230 return error("Could not read %s",
231 sha1_to_hex(item
->object
.sha1
));
232 if (strcmp(type
, tree_type
)) {
234 return error("Object %s not a tree",
235 sha1_to_hex(item
->object
.sha1
));
237 ret
= parse_tree_buffer(item
, buffer
, size
);
242 struct tree
*parse_tree_indirect(const unsigned char *sha1
)
244 struct object
*obj
= parse_object(sha1
);
248 if (obj
->type
== tree_type
)
249 return (struct tree
*) obj
;
250 else if (obj
->type
== commit_type
)
251 obj
= &(((struct commit
*) obj
)->tree
->object
);
252 else if (obj
->type
== tag_type
)
253 obj
= ((struct tag
*) obj
)->tagged
;
257 parse_object(obj
->sha1
);