1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-06-25 06:57:31 +02:00

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:
Nguyễn Thái Ngọc Duy 2013-07-14 15:36:00 +07:00 committed by Junio C Hamano
parent 9a08727443
commit 84b8b5d1fa
6 changed files with 25 additions and 140 deletions

View File

@ -195,23 +195,21 @@ 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,
prefix, seen))
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);

View File

@ -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
View File

@ -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
View File

@ -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);

View File

@ -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;
}

View File

@ -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);