Code

git-bundle: Make thin packs
[git.git] / tree-diff.c
index 1cdf8aa90850441d60553281a1928047563fe8a6..c8275823d0eb976e95b256f2bce5497f45d5da77 100644 (file)
@@ -15,7 +15,8 @@ static char *malloc_base(const char *base, const char *path, int pathlen)
        return newbase;
 }
 
-static int show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base);
+static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc,
+                      const char *base);
 
 static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt)
 {
@@ -38,8 +39,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
                show_entry(opt, "+", t2, base);
                return 1;
        }
-       if (!opt->find_copies_harder &&
-           !memcmp(sha1, sha2, 20) && mode1 == mode2)
+       if (!opt->find_copies_harder && !hashcmp(sha1, sha2) && mode1 == mode2)
                return 0;
 
        /*
@@ -131,20 +131,21 @@ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_
 }
 
 /* A file entry went away or appeared */
-static int show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base)
+static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc,
+                      const char *base)
 {
        unsigned mode;
        const char *path;
        const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode);
 
        if (opt->recursive && S_ISDIR(mode)) {
-               char type[20];
+               enum object_type type;
                char *newbase = malloc_base(base, path, strlen(path));
                struct tree_desc inner;
                void *tree;
 
-               tree = read_sha1_file(sha1, type, &inner.size);
-               if (!tree || strcmp(type, tree_type))
+               tree = read_sha1_file(sha1, &type, &inner.size);
+               if (!tree || type != OBJ_TREE)
                        die("corrupt tree sha %s", sha1_to_hex(sha1));
 
                inner.buf = tree;
@@ -152,11 +153,9 @@ static int show_entry(struct diff_options *opt, const char *prefix, struct tree_
 
                free(tree);
                free(newbase);
-               return 0;
+       } else {
+               opt->add_remove(opt, prefix[0], mode, sha1, base, path);
        }
-
-       opt->add_remove(opt, prefix[0], mode, sha1, base, path);
-       return 0;
 }
 
 int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt)
@@ -216,6 +215,24 @@ int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const cha
        return retval;
 }
 
+int diff_root_tree_sha1(const unsigned char *new, const char *base, struct diff_options *opt)
+{
+       int retval;
+       void *tree;
+       struct tree_desc empty, real;
+
+       tree = read_object_with_reference(new, tree_type, &real.size, NULL);
+       if (!tree)
+               die("unable to read root tree (%s)", sha1_to_hex(new));
+       real.buf = tree;
+
+       empty.size = 0;
+       empty.buf = "";
+       retval = diff_tree(&empty, &real, base, opt);
+       free(tree);
+       return retval;
+}
+
 static int count_paths(const char **paths)
 {
        int i = 0;