Make git-cherry handle root trees
authorRene Scharfe <rene.scharfe@lsrfire.ath.cx>
Thu, 26 Oct 2006 16:52:39 +0000 (18:52 +0200)
committerJunio C Hamano <junkio@cox.net>
Fri, 27 Oct 2006 01:31:17 +0000 (18:31 -0700)
This patch on top of 'next' makes built-in git-cherry handle root
commits.

It moves the static function log-tree.c::diff_root_tree() to
tree-diff.c and makes it more similar to diff_tree_sha1() by
shuffling around arguments and factoring out the call to
log_tree_diff_flush().  Consequently the name is changed to
diff_root_tree_sha1().  It is a version of diff_tree_sha1() that
compares the empty tree (= root tree) against a single 'real' tree.

This function is then used in get_patch_id() to compute patch IDs
for initial commits instead of SEGFAULTing, as the current code
does if confronted with parentless commits.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <junkio@cox.net>
builtin-log.c
diff.h
log-tree.c
tree-diff.c

index fc5e47606c65962a7a1c1ab37a77f21f185a3bd5..fedb0137bc5e3ba50ecb90ce560ce9ce9290d8df 100644 (file)
@@ -171,8 +171,11 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
 static int get_patch_id(struct commit *commit, struct diff_options *options,
                unsigned char *sha1)
 {
-       diff_tree_sha1(commit->parents->item->object.sha1, commit->object.sha1,
-                       "", options);
+       if (commit->parents)
+               diff_tree_sha1(commit->parents->item->object.sha1,
+                              commit->object.sha1, "", options);
+       else
+               diff_root_tree_sha1(commit->object.sha1, "", options);
        diffcore_std(options);
        return diff_flush_patch_id(options, sha1);
 }
diff --git a/diff.h b/diff.h
index ce3058e437d5f0142be0746a3e50a3c32045eecb..ac7b21c46bdf958df5d7c8162c7aa248af54dbdb 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -102,6 +102,8 @@ extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
                     const char *base, struct diff_options *opt);
 extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new,
                          const char *base, struct diff_options *opt);
+extern int diff_root_tree_sha1(const unsigned char *new, const char *base,
+                               struct diff_options *opt);
 
 struct combine_diff_path {
        struct combine_diff_path *next;
index fbe139920ab0eada09dc921c152236d9676da44c..8787df5cc647dda24f09b077276cbe0aa054fc47 100644 (file)
@@ -252,26 +252,6 @@ int log_tree_diff_flush(struct rev_info *opt)
        return 1;
 }
 
-static int diff_root_tree(struct rev_info *opt,
-                         const unsigned char *new, const char *base)
-{
-       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.buf = "";
-       empty.size = 0;
-       retval = diff_tree(&empty, &real, base, &opt->diffopt);
-       free(tree);
-       log_tree_diff_flush(opt);
-       return retval;
-}
-
 static int do_diff_combined(struct rev_info *opt, struct commit *commit)
 {
        unsigned const char *sha1 = commit->object.sha1;
@@ -297,8 +277,10 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
        /* Root commit? */
        parents = commit->parents;
        if (!parents) {
-               if (opt->show_root_diff)
-                       diff_root_tree(opt, sha1, "");
+               if (opt->show_root_diff) {
+                       diff_root_tree_sha1(sha1, "", &opt->diffopt);
+                       log_tree_diff_flush(opt);
+               }
                return !opt->loginfo;
        }
 
index 7e2f4f088a359fe138b085730ba1b3465342e9e9..37d235e06e2cbfbd761fd02d7e73648a14a60daf 100644 (file)
@@ -215,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;