From: Junio C Hamano Date: Wed, 11 Mar 2009 20:53:53 +0000 (-0700) Subject: Merge branch 'fg/maint-exclude-bq' into maint X-Git-Tag: v1.6.2.1~6 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/5f7b3383106d4dc8b9556d52e8fabd8d468c994a?ds=inline;hp=-c Merge branch 'fg/maint-exclude-bq' into maint * fg/maint-exclude-bq: Support "\" in non-wildcard exclusion entries --- 5f7b3383106d4dc8b9556d52e8fabd8d468c994a diff --combined dir.c index cfd1ea587d,04a4b9861e..2245749b3f --- a/dir.c +++ b/dir.c @@@ -52,6 -52,11 +52,6 @@@ int common_prefix(const char **pathspec return prefix; } -static inline int special_char(unsigned char c1) -{ - return !c1 || c1 == '*' || c1 == '[' || c1 == '?' || c1 == '\\'; -} - /* * Does 'match' matches the given name? * A match is found if @@@ -75,7 -80,7 +75,7 @@@ static int match_one(const char *match for (;;) { unsigned char c1 = *match; unsigned char c2 = *name; - if (special_char(c1)) + if (c1 == '\0' || is_glob_special(c1)) break; if (c1 != c2) return 0; @@@ -108,28 -113,25 +108,28 @@@ * and a mark is left in seen[] array for pathspec element that * actually matched anything. */ -int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen) +int match_pathspec(const char **pathspec, const char *name, int namelen, + int prefix, char *seen) { - int retval; - const char *match; + int i, retval = 0; + + if (!pathspec) + return 1; name += prefix; namelen -= prefix; - for (retval = 0; (match = *pathspec++) != NULL; seen++) { + for (i = 0; pathspec[i] != NULL; i++) { int how; - if (retval && *seen == MATCHED_EXACTLY) + const char *match = pathspec[i] + prefix; + if (seen && seen[i] == MATCHED_EXACTLY) continue; - match += prefix; how = match_one(match, name, namelen); if (how) { if (retval < how) retval = how; - if (*seen < how) - *seen = how; + if (seen && seen[i] < how) + seen[i] = how; } } return retval; @@@ -137,7 -139,7 +137,7 @@@ static int no_wildcard(const char *string) { - return string[strcspn(string, "*?[{")] == '\0'; + return string[strcspn(string, "*?[{\\")] == '\0'; } void add_exclude(const char *string, const char *base, @@@ -385,7 -387,7 +385,7 @@@ static struct dir_entry *dir_entry_new( return ent; } -struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len) +static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len) { if (cache_name_exists(pathname, len, ignore_case)) return NULL; @@@ -394,7 -396,7 +394,7 @@@ return dir->entries[dir->nr++] = dir_entry_new(pathname, len); } -struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len) +static struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len) { if (cache_name_pos(pathname, len) >= 0) return NULL; @@@ -588,8 -590,10 +588,8 @@@ static int read_directory_recursive(str int len, dtype; int exclude; - if ((de->d_name[0] == '.') && - (de->d_name[1] == 0 || - !strcmp(de->d_name + 1, ".") || - !strcmp(de->d_name + 1, "git"))) + if (is_dot_or_dotdot(de->d_name) || + !strcmp(de->d_name, ".git")) continue; len = strlen(de->d_name); /* Ignore overly long pathnames! */ @@@ -676,12 -680,17 +676,12 @@@ static int cmp_name(const void *p1, con */ static int simple_length(const char *match) { - const char special[256] = { - [0] = 1, ['?'] = 1, - ['\\'] = 1, ['*'] = 1, - ['['] = 1 - }; int len = -1; for (;;) { unsigned char c = *match++; len++; - if (special[c]) + if (c == '\0' || is_glob_special(c)) return len; } } @@@ -718,12 -727,8 +718,12 @@@ static void free_simplify(struct path_s int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec) { - struct path_simplify *simplify = create_simplify(pathspec); + struct path_simplify *simplify; + + if (has_symlink_leading_path(strlen(path), path)) + return dir->nr; + simplify = create_simplify(pathspec); read_directory_recursive(dir, path, base, baselen, 0, simplify); free_simplify(simplify); qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name); @@@ -780,25 -785,6 +780,25 @@@ int is_inside_dir(const char *dir return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL; } +int is_empty_dir(const char *path) +{ + DIR *dir = opendir(path); + struct dirent *e; + int ret = 1; + + if (!dir) + return 0; + + while ((e = readdir(dir)) != NULL) + if (!is_dot_or_dotdot(e->d_name)) { + ret = 0; + break; + } + + closedir(dir); + return ret; +} + int remove_dir_recursively(struct strbuf *path, int only_empty) { DIR *dir = opendir(path->buf); @@@ -813,8 -799,10 +813,8 @@@ len = path->len; while ((e = readdir(dir)) != NULL) { struct stat st; - if ((e->d_name[0] == '.') && - ((e->d_name[1] == 0) || - ((e->d_name[1] == '.') && e->d_name[2] == 0))) - continue; /* "." and ".." */ + if (is_dot_or_dotdot(e->d_name)) + continue; strbuf_setlen(path, len); strbuf_addstr(path, e->d_name); diff --combined t/t3001-ls-files-others-exclude.sh index 85aef12a11,6a17113745..c65bca8388 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@@ -19,6 -19,9 +19,9 @@@ d >$dir/a.$i done done + >"#ignore1" + >"#ignore2" + >"#hidden" cat >expect <output && test_cmp expect output' - cat > excludes-file << EOF + cat > excludes-file <<\EOF *.[1-8] e* + \#* EOF git config core.excludesFile excludes-file @@@ -140,10 -147,4 +147,10 @@@ test_expect_success 'trailing slash in ' +test_expect_success 'negated exclude matches can override previous ones' ' + + git ls-files --others --exclude="a.*" --exclude="!a.1" >output && + grep "^a.1" output +' + test_done