From: Junio C Hamano Date: Wed, 27 Oct 2010 04:37:49 +0000 (-0700) Subject: Merge branch 'en/tree-walk-optim' X-Git-Tag: v1.7.4-rc0~171 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/acbaf54f3030854b54f8391f7d1ca11935a75518?ds=inline;hp=-c Merge branch 'en/tree-walk-optim' * en/tree-walk-optim: diff_tree(): Skip skip_uninteresting() when all remaining paths interesting tree_entry_interesting(): Make return value more specific tree-walk: Correct bitrotted comment about tree_entry() Document pre-condition for tree_entry_interesting --- acbaf54f3030854b54f8391f7d1ca11935a75518 diff --combined tree-diff.c index cd659c6fe4,f6a6b2f71f..12c9a88884 --- a/tree-diff.c +++ b/tree-diff.c @@@ -85,6 -85,8 +85,8 @@@ static int compare_tree_entry(struct tr /* * Is a tree entry interesting given the pathspec we have? * + * Pre-condition: baselen == 0 || base[baselen-1] == '/' + * * Return: * - 2 for "yes, and all subsequent entries will be" * - 1 for yes @@@ -101,7 -103,7 +103,7 @@@ static int tree_entry_interesting(struc int never_interesting = -1; if (!opt->nr_paths) - return 1; + return 2; sha1 = tree_entry_extract(desc, &path, &mode); @@@ -257,19 -259,12 +259,12 @@@ static void show_entry(struct diff_opti } } - static void skip_uninteresting(struct tree_desc *t, const char *base, int baselen, struct diff_options *opt) + static void skip_uninteresting(struct tree_desc *t, const char *base, int baselen, struct diff_options *opt, int *all_interesting) { - int all_interesting = 0; while (t->size) { - int show; - - if (all_interesting) - show = 1; - else { - show = tree_entry_interesting(t, base, baselen, opt); - if (show == 2) - all_interesting = 1; - } + int show = tree_entry_interesting(t, base, baselen, opt); + if (show == 2) + *all_interesting = 1; if (!show) { update_tree_entry(t); continue; @@@ -284,14 -279,20 +279,20 @@@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt) { int baselen = strlen(base); + int all_t1_interesting = 0; + int all_t2_interesting = 0; for (;;) { if (DIFF_OPT_TST(opt, QUICK) && DIFF_OPT_TST(opt, HAS_CHANGES)) break; if (opt->nr_paths) { - skip_uninteresting(t1, base, baselen, opt); - skip_uninteresting(t2, base, baselen, opt); + if (!all_t1_interesting) + skip_uninteresting(t1, base, baselen, opt, + &all_t1_interesting); + if (!all_t2_interesting) + skip_uninteresting(t2, base, baselen, opt, + &all_t2_interesting); } if (!t1->size) { if (!t2->size) @@@ -346,7 -347,7 +347,7 @@@ static void try_to_follow_renames(struc diff_setup(&diff_opts); DIFF_OPT_SET(&diff_opts, RECURSIVE); - diff_opts.detect_rename = DIFF_DETECT_RENAME; + DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER); diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = opt->paths[0]; diff_opts.break_opt = opt->break_opt; @@@ -359,7 -360,6 +360,7 @@@ diff_tree_release_paths(&diff_opts); /* Go through the new set of filepairing, and see if we find a more interesting one */ + opt->found_follow = 0; for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; @@@ -377,16 -377,6 +378,16 @@@ diff_tree_release_paths(opt); opt->paths[0] = xstrdup(p->one->path); diff_tree_setup_paths(opt->paths, opt); + + /* + * The caller expects us to return a set of vanilla + * filepairs to let a later call to diffcore_std() + * it makes to sort the renames out (among other + * things), but we already have found renames + * ourselves; signal diffcore_std() not to muck with + * rename information. + */ + opt->found_follow = 1; break; } } @@@ -423,7 -413,7 +424,7 @@@ int diff_tree_sha1(const unsigned char init_tree_desc(&t1, tree1, size1); init_tree_desc(&t2, tree2, size2); retval = diff_tree(&t1, &t2, base, opt); - if (DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) { + if (!*base && DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) { init_tree_desc(&t1, tree1, size1); init_tree_desc(&t2, tree2, size2); try_to_follow_renames(&t1, &t2, base, opt);