diff --git a/tree-diff.c b/tree-diff.c index cd659c6fe4..12c9a88884 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -85,6 +85,8 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const /* * 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 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int int never_interesting = -1; if (!opt->nr_paths) - return 1; + return 2; sha1 = tree_entry_extract(desc, &path, &mode); @@ -257,19 +259,12 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree } } -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 @@ static void skip_uninteresting(struct tree_desc *t, const char *base, int basele 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)