5 static const char *get_mode(const char *str
, unsigned int *modep
)
13 while ((c
= *str
++) != ' ') {
14 if (c
< '0' || c
> '7')
16 mode
= (mode
<< 3) + (c
- '0');
22 static void decode_tree_entry(struct tree_desc
*desc
, const char *buf
, unsigned long size
)
25 unsigned int mode
, len
;
27 if (size
< 24 || buf
[size
- 21])
28 die("corrupt tree file");
30 path
= get_mode(buf
, &mode
);
32 die("corrupt tree file");
33 len
= strlen(path
) + 1;
35 /* Initialize the descriptor entry */
36 desc
->entry
.path
= path
;
37 desc
->entry
.mode
= mode
;
38 desc
->entry
.sha1
= (const unsigned char *)(path
+ len
);
41 void init_tree_desc(struct tree_desc
*desc
, const void *buffer
, unsigned long size
)
43 desc
->buffer
= buffer
;
46 decode_tree_entry(desc
, buffer
, size
);
49 void *fill_tree_descriptor(struct tree_desc
*desc
, const unsigned char *sha1
)
51 unsigned long size
= 0;
55 buf
= read_object_with_reference(sha1
, tree_type
, &size
, NULL
);
57 die("unable to read tree %s", sha1_to_hex(sha1
));
59 init_tree_desc(desc
, buf
, size
);
63 static void entry_clear(struct name_entry
*a
)
65 memset(a
, 0, sizeof(*a
));
68 static void entry_extract(struct tree_desc
*t
, struct name_entry
*a
)
73 void update_tree_entry(struct tree_desc
*desc
)
75 const void *buf
= desc
->buffer
;
76 const unsigned char *end
= desc
->entry
.sha1
+ 20;
77 unsigned long size
= desc
->size
;
78 unsigned long len
= end
- (const unsigned char *)buf
;
81 die("corrupt tree file");
87 decode_tree_entry(desc
, buf
, size
);
90 int tree_entry(struct tree_desc
*desc
, struct name_entry
*entry
)
96 update_tree_entry(desc
);
100 void setup_traverse_info(struct traverse_info
*info
, const char *base
)
102 int pathlen
= strlen(base
);
103 static struct traverse_info dummy
;
105 memset(info
, 0, sizeof(*info
));
106 if (pathlen
&& base
[pathlen
-1] == '/')
108 info
->pathlen
= pathlen
? pathlen
+ 1 : 0;
109 info
->name
.path
= base
;
110 info
->name
.sha1
= (void *)(base
+ pathlen
+ 1);
115 char *make_traverse_path(char *path
, const struct traverse_info
*info
, const struct name_entry
*n
)
117 int len
= tree_entry_len(n
->path
, n
->sha1
);
118 int pathlen
= info
->pathlen
;
120 path
[pathlen
+ len
] = 0;
122 memcpy(path
+ pathlen
, n
->path
, len
);
125 path
[--pathlen
] = '/';
127 len
= tree_entry_len(n
->path
, n
->sha1
);
134 struct tree_desc_skip
{
135 struct tree_desc_skip
*prev
;
141 struct tree_desc_skip
*skip
;
144 static int name_compare(const char *a
, int a_len
,
145 const char *b
, int b_len
)
147 int len
= (a_len
< b_len
) ? a_len
: b_len
;
148 int cmp
= memcmp(a
, b
, len
);
151 return (a_len
- b_len
);
154 static int check_entry_match(const char *a
, int a_len
, const char *b
, int b_len
)
157 * The caller wants to pick *a* from a tree or nothing.
158 * We are looking at *b* in a tree.
160 * (0) If a and b are the same name, we are trivially happy.
162 * There are three possibilities where *a* could be hiding
165 * (1) *a* == "t", *b* == "ab" i.e. *b* sorts earlier than *a* no
167 * (2) *a* == "t", *b* == "t-2" and "t" is a subtree in the tree;
168 * (3) *a* == "t-2", *b* == "t" and "t-2" is a blob in the tree.
170 * Otherwise we know *a* won't appear in the tree without
174 int cmp
= name_compare(a
, a_len
, b
, b_len
);
176 /* Most common case first -- reading sync'd trees */
181 /* a comes after b; it does not matter if it is case (3)
182 if (b_len < a_len && !memcmp(a, b, b_len) && a[b_len] < '/')
185 return 1; /* keep looking */
188 /* b comes after a; are we looking at case (2)? */
189 if (a_len
< b_len
&& !memcmp(a
, b
, a_len
) && b
[a_len
] < '/')
190 return 1; /* keep looking */
192 return -1; /* a cannot appear in the tree */
196 * From the extended tree_desc, extract the first name entry, while
197 * paying attention to the candidate "first" name. Most importantly,
198 * when looking for an entry, if there are entries that sorts earlier
199 * in the tree object representation than that name, skip them and
200 * process the named entry first. We will remember that we haven't
201 * processed the first entry yet, and in the later call skip the
202 * entry we processed early when update_extended_entry() is called.
204 * E.g. if the underlying tree object has these entries:
211 * and the "first" asks for "t", remember that we still need to
212 * process "t-1" and "t-2" but extract "t". After processing the
213 * entry "t" from this call, the caller will let us know by calling
214 * update_extended_entry() that we can remember "t" has been processed
218 static void extended_entry_extract(struct tree_desc_x
*t
,
219 struct name_entry
*a
,
225 struct tree_desc probe
;
226 struct tree_desc_skip
*skip
;
229 * Extract the first entry from the tree_desc, but skip the
230 * ones that we already returned in earlier rounds.
235 break; /* not found */
237 entry_extract(&t
->d
, a
);
238 for (skip
= t
->skip
; skip
; skip
= skip
->prev
)
239 if (a
->path
== skip
->ptr
)
243 /* We have processed this entry already. */
244 update_tree_entry(&t
->d
);
247 if (!first
|| !a
->path
)
251 * The caller wants "first" from this tree, or nothing.
254 len
= tree_entry_len(a
->path
, a
->sha1
);
255 switch (check_entry_match(first
, first_len
, path
, len
)) {
265 * We need to look-ahead -- we suspect that a subtree whose
266 * name is "first" may be hiding behind the current entry "path".
270 entry_extract(&probe
, a
);
272 len
= tree_entry_len(a
->path
, a
->sha1
);
273 switch (check_entry_match(first
, first_len
, path
, len
)) {
279 update_tree_entry(&probe
);
287 static void update_extended_entry(struct tree_desc_x
*t
, struct name_entry
*a
)
289 if (t
->d
.entry
.path
== a
->path
) {
290 update_tree_entry(&t
->d
);
292 /* we have returned this entry early */
293 struct tree_desc_skip
*skip
= xmalloc(sizeof(*skip
));
295 skip
->prev
= t
->skip
;
300 static void free_extended_entry(struct tree_desc_x
*t
)
302 struct tree_desc_skip
*p
, *s
;
304 for (s
= t
->skip
; s
; s
= p
) {
310 int traverse_trees(int n
, struct tree_desc
*t
, struct traverse_info
*info
)
313 struct name_entry
*entry
= xmalloc(n
*sizeof(*entry
));
315 struct tree_desc_x
*tx
= xcalloc(n
, sizeof(*tx
));
317 for (i
= 0; i
< n
; i
++)
321 unsigned long mask
, dirmask
;
322 const char *first
= NULL
;
324 struct name_entry
*e
;
327 for (i
= 0; i
< n
; i
++) {
329 extended_entry_extract(tx
+ i
, e
, NULL
, 0);
333 * A tree may have "t-2" at the current location even
334 * though it may have "t" that is a subtree behind it,
335 * and another tree may return "t". We want to grab
336 * all "t" from all trees to match in such a case.
338 for (i
= 0; i
< n
; i
++) {
342 len
= tree_entry_len(e
->path
, e
->sha1
);
348 if (name_compare(e
->path
, len
, first
, first_len
) < 0) {
355 for (i
= 0; i
< n
; i
++) {
357 extended_entry_extract(tx
+ i
, e
, first
, first_len
);
358 /* Cull the ones that are not the earliest */
361 len
= tree_entry_len(e
->path
, e
->sha1
);
362 if (name_compare(e
->path
, len
, first
, first_len
))
367 /* Now we have in entry[i] the earliest name from the trees */
370 for (i
= 0; i
< n
; i
++) {
374 if (S_ISDIR(entry
[i
].mode
))
379 ret
= info
->fn(n
, mask
, dirmask
, entry
, info
);
384 for (i
= 0; i
< n
; i
++)
385 if (mask
& (1ul << i
))
386 update_extended_entry(tx
+ i
, entry
+ i
);
389 for (i
= 0; i
< n
; i
++)
390 free_extended_entry(tx
+ i
);
395 static int find_tree_entry(struct tree_desc
*t
, const char *name
, unsigned char *result
, unsigned *mode
)
397 int namelen
= strlen(name
);
400 const unsigned char *sha1
;
403 sha1
= tree_entry_extract(t
, &entry
, mode
);
404 update_tree_entry(t
);
405 entrylen
= tree_entry_len(entry
, sha1
);
406 if (entrylen
> namelen
)
408 cmp
= memcmp(name
, entry
, entrylen
);
413 if (entrylen
== namelen
) {
414 hashcpy(result
, sha1
);
417 if (name
[entrylen
] != '/')
421 if (++entrylen
== namelen
) {
422 hashcpy(result
, sha1
);
425 return get_tree_entry(sha1
, name
+ entrylen
, result
, mode
);
430 int get_tree_entry(const unsigned char *tree_sha1
, const char *name
, unsigned char *sha1
, unsigned *mode
)
436 unsigned char root
[20];
438 tree
= read_object_with_reference(tree_sha1
, tree_type
, &size
, root
);
442 if (name
[0] == '\0') {
447 init_tree_desc(&t
, tree
, size
);
448 retval
= find_tree_entry(&t
, name
, sha1
, mode
);