contacts: fix to work in subdirectories
[gitweb.git] / pathspec.c
index 6a16938cb65936fd1df816b149408daa57945c55..4b32cc32cb5b0be495ac941c5e96d8aee8fd8ff9 100644 (file)
@@ -32,7 +32,7 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec,
        if (!num_unmatched)
                return;
        for (i = 0; i < active_nr; i++) {
-               struct cache_entry *ce = active_cache[i];
+               const struct cache_entry *ce = active_cache[i];
                match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);
        }
 }
@@ -57,8 +57,6 @@ char *find_pathspecs_matching_against_index(const struct pathspec *pathspec)
  *
  * Possible future magic semantics include stuff like:
  *
- *     { PATHSPEC_NOGLOB, '!', "noglob" },
- *     { PATHSPEC_ICASE, '\0', "icase" },
  *     { PATHSPEC_RECURSIVE, '*', "recursive" },
  *     { PATHSPEC_REGEXP, '\0', "regexp" },
  *
@@ -71,6 +69,8 @@ static struct pathspec_magic {
 } pathspec_magic[] = {
        { PATHSPEC_FROMTOP, '/', "top" },
        { PATHSPEC_LITERAL,   0, "literal" },
+       { PATHSPEC_GLOB,   '\0', "glob" },
+       { PATHSPEC_ICASE,  '\0', "icase" },
 };
 
 /*
@@ -93,6 +93,9 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
                                const char *elt)
 {
        static int literal_global = -1;
+       static int glob_global = -1;
+       static int noglob_global = -1;
+       static int icase_global = -1;
        unsigned magic = 0, short_magic = 0, global_magic = 0;
        const char *copyfrom = elt, *long_magic_end = NULL;
        char *match;
@@ -103,7 +106,29 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
        if (literal_global)
                global_magic |= PATHSPEC_LITERAL;
 
-       if (elt[0] != ':') {
+       if (glob_global < 0)
+               glob_global = git_env_bool(GIT_GLOB_PATHSPECS_ENVIRONMENT, 0);
+       if (glob_global)
+               global_magic |= PATHSPEC_GLOB;
+
+       if (noglob_global < 0)
+               noglob_global = git_env_bool(GIT_NOGLOB_PATHSPECS_ENVIRONMENT, 0);
+
+       if (glob_global && noglob_global)
+               die(_("global 'glob' and 'noglob' pathspec settings are incompatible"));
+
+
+       if (icase_global < 0)
+               icase_global = git_env_bool(GIT_ICASE_PATHSPECS_ENVIRONMENT, 0);
+       if (icase_global)
+               global_magic |= PATHSPEC_ICASE;
+
+       if ((global_magic & PATHSPEC_LITERAL) &&
+           (global_magic & ~PATHSPEC_LITERAL))
+               die(_("global 'literal' pathspec setting is incompatible "
+                     "with all other global pathspec settings"));
+
+       if (elt[0] != ':' || literal_global) {
                ; /* nothing to do */
        } else if (elt[1] == '(') {
                /* longhand */
@@ -167,12 +192,24 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 
        magic |= short_magic;
        *p_short_magic = short_magic;
+
+       /* --noglob-pathspec adds :(literal) _unless_ :(glob) is specifed */
+       if (noglob_global && !(magic & PATHSPEC_GLOB))
+               global_magic |= PATHSPEC_LITERAL;
+
+       /* --glob-pathspec is overriden by :(literal) */
+       if ((global_magic & PATHSPEC_GLOB) && (magic & PATHSPEC_LITERAL))
+               global_magic &= ~PATHSPEC_GLOB;
+
        magic |= global_magic;
 
        if (pathspec_prefix >= 0 &&
            (prefixlen || (prefix && *prefix)))
                die("BUG: 'prefix' magic is supposed to be used at worktree's root");
 
+       if ((magic & PATHSPEC_LITERAL) && (magic & PATHSPEC_GLOB))
+               die(_("%s: 'literal' and 'glob' are incompatible"), elt);
+
        if (pathspec_prefix >= 0) {
                match = xstrdup(copyfrom);
                prefixlen = pathspec_prefix;
@@ -248,10 +285,17 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
                        item->nowildcard_len = prefixlen;
        }
        item->flags = 0;
-       if (item->nowildcard_len < item->len &&
-           item->match[item->nowildcard_len] == '*' &&
-           no_wildcard(item->match + item->nowildcard_len + 1))
-               item->flags |= PATHSPEC_ONESTAR;
+       if (magic & PATHSPEC_GLOB) {
+               /*
+                * FIXME: should we enable ONESTAR in _GLOB for
+                * pattern "* * / * . c"?
+                */
+       } else {
+               if (item->nowildcard_len < item->len &&
+                   item->match[item->nowildcard_len] == '*' &&
+                   no_wildcard(item->match + item->nowildcard_len + 1))
+                       item->flags |= PATHSPEC_ONESTAR;
+       }
 
        /* sanity checks, pathspec matchers assume these are sane */
        assert(item->nowildcard_len <= item->len &&