- }
- if (cmp > 0) {
- show_file("+", tree2, size2, base);
- return 1;
- }
- if (!memcmp(sha1, sha2, 20) && mode1 == mode2)
- return 0;
-
- /*
- * If the filemode has changed to/from a directory from/to a regular
- * file, we need to consider it a remove and an add.
- */
- if (S_ISDIR(mode1) != S_ISDIR(mode2)) {
- show_file("-", tree1, size1, base);
- show_file("+", tree2, size2, base);
- return 0;
- }
-
- if (recursive && S_ISDIR(mode1)) {
- int retval;
- char *newbase = malloc_base(base, path1, pathlen1);
- retval = diff_tree_sha1(sha1, sha2, newbase);
- free(newbase);
- return retval;
- }
-
- strcpy(old_sha1_hex, sha1_to_hex(sha1));
- printf("*%o->%o\t%s\t%s->%s\t%s%s%c", mode1, mode2,
- S_ISDIR(mode1) ? "tree" : "blob",
- old_sha1_hex, sha1_to_hex(sha2), base, path1,
- line_termination);
- return 0;
-}
-
-static int diff_tree(void *tree1, unsigned long size1, void *tree2, unsigned long size2, const char *base)
-{
- while (size1 | size2) {
- if (!size1) {
- show_file("+", tree2, size2, base);
- update_tree_entry(&tree2, &size2);
- continue;
- }
- if (!size2) {
- show_file("-", tree1, size1, base);
- update_tree_entry(&tree1, &size1);
- continue;
+ line[len-1] = 0;
+ if (get_sha1_hex(line, sha1))
+ return -1;
+ commit = lookup_commit(sha1);
+ if (!commit || parse_commit(commit))
+ return -1;
+ if (isspace(line[40]) && !get_sha1_hex(line+41, sha1)) {
+ /* Graft the fake parents locally to the commit */
+ int pos = 41;
+ struct commit_list **pptr, *parents;
+
+ /* Free the real parent list */
+ for (parents = commit->parents; parents; ) {
+ struct commit_list *tmp = parents->next;
+ free(parents);
+ parents = tmp;