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
);