зеркало из https://github.com/microsoft/git.git
Move tree_entry_interesting() to tree-walk.c and export it
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
475005a117
Коммит
2c389fc8ec
112
tree-diff.c
112
tree-diff.c
|
@ -82,118 +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?
|
||||
*
|
||||
* Pre-condition: baselen == 0 || base[baselen-1] == '/'
|
||||
*
|
||||
* 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(const struct name_entry *entry, const char *base, int baselen, const struct pathspec *ps)
|
||||
{
|
||||
int i;
|
||||
int pathlen;
|
||||
int never_interesting = -1;
|
||||
|
||||
if (!ps || !ps->nr)
|
||||
return 2;
|
||||
|
||||
pathlen = tree_entry_len(entry->path, entry->sha1);
|
||||
|
||||
for (i = 0; i < ps->nr; i++) {
|
||||
const struct pathspec_item *item = ps->items+i;
|
||||
const char *match = item->match;
|
||||
int matchlen = item->len;
|
||||
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, entry->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(entry->mode))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m == -1)
|
||||
/*
|
||||
* we cheated and did not do strncmp(), so we do
|
||||
* that here.
|
||||
*/
|
||||
m = strncmp(match, entry->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)
|
||||
{
|
||||
|
|
114
tree-walk.c
114
tree-walk.c
|
@ -455,3 +455,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?
|
||||
*
|
||||
* Pre-condition: baselen == 0 || base[baselen-1] == '/'
|
||||
*
|
||||
* 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"
|
||||
*/
|
||||
int tree_entry_interesting(const struct name_entry *entry,
|
||||
const char *base, int baselen,
|
||||
const struct pathspec *ps)
|
||||
{
|
||||
int i;
|
||||
int pathlen;
|
||||
int never_interesting = -1;
|
||||
|
||||
if (!ps || !ps->nr)
|
||||
return 2;
|
||||
|
||||
pathlen = tree_entry_len(entry->path, entry->sha1);
|
||||
|
||||
for (i = 0; i < ps->nr; i++) {
|
||||
const struct pathspec_item *item = ps->items+i;
|
||||
const char *match = item->match;
|
||||
int matchlen = item->len;
|
||||
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, entry->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(entry->mode))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m == -1)
|
||||
/*
|
||||
* we cheated and did not do strncmp(), so we do
|
||||
* that here.
|
||||
*/
|
||||
m = strncmp(match, entry->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 */
|
||||
}
|
||||
|
|
|
@ -60,4 +60,6 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru
|
|||
return info->pathlen + tree_entry_len(n->path, n->sha1);
|
||||
}
|
||||
|
||||
extern int tree_entry_interesting(const struct name_entry *, const char *, int, const struct pathspec *ps);
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче