pathspec: make --literal-pathspecs disable pathspec magic
[gitweb.git] / dir.c
diff --git a/dir.c b/dir.c
index 019ad09b6e78ef9f2ee4ce057ffb826e48229bfb..50ec2f547800ecb929c694bd6ff059cbd38055da 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -108,7 +108,10 @@ static size_t common_prefix_len(const struct pathspec *pathspec)
        int n;
        size_t max = 0;
 
-       GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+       GUARD_PATHSPEC(pathspec,
+                      PATHSPEC_FROMTOP |
+                      PATHSPEC_MAXDEPTH |
+                      PATHSPEC_LITERAL);
 
        for (n = 0; n < pathspec->nr; n++) {
                size_t i = 0, len = 0;
@@ -152,7 +155,7 @@ int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
        len = common_prefix_len(pathspec);
 
        /* Read the directory and prune it */
-       read_directory(dir, pathspec->nr ? pathspec->raw[0] : "", len, pathspec);
+       read_directory(dir, pathspec->nr ? pathspec->_raw[0] : "", len, pathspec);
        return len;
 }
 
@@ -171,113 +174,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
@@ -339,7 +235,10 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
        int i, retval = 0;
 
-       GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+       GUARD_PATHSPEC(ps,
+                      PATHSPEC_FROMTOP |
+                      PATHSPEC_MAXDEPTH |
+                      PATHSPEC_LITERAL);
 
        if (!ps->nr) {
                if (!ps->recursive ||
@@ -1395,12 +1294,15 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru
         * Check out create_simplify()
         */
        if (pathspec)
-               GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+               GUARD_PATHSPEC(pathspec,
+                              PATHSPEC_FROMTOP |
+                              PATHSPEC_MAXDEPTH |
+                              PATHSPEC_LITERAL);
 
        if (has_symlink_leading_path(path, len))
                return dir->nr;
 
-       simplify = create_simplify(pathspec ? pathspec->raw : NULL);
+       simplify = create_simplify(pathspec ? pathspec->_raw : NULL);
        if (!len || treat_leading_path(dir, path, len, simplify))
                read_directory_recursive(dir, path, len, 0, simplify);
        free_simplify(simplify);
@@ -1580,72 +1482,6 @@ int remove_path(const char *name)
        return 0;
 }
 
-static int pathspec_item_cmp(const void *a_, const void *b_)
-{
-       struct pathspec_item *a, *b;
-
-       a = (struct pathspec_item *)a_;
-       b = (struct pathspec_item *)b_;
-       return strcmp(a->match, b->match);
-}
-
-int init_pathspec(struct pathspec *pathspec, const char **paths)
-{
-       const char **p = paths;
-       int i;
-
-       memset(pathspec, 0, sizeof(*pathspec));
-       if (!p)
-               return 0;
-       while (*p)
-               p++;
-       pathspec->raw = paths;
-       pathspec->nr = p - paths;
-       if (!pathspec->nr)
-               return 0;
-
-       pathspec->items = xmalloc(sizeof(struct pathspec_item)*pathspec->nr);
-       for (i = 0; i < pathspec->nr; i++) {
-               struct pathspec_item *item = pathspec->items+i;
-               const char *path = paths[i];
-
-               item->match = path;
-               item->original = path;
-               item->len = strlen(path);
-               item->flags = 0;
-               if (limit_pathspec_to_literal()) {
-                       item->nowildcard_len = item->len;
-               } else {
-                       item->nowildcard_len = simple_length(path);
-                       if (item->nowildcard_len < item->len) {
-                               pathspec->has_wildcard = 1;
-                               if (path[item->nowildcard_len] == '*' &&
-                                   no_wildcard(path + item->nowildcard_len + 1))
-                                       item->flags |= PATHSPEC_ONESTAR;
-                       }
-               }
-       }
-
-       qsort(pathspec->items, pathspec->nr,
-             sizeof(struct pathspec_item), pathspec_item_cmp);
-
-       return 0;
-}
-
-void free_pathspec(struct pathspec *pathspec)
-{
-       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;
-}
-
 /*
  * Frees memory within dir which was allocated for exclude lists and
  * the exclude_stack.  Does not free dir itself.