5 static struct tree_entry
*update_tree_entry(void **bufp
, unsigned long *sizep
)
8 unsigned long size
= *sizep
;
9 int len
= strlen(buf
) + 1 + 20;
12 usage("corrupt tree file");
18 static const unsigned char *extract(void *tree
, unsigned long size
, const char **pathp
, unsigned int *modep
)
20 int len
= strlen(tree
)+1;
21 const unsigned char *sha1
= tree
+ len
;
22 const char *path
= strchr(tree
, ' ');
24 if (!path
|| size
< len
+ 20 || sscanf(tree
, "%o", modep
) != 1)
25 usage("corrupt tree file");
30 static void show_file(const char *prefix
, void *tree
, unsigned long size
)
34 const unsigned char *sha1
= extract(tree
, size
, &path
, &mode
);
35 printf("%s%o %s %s%c", prefix
, mode
, sha1_to_hex(sha1
), path
, 0);
38 static int compare_tree_entry(void *tree1
, unsigned long size1
, void *tree2
, unsigned long size2
)
40 unsigned mode1
, mode2
;
41 const char *path1
, *path2
;
42 const unsigned char *sha1
, *sha2
;
45 sha1
= extract(tree1
, size1
, &path1
, &mode1
);
46 sha2
= extract(tree2
, size2
, &path2
, &mode2
);
48 cmp
= cache_name_compare(path1
, strlen(path1
), path2
, strlen(path2
));
50 show_file("-", tree1
, size1
);
54 show_file("+", tree2
, size2
);
57 if (!memcmp(sha1
, sha2
, 20) && mode1
== mode2
)
59 show_file("<", tree1
, size1
);
60 show_file(">", tree2
, size2
);
64 static int diff_tree(void *tree1
, unsigned long size1
, void *tree2
, unsigned long size2
)
66 while (size1
| size2
) {
68 show_file("+", tree2
, size2
);
69 update_tree_entry(&tree2
, &size2
);
73 show_file("-", tree1
, size1
);
74 update_tree_entry(&tree1
, &size1
);
77 switch (compare_tree_entry(tree1
, size1
, tree2
, size2
)) {
79 update_tree_entry(&tree1
, &size1
);
82 update_tree_entry(&tree1
, &size1
);
85 update_tree_entry(&tree2
, &size2
);
88 usage("diff-tree: internal error");
93 int main(int argc
, char **argv
)
95 unsigned char old
[20], new[20];
97 unsigned long size1
, size2
;
100 if (argc
!= 3 || get_sha1_hex(argv
[1], old
) || get_sha1_hex(argv
[2], new))
101 usage("diff-tree <tree sha1> <tree sha1>");
102 tree1
= read_sha1_file(old
, type
, &size1
);
103 if (!tree1
|| strcmp(type
, "tree"))
104 usage("unable to read source tree");
105 tree2
= read_sha1_file(new, type
, &size2
);
106 if (!tree2
|| strcmp(type
, "tree"))
107 usage("unable to read destination tree");
108 return diff_tree(tree1
, size1
, tree2
, size2
);