Make git-cherry handle root trees
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>
This commit is contained in:
parent
e827633a5d
commit
2b60356da5
@ -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);
|
||||
}
|
||||
|
2
diff.h
2
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;
|
||||
|
26
log-tree.c
26
log-tree.c
@ -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;
|
||||
}
|
||||
|
||||
|
18
tree-diff.c
18
tree-diff.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user