4 void *fill_tree_descriptor(struct tree_desc
*desc
, const unsigned char *sha1
)
6 unsigned long size
= 0;
10 buf
= read_object_with_reference(sha1
, "tree", &size
, NULL
);
12 die("unable to read tree %s", sha1_to_hex(sha1
));
19 static int entry_compare(struct name_entry
*a
, struct name_entry
*b
)
21 return base_name_compare(
22 a
->path
, a
->pathlen
, a
->mode
,
23 b
->path
, b
->pathlen
, b
->mode
);
26 static void entry_clear(struct name_entry
*a
)
28 memset(a
, 0, sizeof(*a
));
31 static void entry_extract(struct tree_desc
*t
, struct name_entry
*a
)
33 a
->sha1
= tree_entry_extract(t
, &a
->path
, &a
->mode
);
34 a
->pathlen
= strlen(a
->path
);
37 void update_tree_entry(struct tree_desc
*desc
)
39 void *buf
= desc
->buf
;
40 unsigned long size
= desc
->size
;
41 int len
= strlen(buf
) + 1 + 20;
44 die("corrupt tree file");
45 desc
->buf
= buf
+ len
;
46 desc
->size
= size
- len
;
49 const unsigned char *tree_entry_extract(struct tree_desc
*desc
, const char **pathp
, unsigned int *modep
)
51 void *tree
= desc
->buf
;
52 unsigned long size
= desc
->size
;
53 int len
= strlen(tree
)+1;
54 const unsigned char *sha1
= tree
+ len
;
55 const char *path
= strchr(tree
, ' ');
58 if (!path
|| size
< len
+ 20 || sscanf(tree
, "%o", &mode
) != 1)
59 die("corrupt tree file");
61 *modep
= canon_mode(mode
);
65 void traverse_trees(int n
, struct tree_desc
*t
, const char *base
, traverse_callback_t callback
)
67 struct name_entry
*entry
= xmalloc(n
*sizeof(*entry
));
70 struct name_entry entry
[3];
71 unsigned long mask
= 0;
75 for (i
= 0; i
< n
; i
++) {
78 entry_extract(t
+i
, entry
+i
);
80 int cmp
= entry_compare(entry
+i
, entry
+last
);
83 * Is the new name bigger than the old one?
89 * Is the new name smaller than the old one?
102 * Update the tree entries we've walked, and clear
103 * all the unused name-entries.
105 for (i
= 0; i
< n
; i
++) {
106 if (mask
& (1ul << i
)) {
107 update_tree_entry(t
+i
);
110 entry_clear(entry
+ i
);
112 callback(n
, mask
, entry
, base
);