From eeb3f32868862609b475122f3e0c2ef7c0dd3e79 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Mon, 3 Feb 2014 16:47:20 +0400 Subject: [PATCH] combine-diff: move changed-paths scanning logic into its own function Move code for finding paths for which diff(commit,parent_i) is not-empty for all parents to separate function - at present we have generic (and slow) code for this job, which translates 1 n-parent problem to n 1-parent problems and then intersect results, and will be adding another limited, but faster, paths scanning implementation in the next patch. Signed-off-by: Kirill Smelkov Signed-off-by: Junio C Hamano --- combine-diff.c | 80 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index 68d2e53be6..1732dfd110 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -1301,6 +1301,51 @@ static const char *path_path(void *obj) return path->path; } + +/* find set of paths that every parent touches */ +static struct combine_diff_path *find_paths(const unsigned char *sha1, + const struct sha1_array *parents, struct diff_options *opt) +{ + struct combine_diff_path *paths = NULL; + int i, num_parent = parents->nr; + + int output_format = opt->output_format; + const char *orderfile = opt->orderfile; + + opt->output_format = DIFF_FORMAT_NO_OUTPUT; + /* tell diff_tree to emit paths in sorted (=tree) order */ + opt->orderfile = NULL; + + for (i = 0; i < num_parent; i++) { + /* + * show stat against the first parent even when doing + * combined diff. + */ + int stat_opt = (output_format & + (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT)); + if (i == 0 && stat_opt) + opt->output_format = stat_opt; + else + opt->output_format = DIFF_FORMAT_NO_OUTPUT; + diff_tree_sha1(parents->sha1[i], sha1, "", opt); + diffcore_std(opt); + paths = intersect_paths(paths, i, num_parent); + + /* if showing diff, show it in requested order */ + if (opt->output_format != DIFF_FORMAT_NO_OUTPUT && + orderfile) { + diffcore_order(orderfile); + } + + diff_flush(opt); + } + + opt->output_format = output_format; + opt->orderfile = orderfile; + return paths; +} + + void diff_tree_combined(const unsigned char *sha1, const struct sha1_array *parents, int dense, @@ -1308,7 +1353,7 @@ void diff_tree_combined(const unsigned char *sha1, { struct diff_options *opt = &rev->diffopt; struct diff_options diffopts; - struct combine_diff_path *p, *paths = NULL; + struct combine_diff_path *p, *paths; int i, num_paths, needsep, show_log_first, num_parent = parents->nr; /* nothing to do, if no parents */ @@ -1327,35 +1372,16 @@ void diff_tree_combined(const unsigned char *sha1, diffopts = *opt; copy_pathspec(&diffopts.pathspec, &opt->pathspec); - diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; DIFF_OPT_SET(&diffopts, RECURSIVE); DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL); - /* tell diff_tree to emit paths in sorted (=tree) order */ - diffopts.orderfile = NULL; - /* find set of paths that everybody touches */ - for (i = 0; i < num_parent; i++) { - /* show stat against the first parent even - * when doing combined diff. - */ - int stat_opt = (opt->output_format & - (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT)); - if (i == 0 && stat_opt) - diffopts.output_format = stat_opt; - else - diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; - diff_tree_sha1(parents->sha1[i], sha1, "", &diffopts); - diffcore_std(&diffopts); - paths = intersect_paths(paths, i, num_parent); - - /* if showing diff, show it in requested order */ - if (diffopts.output_format != DIFF_FORMAT_NO_OUTPUT && - opt->orderfile) { - diffcore_order(opt->orderfile); - } - - diff_flush(&diffopts); - } + /* find set of paths that everybody touches + * + * NOTE find_paths() also handles --stat, as it computes + * diff(sha1,parent_i) for all i to do the job, specifically + * for parent0. + */ + paths = find_paths(sha1, parents, &diffopts); /* find out number of surviving paths */ for (num_paths = 0, p = paths; p; p = p->next)