{"thread":{"id":"43777","subject":"[PATCH] Make git-cherry handle root trees","startedAt":"2006-10-26T16:52:39Z","lastAt":"2006-10-26T16:52:39Z","messageCount":1,"participants":["Rene Scharfe"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"298575","messageId":"4540E7D7.1000208@lsrfire.ath.cx","threadId":"43777","inReplyTo":null,"subject":"[PATCH] Make git-cherry handle root trees","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2006-10-26T16:52:39Z","receivedAt":"2006-10-26T16:52:39Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"This patch on top of 'next' makes built-in git-cherry handle root\ncommits.\n\nIt moves the static function log-tree.c::diff_root_tree() to\ntree-diff.c and makes it more similar to diff_tree_sha1() by\nshuffling around arguments and factoring out the call to\nlog_tree_diff_flush().  Consequently the name is changed to\ndiff_root_tree_sha1().  It is a version of diff_tree_sha1() that\ncompares the empty tree (= root tree) against a single 'real' tree.\n\nThis function is then used in get_patch_id() to compute patch IDs\nfor initial commits instead of SEGFAULTing, as the current code\ndoes if confronted with parentless commits.\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n\nExample for testing: 'git-cherry v0.99.1 v0.99.2' in the git repo\nhits root trees.\n\n builtin-log.c |    7 +++++--\n diff.h        |    2 ++\n log-tree.c    |   26 ++++----------------------\n tree-diff.c   |   18 ++++++++++++++++++\n 4 files changed, 29 insertions(+), 24 deletions(-)\n\ndiff --git a/builtin-log.c b/builtin-log.c\nindex fc5e476..fedb013 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -171,8 +171,11 @@ static void reopen_stdout(struct commit\n static int get_patch_id(struct commit *commit, struct diff_options *options,\n \t\tunsigned char *sha1)\n {\n-\tdiff_tree_sha1(commit->parents->item->object.sha1, commit->object.sha1,\n-\t\t\t\"\", options);\n+\tif (commit->parents)\n+\t\tdiff_tree_sha1(commit->parents->item->object.sha1,\n+\t\t               commit->object.sha1, \"\", options);\n+\telse\n+\t\tdiff_root_tree_sha1(commit->object.sha1, \"\", options);\n \tdiffcore_std(options);\n \treturn diff_flush_patch_id(options, sha1);\n }\ndiff --git a/diff.h b/diff.h\nindex ce3058e..ac7b21c 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -102,6 +102,8 @@ extern int diff_tree(struct tree_desc *t\n \t\t     const char *base, struct diff_options *opt);\n extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new,\n \t\t\t  const char *base, struct diff_options *opt);\n+extern int diff_root_tree_sha1(const unsigned char *new, const char *base,\n+                               struct diff_options *opt);\n \n struct combine_diff_path {\n \tstruct combine_diff_path *next;\ndiff --git a/log-tree.c b/log-tree.c\nindex fbe1399..8787df5 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -252,26 +252,6 @@ int log_tree_diff_flush(struct rev_info\n \treturn 1;\n }\n \n-static int diff_root_tree(struct rev_info *opt,\n-\t\t\t  const unsigned char *new, const char *base)\n-{\n-\tint retval;\n-\tvoid *tree;\n-\tstruct tree_desc empty, real;\n-\n-\ttree = read_object_with_reference(new, tree_type, &real.size, NULL);\n-\tif (!tree)\n-\t\tdie(\"unable to read root tree (%s)\", sha1_to_hex(new));\n-\treal.buf = tree;\n-\n-\tempty.buf = \"\";\n-\tempty.size = 0;\n-\tretval = diff_tree(&empty, &real, base, &opt->diffopt);\n-\tfree(tree);\n-\tlog_tree_diff_flush(opt);\n-\treturn retval;\n-}\n-\n static int do_diff_combined(struct rev_info *opt, struct commit *commit)\n {\n \tunsigned const char *sha1 = commit->object.sha1;\n@@ -297,8 +277,10 @@ static int log_tree_diff(struct rev_info\n \t/* Root commit? */\n \tparents = commit->parents;\n \tif (!parents) {\n-\t\tif (opt->show_root_diff)\n-\t\t\tdiff_root_tree(opt, sha1, \"\");\n+\t\tif (opt->show_root_diff) {\n+\t\t\tdiff_root_tree_sha1(sha1, \"\", &opt->diffopt);\n+\t\t\tlog_tree_diff_flush(opt);\n+\t\t}\n \t\treturn !opt->loginfo;\n \t}\n \ndiff --git a/tree-diff.c b/tree-diff.c\nindex 7e2f4f0..37d235e 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -215,6 +215,24 @@ int diff_tree_sha1(const unsigned char *\n \treturn retval;\n }\n \n+int diff_root_tree_sha1(const unsigned char *new, const char *base, struct diff_options *opt)\n+{\n+\tint retval;\n+\tvoid *tree;\n+\tstruct tree_desc empty, real;\n+\n+\ttree = read_object_with_reference(new, tree_type, &real.size, NULL);\n+\tif (!tree)\n+\t\tdie(\"unable to read root tree (%s)\", sha1_to_hex(new));\n+\treal.buf = tree;\n+\n+\tempty.size = 0;\n+\tempty.buf = \"\";\n+\tretval = diff_tree(&empty, &real, base, opt);\n+\tfree(tree);\n+\treturn retval;\n+}\n+\n static int count_paths(const char **paths)\n {\n"}]}