X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=tree-diff.c;h=852498eb49fe0cba5e1cd21661288e8321a4b20e;hb=566842f62bdf1f16c2e94fb431445d2e6c0f3f0b;hp=35af569fb814c5305e816ed52dd03c702cf7970e;hpb=7d2f667b12334cea68087eb7da717efd7b3d80f6;p=git.git diff --git a/tree-diff.c b/tree-diff.c index 35af569fb..852498eb4 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -70,7 +70,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? * * Return: - * - positive for yes + * - 2 for "yes, and all subsequent entries will be" + * - 1 for yes * - zero for no * - negative for "no, and no subsequent entries will be either" */ @@ -93,15 +94,18 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int for (i = 0; i < opt->nr_paths; i++) { const char *match = opt->paths[i]; int matchlen = opt->pathlens[i]; - int m; + int m = -1; /* signals that we haven't called strncmp() */ if (baselen >= matchlen) { /* If it doesn't match, move along... */ if (strncmp(base, match, matchlen)) continue; - /* The base is a subdirectory of a path which was specified. */ - return 1; + /* + * The base is a subdirectory of a path which + * was specified, so all of them are interesting. + */ + return 2; } /* Does the base match? */ @@ -111,29 +115,36 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int match += baselen; matchlen -= baselen; - /* - * Does match sort strictly earlier than path with their - * common parts? - */ - m = strncmp(match, path, - (matchlen < pathlen) ? matchlen : pathlen); - if (m < 0) - continue; + if (never_interesting) { + /* + * We have not seen any match that sorts later + * than the current path. + */ + + /* + * Does match sort strictly earlier than path + * with their common parts? + */ + m = strncmp(match, path, + (matchlen < pathlen) ? matchlen : pathlen); + if (m < 0) + continue; - /* - * If we come here even once, that means there is at - * least one pathspec that would sort equal to or - * later than the path we are currently looking at. - * In other words, if we have never reached this point - * after iterating all pathspecs, it means all - * pathspecs are either outside of base, or inside the - * base but sorts strictly earlier than the current - * one. In either case, they will never match the - * subsequent entries. In such a case, we initialized - * the variable to -1 and that is what will be - * returned, allowing the caller to terminate early. - */ - never_interesting = 0; + /* + * If we come here even once, that means there is at + * least one pathspec that would sort equal to or + * later than the path we are currently looking at. + * In other words, if we have never reached this point + * after iterating all pathspecs, it means all + * pathspecs are either outside of base, or inside the + * base but sorts strictly earlier than the current + * one. In either case, they will never match the + * subsequent entries. In such a case, we initialized + * the variable to -1 and that is what will be + * returned, allowing the caller to terminate early. + */ + never_interesting = 0; + } if (pathlen > matchlen) continue; @@ -145,6 +156,13 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int continue; } + if (m == -1) + /* + * we cheated and did not do strncmp(), so we do + * that here. + */ + m = strncmp(match, path, pathlen); + /* * If common part matched earlier then it is a hit, * because we rejected the case where path is not a @@ -159,8 +177,18 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int /* A whole sub-tree went away or appeared */ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen) { + int all_interesting = 0; while (desc->size) { - int show = tree_entry_interesting(desc, base, baselen, opt); + int show; + + if (all_interesting) + show = 1; + else { + show = tree_entry_interesting(desc, base, baselen, + opt); + if (show == 2) + all_interesting = 1; + } if (show < 0) break; if (show) @@ -201,8 +229,17 @@ 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) { + int all_interesting = 0; while (t->size) { - int show = tree_entry_interesting(t, base, baselen, opt); + int show; + + if (all_interesting) + show = 1; + else { + show = tree_entry_interesting(t, base, baselen, opt); + if (show == 2) + all_interesting = 1; + } if (!show) { update_tree_entry(t); continue;