Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- tree-diff.c | 114 ---------------------------------------------------------- tree-walk.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tree-walk.h | 3 ++ 3 files changed, 118 insertions(+), 114 deletions(-) diff --git a/tree-diff.c b/tree-diff.c index cd659c6..c74d0b5 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -82,120 +82,6 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const return 0; } -/* - * Is a tree entry interesting given the pathspec we have? - * - * Return: - * - 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" - */ -static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt) -{ - const char *path; - const unsigned char *sha1; - unsigned mode; - int i; - int pathlen; - int never_interesting = -1; - - if (!opt->nr_paths) - return 1; - - sha1 = tree_entry_extract(desc, &path, &mode); - - pathlen = tree_entry_len(path, sha1); - - for (i = 0; i < opt->nr_paths; i++) { - const char *match = opt->paths[i]; - int matchlen = opt->pathlens[i]; - 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; - - /* - * If the base is a subdirectory of a path which - * was specified, all of them are interesting. - */ - if (!matchlen || - base[matchlen] == '/' || - match[matchlen - 1] == '/') - return 2; - - /* Just a random prefix match */ - continue; - } - - /* Does the base match? */ - if (strncmp(base, match, baselen)) - continue; - - match += baselen; - matchlen -= baselen; - - 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 (pathlen > matchlen) - continue; - - if (matchlen > pathlen) { - if (match[pathlen] != '/') - continue; - if (!S_ISDIR(mode)) - 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 - * leading directory and is shorter than match. - */ - if (!m) - return 1; - } - return never_interesting; /* No matches */ -} - /* 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) { diff --git a/tree-walk.c b/tree-walk.c index a9bbf4e..bc83fa3 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -2,6 +2,7 @@ #include "tree-walk.h" #include "unpack-trees.h" #include "tree.h" +#include "diff.h" static const char *get_mode(const char *str, unsigned int *modep) { @@ -455,3 +456,117 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch free(tree); return retval; } + +/* + * Is a tree entry interesting given the pathspec we have? + * + * Return: + * - 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" + */ +static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt) +{ + const char *path; + const unsigned char *sha1; + unsigned mode; + int i; + int pathlen; + int never_interesting = -1; + + if (!opt->nr_paths) + return 1; + + sha1 = tree_entry_extract(desc, &path, &mode); + + pathlen = tree_entry_len(path, sha1); + + for (i = 0; i < opt->nr_paths; i++) { + const char *match = opt->paths[i]; + int matchlen = opt->pathlens[i]; + 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; + + /* + * If the base is a subdirectory of a path which + * was specified, all of them are interesting. + */ + if (!matchlen || + base[matchlen] == '/' || + match[matchlen - 1] == '/') + return 2; + + /* Just a random prefix match */ + continue; + } + + /* Does the base match? */ + if (strncmp(base, match, baselen)) + continue; + + match += baselen; + matchlen -= baselen; + + 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 (pathlen > matchlen) + continue; + + if (matchlen > pathlen) { + if (match[pathlen] != '/') + continue; + if (!S_ISDIR(mode)) + 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 + * leading directory and is shorter than match. + */ + if (!m) + return 1; + } + return never_interesting; /* No matches */ +} diff --git a/tree-walk.h b/tree-walk.h index 88ea7e9..0572721 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -57,4 +57,7 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru return info->pathlen + tree_entry_len(n->path, n->sha1); } +struct diff_options; +extern int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt); + #endif -- 1.7.1.rc1.69.g24c2f7 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html