зеркало из https://github.com/microsoft/git.git
remove match_pathspec() in favor of match_pathspec_depth()
match_pathspec_depth was created to replace match_pathspec (see
61cf282
(pathspec: add match_pathspec_depth() - 2010-12-15). It took
more than two years, but the replacement finally happens :-)
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:
Родитель
9a08727443
Коммит
84b8b5d1fa
|
@ -195,22 +195,20 @@ int add_files_to_cache(const char *prefix,
|
|||
}
|
||||
|
||||
#define WARN_IMPLICIT_DOT (1u << 0)
|
||||
static char *prune_directory(struct dir_struct *dir, const char **pathspec,
|
||||
static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
|
||||
int prefix, unsigned flag)
|
||||
{
|
||||
char *seen;
|
||||
int i, specs;
|
||||
int i;
|
||||
struct dir_entry **src, **dst;
|
||||
|
||||
for (specs = 0; pathspec[specs]; specs++)
|
||||
/* nothing */;
|
||||
seen = xcalloc(specs, 1);
|
||||
seen = xcalloc(pathspec->nr, 1);
|
||||
|
||||
src = dst = dir->entries;
|
||||
i = dir->nr;
|
||||
while (--i >= 0) {
|
||||
struct dir_entry *entry = *src++;
|
||||
if (match_pathspec(pathspec, entry->name, entry->len,
|
||||
if (match_pathspec_depth(pathspec, entry->name, entry->len,
|
||||
prefix, seen))
|
||||
*dst++ = entry;
|
||||
else if (flag & WARN_IMPLICIT_DOT)
|
||||
|
@ -225,7 +223,7 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec,
|
|||
warn_pathless_add();
|
||||
}
|
||||
dir->nr = dst - dir->entries;
|
||||
add_pathspec_matches_against_index(pathspec, seen, specs);
|
||||
add_pathspec_matches_against_index(pathspec, seen);
|
||||
return seen;
|
||||
}
|
||||
|
||||
|
@ -523,7 +521,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||
/* This picks up the paths that are not tracked */
|
||||
baselen = fill_directory(&dir, implicit_dot ? &empty_pathspec : &pathspec);
|
||||
if (pathspec.nr)
|
||||
seen = prune_directory(&dir, pathspec.raw, baselen,
|
||||
seen = prune_directory(&dir, &pathspec, baselen,
|
||||
implicit_dot ? WARN_IMPLICIT_DOT : 0);
|
||||
}
|
||||
|
||||
|
@ -538,23 +536,23 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||
int i;
|
||||
|
||||
if (!seen)
|
||||
seen = find_pathspecs_matching_against_index(pathspec.raw);
|
||||
seen = find_pathspecs_matching_against_index(&pathspec);
|
||||
|
||||
/*
|
||||
* file_exists() assumes exact match
|
||||
*/
|
||||
GUARD_PATHSPEC(&pathspec, PATHSPEC_FROMTOP);
|
||||
|
||||
for (i = 0; pathspec.raw[i]; i++) {
|
||||
if (!seen[i] && pathspec.raw[i][0]
|
||||
&& !file_exists(pathspec.raw[i])) {
|
||||
for (i = 0; i < pathspec.nr; i++) {
|
||||
const char *path = pathspec.items[i].match;
|
||||
if (!seen[i] && !file_exists(path)) {
|
||||
if (ignore_missing) {
|
||||
int dtype = DT_UNKNOWN;
|
||||
if (is_excluded(&dir, pathspec.raw[i], &dtype))
|
||||
dir_add_ignored(&dir, pathspec.raw[i], strlen(pathspec.raw[i]));
|
||||
if (is_excluded(&dir, path, &dtype))
|
||||
dir_add_ignored(&dir, path, pathspec.items[i].len);
|
||||
} else
|
||||
die(_("pathspec '%s' did not match any files"),
|
||||
pathspec.raw[i]);
|
||||
pathspec.items[i].original);
|
||||
}
|
||||
}
|
||||
free(seen);
|
||||
|
|
|
@ -94,9 +94,9 @@ static int check_ignore(struct dir_struct *dir,
|
|||
* should not be ignored, in order to be consistent with
|
||||
* 'git status', 'git add' etc.
|
||||
*/
|
||||
seen = find_pathspecs_matching_against_index(pathspec.raw);
|
||||
seen = find_pathspecs_matching_against_index(&pathspec);
|
||||
for (i = 0; i < pathspec.nr; i++) {
|
||||
full_path = pathspec.raw[i];
|
||||
full_path = pathspec.items[i].match;
|
||||
exclude = NULL;
|
||||
if (!seen[i]) {
|
||||
exclude = last_exclude_matching(dir, full_path, &dtype);
|
||||
|
|
107
dir.c
107
dir.c
|
@ -171,113 +171,6 @@ int within_depth(const char *name, int namelen,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does 'match' match the given name?
|
||||
* A match is found if
|
||||
*
|
||||
* (1) the 'match' string is leading directory of 'name', or
|
||||
* (2) the 'match' string is a wildcard and matches 'name', or
|
||||
* (3) the 'match' string is exactly the same as 'name'.
|
||||
*
|
||||
* and the return value tells which case it was.
|
||||
*
|
||||
* It returns 0 when there is no match.
|
||||
*/
|
||||
static int match_one(const char *match, const char *name, int namelen)
|
||||
{
|
||||
int matchlen;
|
||||
int literal = limit_pathspec_to_literal();
|
||||
|
||||
/* If the match was just the prefix, we matched */
|
||||
if (!*match)
|
||||
return MATCHED_RECURSIVELY;
|
||||
|
||||
if (ignore_case) {
|
||||
for (;;) {
|
||||
unsigned char c1 = tolower(*match);
|
||||
unsigned char c2 = tolower(*name);
|
||||
if (c1 == '\0' || (!literal && is_glob_special(c1)))
|
||||
break;
|
||||
if (c1 != c2)
|
||||
return 0;
|
||||
match++;
|
||||
name++;
|
||||
namelen--;
|
||||
}
|
||||
} else {
|
||||
for (;;) {
|
||||
unsigned char c1 = *match;
|
||||
unsigned char c2 = *name;
|
||||
if (c1 == '\0' || (!literal && is_glob_special(c1)))
|
||||
break;
|
||||
if (c1 != c2)
|
||||
return 0;
|
||||
match++;
|
||||
name++;
|
||||
namelen--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't match the matchstring exactly,
|
||||
* we need to match by fnmatch
|
||||
*/
|
||||
matchlen = strlen(match);
|
||||
if (strncmp_icase(match, name, matchlen)) {
|
||||
if (literal)
|
||||
return 0;
|
||||
return !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0;
|
||||
}
|
||||
|
||||
if (namelen == matchlen)
|
||||
return MATCHED_EXACTLY;
|
||||
if (match[matchlen-1] == '/' || name[matchlen] == '/')
|
||||
return MATCHED_RECURSIVELY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a name and a list of pathspecs, returns the nature of the
|
||||
* closest (i.e. most specific) match of the name to any of the
|
||||
* pathspecs.
|
||||
*
|
||||
* The caller typically calls this multiple times with the same
|
||||
* pathspec and seen[] array but with different name/namelen
|
||||
* (e.g. entries from the index) and is interested in seeing if and
|
||||
* how each pathspec matches all the names it calls this function
|
||||
* with. A mark is left in the seen[] array for each pathspec element
|
||||
* indicating the closest type of match that element achieved, so if
|
||||
* seen[n] remains zero after multiple invocations, that means the nth
|
||||
* pathspec did not match any names, which could indicate that the
|
||||
* user mistyped the nth pathspec.
|
||||
*/
|
||||
int match_pathspec(const char **pathspec, const char *name, int namelen,
|
||||
int prefix, char *seen)
|
||||
{
|
||||
int i, retval = 0;
|
||||
|
||||
if (!pathspec)
|
||||
return 1;
|
||||
|
||||
name += prefix;
|
||||
namelen -= prefix;
|
||||
|
||||
for (i = 0; pathspec[i] != NULL; i++) {
|
||||
int how;
|
||||
const char *match = pathspec[i] + prefix;
|
||||
if (seen && seen[i] == MATCHED_EXACTLY)
|
||||
continue;
|
||||
how = match_one(match, name, namelen);
|
||||
if (how) {
|
||||
if (retval < how)
|
||||
retval = how;
|
||||
if (seen && seen[i] < how)
|
||||
seen[i] = how;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does 'match' match the given name?
|
||||
* A match is found if
|
||||
|
|
1
dir.h
1
dir.h
|
@ -131,7 +131,6 @@ struct dir_struct {
|
|||
extern int simple_length(const char *match);
|
||||
extern int no_wildcard(const char *string);
|
||||
extern char *common_prefix(const struct pathspec *pathspec);
|
||||
extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
|
||||
extern int match_pathspec_depth(const struct pathspec *pathspec,
|
||||
const char *name, int namelen,
|
||||
int prefix, char *seen);
|
||||
|
|
19
pathspec.c
19
pathspec.c
|
@ -15,8 +15,8 @@
|
|||
* If seen[] has not already been written to, it may make sense
|
||||
* to use find_pathspecs_matching_against_index() instead.
|
||||
*/
|
||||
void add_pathspec_matches_against_index(const char **pathspec,
|
||||
char *seen, int specs)
|
||||
void add_pathspec_matches_against_index(const struct pathspec *pathspec,
|
||||
char *seen)
|
||||
{
|
||||
int num_unmatched = 0, i;
|
||||
|
||||
|
@ -26,14 +26,14 @@ void add_pathspec_matches_against_index(const char **pathspec,
|
|||
* mistakenly think that the user gave a pathspec that did not match
|
||||
* anything.
|
||||
*/
|
||||
for (i = 0; i < specs; i++)
|
||||
for (i = 0; i < pathspec->nr; i++)
|
||||
if (!seen[i])
|
||||
num_unmatched++;
|
||||
if (!num_unmatched)
|
||||
return;
|
||||
for (i = 0; i < active_nr; i++) {
|
||||
struct cache_entry *ce = active_cache[i];
|
||||
match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);
|
||||
match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,15 +45,10 @@ void add_pathspec_matches_against_index(const char **pathspec,
|
|||
* nature of the "closest" (i.e. most specific) matches which each of the
|
||||
* given pathspecs achieves against all items in the index.
|
||||
*/
|
||||
char *find_pathspecs_matching_against_index(const char **pathspec)
|
||||
char *find_pathspecs_matching_against_index(const struct pathspec *pathspec)
|
||||
{
|
||||
char *seen;
|
||||
int i;
|
||||
|
||||
for (i = 0; pathspec[i]; i++)
|
||||
; /* just counting */
|
||||
seen = xcalloc(i, 1);
|
||||
add_pathspec_matches_against_index(pathspec, seen, i);
|
||||
char *seen = xcalloc(pathspec->nr, 1);
|
||||
add_pathspec_matches_against_index(pathspec, seen);
|
||||
return seen;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ extern void free_pathspec(struct pathspec *);
|
|||
|
||||
extern int limit_pathspec_to_literal(void);
|
||||
|
||||
extern char *find_pathspecs_matching_against_index(const char **pathspec);
|
||||
extern void add_pathspec_matches_against_index(const char **pathspec, char *seen, int specs);
|
||||
extern char *find_pathspecs_matching_against_index(const struct pathspec *pathspec);
|
||||
extern void add_pathspec_matches_against_index(const struct pathspec *pathspec, char *seen);
|
||||
extern const char *check_path_for_gitlink(const char *path);
|
||||
extern void die_if_path_beyond_symlink(const char *path, const char *prefix);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче