- unsigned mode1, mode2;
- const char *path1, *path2;
- const unsigned char *sha1, *sha2;
- int cmp, pathlen1, pathlen2;
-
- sha1 = extract(tree1, size1, &path1, &mode1);
- sha2 = extract(tree2, size2, &path2, &mode2);
-
- pathlen1 = strlen(path1);
- pathlen2 = strlen(path2);
- cmp = cache_name_compare(path1, pathlen1, path2, pathlen2);
- if (cmp < 0) {
- show_file("-", tree1, size1, src);
- return -1;
- }
- if (cmp > 0) {
- show_file("+", tree2, size2, dst);
- return 1;
- }
- if (!memcmp(sha1, sha2, 20) && mode1 == mode2)
- return 0;
- if (recursive && S_ISDIR(mode1) && S_ISDIR(mode2)) {
- int srclen = strlen(src);
- int dstlen = strlen(dst);
- char *srcbase = malloc(srclen + pathlen1 + 2);
- char *dstbase = malloc(srclen + pathlen1 + 2);
- memcpy(srcbase, src, srclen);
- memcpy(srcbase + srclen, path1, pathlen1);
- memcpy(srcbase + srclen + pathlen1, "/", 2);
- memcpy(dstbase, dst, dstlen);
- memcpy(dstbase + dstlen, path2, pathlen2);
- memcpy(dstbase + dstlen + pathlen2, "/", 2);
- return diff_tree_sha1(sha1, sha2, srcbase, dstbase);
- }