5 void *fill_tree_descriptor(struct tree_desc
*desc
, const unsigned char *sha1
)
7 unsigned long size
= 0;
11 buf
= read_object_with_reference(sha1
, tree_type
, &size
, NULL
);
13 die("unable to read tree %s", sha1_to_hex(sha1
));
20 static int entry_compare(struct name_entry
*a
, struct name_entry
*b
)
22 return base_name_compare(
23 a
->path
, a
->pathlen
, a
->mode
,
24 b
->path
, b
->pathlen
, b
->mode
);
27 static void entry_clear(struct name_entry
*a
)
29 memset(a
, 0, sizeof(*a
));
32 static void entry_extract(struct tree_desc
*t
, struct name_entry
*a
)
34 a
->sha1
= tree_entry_extract(t
, &a
->path
, &a
->mode
);
35 a
->pathlen
= strlen(a
->path
);
38 void update_tree_entry(struct tree_desc
*desc
)
40 void *buf
= desc
->buf
;
41 unsigned long size
= desc
->size
;
42 int len
= strlen(buf
) + 1 + 20;
45 die("corrupt tree file");
46 desc
->buf
= buf
+ len
;
47 desc
->size
= size
- len
;
50 const unsigned char *tree_entry_extract(struct tree_desc
*desc
, const char **pathp
, unsigned int *modep
)
52 void *tree
= desc
->buf
;
53 unsigned long size
= desc
->size
;
54 int len
= strlen(tree
)+1;
55 const unsigned char *sha1
= tree
+ len
;
56 const char *path
= strchr(tree
, ' ');
59 if (!path
|| size
< len
+ 20 || sscanf(tree
, "%o", &mode
) != 1)
60 die("corrupt tree file");
62 *modep
= canon_mode(mode
);
66 void traverse_trees(int n
, struct tree_desc
*t
, const char *base
, traverse_callback_t callback
)
68 struct name_entry
*entry
= xmalloc(n
*sizeof(*entry
));
71 struct name_entry entry
[3];
72 unsigned long mask
= 0;
76 for (i
= 0; i
< n
; i
++) {
79 entry_extract(t
+i
, entry
+i
);
81 int cmp
= entry_compare(entry
+i
, entry
+last
);
84 * Is the new name bigger than the old one?
90 * Is the new name smaller than the old one?
103 * Update the tree entries we've walked, and clear
104 * all the unused name-entries.
106 for (i
= 0; i
< n
; i
++) {
107 if (mask
& (1ul << i
)) {
108 update_tree_entry(t
+i
);
111 entry_clear(entry
+ i
);
113 callback(n
, mask
, entry
, base
);
118 static int find_tree_entry(struct tree_desc
*t
, const char *name
, unsigned char *result
, unsigned *mode
)
120 int namelen
= strlen(name
);
123 const unsigned char *sha1
;
126 sha1
= tree_entry_extract(t
, &entry
, mode
);
127 update_tree_entry(t
);
128 entrylen
= strlen(entry
);
129 if (entrylen
> namelen
)
131 cmp
= memcmp(name
, entry
, entrylen
);
136 if (entrylen
== namelen
) {
137 memcpy(result
, sha1
, 20);
140 if (name
[entrylen
] != '/')
144 if (++entrylen
== namelen
) {
145 memcpy(result
, sha1
, 20);
148 return get_tree_entry(sha1
, name
+ entrylen
, result
, mode
);
153 int get_tree_entry(const unsigned char *tree_sha1
, const char *name
, unsigned char *sha1
, unsigned *mode
)
159 tree
= read_object_with_reference(tree_sha1
, tree_type
, &t
.size
, NULL
);
163 retval
= find_tree_entry(&t
, name
, sha1
, mode
);