{
const char *n, *first;
size_t max = 0;
+ int literal = limit_pathspec_to_literal();
if (!pathspec)
return max;
size_t i, len = 0;
for (i = 0; first == n || i < max; i++) {
char c = n[i];
- if (!c || c != first[i] || is_glob_special(c))
+ if (!c || c != first[i] || (!literal && is_glob_special(c)))
break;
if (c == '/')
len = i + 1;
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)
for (;;) {
unsigned char c1 = tolower(*match);
unsigned char c2 = tolower(*name);
- if (c1 == '\0' || is_glob_special(c1))
+ if (c1 == '\0' || (!literal && is_glob_special(c1)))
break;
if (c1 != c2)
return 0;
for (;;) {
unsigned char c1 = *match;
unsigned char c2 = *name;
- if (c1 == '\0' || is_glob_special(c1))
+ if (c1 == '\0' || (!literal && is_glob_special(c1)))
break;
if (c1 != c2)
return 0;
}
}
-
/*
* If we don't match the matchstring exactly,
* we need to match by fnmatch
*/
matchlen = strlen(match);
- if (strncmp_icase(match, name, matchlen))
+ 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;
return string[simple_length(string)] == '\0';
}
-static void parse_exclude_pattern(const char **pattern,
- int *patternlen,
- int *flags,
- int *nowildcardlen)
+void parse_exclude_pattern(const char **pattern,
+ int *patternlen,
+ int *flags,
+ int *nowildcardlen)
{
const char *p = *pattern;
size_t i, len;
fd = open(fname, O_RDONLY);
if (fd < 0 || fstat(fd, &st) < 0) {
+ if (errno != ENOENT)
+ warn_on_inaccessible(fname);
if (0 <= fd)
close(fd);
if (!check_index ||
dir->basebuf[baselen] = '\0';
}
-static int match_basename(const char *basename, int basenamelen,
- const char *pattern, int prefix, int patternlen,
- int flags)
+int match_basename(const char *basename, int basenamelen,
+ const char *pattern, int prefix, int patternlen,
+ int flags)
{
if (prefix == patternlen) {
if (!strcmp_icase(pattern, basename))
return 0;
}
-static int match_pathname(const char *pathname, int pathlen,
- const char *base, int baselen,
- const char *pattern, int prefix, int patternlen,
- int flags)
+int match_pathname(const char *pathname, int pathlen,
+ const char *base, int baselen,
+ const char *pattern, int prefix, int patternlen,
+ int flags)
{
const char *name;
int namelen;
void setup_standard_excludes(struct dir_struct *dir)
{
const char *path;
+ char *xdg_path;
dir->exclude_per_dir = ".gitignore";
path = git_path("info/exclude");
- if (!access(path, R_OK))
+ if (!excludes_file) {
+ home_config_paths(NULL, &xdg_path, "ignore");
+ excludes_file = xdg_path;
+ }
+ if (!access_or_warn(path, R_OK))
add_excludes_from_file(dir, path);
- if (excludes_file && !access(excludes_file, R_OK))
+ if (excludes_file && !access_or_warn(excludes_file, R_OK))
add_excludes_from_file(dir, excludes_file);
}
item->match = path;
item->len = strlen(path);
- item->use_wildcard = !no_wildcard(path);
+ item->use_wildcard = !limit_pathspec_to_literal() &&
+ !no_wildcard(path);
if (item->use_wildcard)
pathspec->has_wildcard = 1;
}
free(pathspec->items);
pathspec->items = NULL;
}
+
+int limit_pathspec_to_literal(void)
+{
+ static int flag = -1;
+ if (flag < 0)
+ flag = git_env_bool(GIT_LITERAL_PATHSPECS_ENVIRONMENT, 0);
+ return flag;
+}