[PATCH] Make git-cherry handle root trees

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxx>
---

Example for testing: 'git-cherry v0.99.1 v0.99.2' in the git repo
hits root trees.

 builtin-log.c |    7 +++++--
 diff.h        |    2 ++
 log-tree.c    |   26 ++++----------------------
 tree-diff.c   |   18 ++++++++++++++++++
 4 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/builtin-log.c b/builtin-log.c
index fc5e476..fedb013 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -171,8 +171,11 @@ static void reopen_stdout(struct commit
 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 ce3058e..ac7b21c 100644
--- a/diff.h
+++ b/diff.h
@@ -102,6 +102,8 @@ extern int diff_tree(struct tree_desc *t
 		     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;
diff --git a/log-tree.c b/log-tree.c
index fbe1399..8787df5 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -252,26 +252,6 @@ int log_tree_diff_flush(struct rev_info
 	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
 	/* 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;
 	}
 
diff --git a/tree-diff.c b/tree-diff.c
index 7e2f4f0..37d235e 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -215,6 +215,24 @@ int diff_tree_sha1(const unsigned char *
 	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;
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]