+ call_diff_setup();
+ tree = read_object_with_reference(new, "tree", &size, NULL);
+ if (!tree)
+ die("unable to read root tree (%s)", sha1_to_hex(new));
+ retval = diff_tree("", 0, tree, size, base);
+ free(tree);
+ call_diff_flush();
+ return retval;
+}
+
+static const char *generate_header(const char *commit, const char *parent, const char *msg, unsigned long len)
+{
+ static char this_header[16384];
+ int offset;
+
+ if (!verbose_header)
+ return commit;
+
+ offset = sprintf(this_header, "%s%s (from %s)\n", header_prefix, commit, parent);
+ offset += pretty_print_commit(commit_format, msg, len, this_header + offset, sizeof(this_header) - offset);
+ return this_header;
+}
+
+static int diff_tree_commit(const unsigned char *commit, const char *name)
+{
+ unsigned long size, offset;
+ char *buf = read_object_with_reference(commit, "commit", &size, NULL);
+
+ if (!buf)
+ return -1;
+
+ if (!name) {
+ static char commit_name[60];
+ strcpy(commit_name, sha1_to_hex(commit));
+ name = commit_name;
+ }
+
+ /* Root commit? */
+ if (show_root_diff && memcmp(buf + 46, "parent ", 7)) {
+ header = generate_header(name, "root", buf, size);
+ diff_root_tree(commit, "");
+ }
+
+ /* More than one parent? */
+ if (ignore_merges) {
+ if (!memcmp(buf + 46 + 48, "parent ", 7))
+ return 0;