Merge branch 'mm/config-xdg'
authorJunio C Hamano <gitster@pobox.com>
Wed, 25 Jul 2012 22:47:04 +0000 (15:47 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 25 Jul 2012 22:47:05 +0000 (15:47 -0700)
Finishing touches to the XDG support (new feature for 1.7.12) and
tests.

* mm/config-xdg:
t1306: check that XDG_CONFIG_HOME works
ignore: make sure we have an xdg path before using it
attr: make sure we have an xdg path before using it
test-lib.sh: unset XDG_CONFIG_HOME

1  2 
dir.c
t/test-lib.sh
diff --combined dir.c
index a772c6dc6c2bf4dc40f46f0bb5d0899312f3ffd4,059ec28dbbf25fd845bbeccb7e7852b5500036aa..240bf0c49c9654b7cef56959786613e17113c3a0
--- 1/dir.c
--- 2/dir.c
+++ b/dir.c
@@@ -288,24 -288,9 +288,24 @@@ int match_pathspec_depth(const struct p
        return retval;
  }
  
 +/*
 + * Return the length of the "simple" part of a path match limiter.
 + */
 +static int simple_length(const char *match)
 +{
 +      int len = -1;
 +
 +      for (;;) {
 +              unsigned char c = *match++;
 +              len++;
 +              if (c == '\0' || is_glob_special(c))
 +                      return len;
 +      }
 +}
 +
  static int no_wildcard(const char *string)
  {
 -      return string[strcspn(string, "*?[{\\")] == '\0';
 +      return string[simple_length(string)] == '\0';
  }
  
  void add_exclude(const char *string, const char *base,
        x->flags = flags;
        if (!strchr(string, '/'))
                x->flags |= EXC_FLAG_NODIR;
 -      if (no_wildcard(string))
 -              x->flags |= EXC_FLAG_NOWILDCARD;
 +      x->nowildcardlen = simple_length(string);
        if (*string == '*' && no_wildcard(string+1))
                x->flags |= EXC_FLAG_ENDSWITH;
        ALLOC_GROW(which->excludes, which->nr + 1, which->alloc);
@@@ -512,69 -498,57 +512,69 @@@ int excluded_from_list(const char *path
  {
        int i;
  
 -      if (el->nr) {
 -              for (i = el->nr - 1; 0 <= i; i--) {
 -                      struct exclude *x = el->excludes[i];
 -                      const char *exclude = x->pattern;
 -                      int to_exclude = x->to_exclude;
 -
 -                      if (x->flags & EXC_FLAG_MUSTBEDIR) {
 -                              if (*dtype == DT_UNKNOWN)
 -                                      *dtype = get_dtype(NULL, pathname, pathlen);
 -                              if (*dtype != DT_DIR)
 -                                      continue;
 -                      }
 +      if (!el->nr)
 +              return -1;      /* undefined */
  
 -                      if (x->flags & EXC_FLAG_NODIR) {
 -                              /* match basename */
 -                              if (x->flags & EXC_FLAG_NOWILDCARD) {
 -                                      if (!strcmp_icase(exclude, basename))
 -                                              return to_exclude;
 -                              } else if (x->flags & EXC_FLAG_ENDSWITH) {
 -                                      if (x->patternlen - 1 <= pathlen &&
 -                                          !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1))
 -                                              return to_exclude;
 -                              } else {
 -                                      if (fnmatch_icase(exclude, basename, 0) == 0)
 -                                              return to_exclude;
 -                              }
 -                      }
 -                      else {
 -                              /* match with FNM_PATHNAME:
 -                               * exclude has base (baselen long) implicitly
 -                               * in front of it.
 -                               */
 -                              int baselen = x->baselen;
 -                              if (*exclude == '/')
 -                                      exclude++;
 -
 -                              if (pathlen < baselen ||
 -                                  (baselen && pathname[baselen-1] != '/') ||
 -                                  strncmp_icase(pathname, x->base, baselen))
 -                                  continue;
 -
 -                              if (x->flags & EXC_FLAG_NOWILDCARD) {
 -                                      if (!strcmp_icase(exclude, pathname + baselen))
 -                                              return to_exclude;
 -                              } else {
 -                                      if (fnmatch_icase(exclude, pathname+baselen,
 -                                                  FNM_PATHNAME) == 0)
 -                                          return to_exclude;
 -                              }
 +      for (i = el->nr - 1; 0 <= i; i--) {
 +              struct exclude *x = el->excludes[i];
 +              const char *name, *exclude = x->pattern;
 +              int to_exclude = x->to_exclude;
 +              int namelen, prefix = x->nowildcardlen;
 +
 +              if (x->flags & EXC_FLAG_MUSTBEDIR) {
 +                      if (*dtype == DT_UNKNOWN)
 +                              *dtype = get_dtype(NULL, pathname, pathlen);
 +                      if (*dtype != DT_DIR)
 +                              continue;
 +              }
 +
 +              if (x->flags & EXC_FLAG_NODIR) {
 +                      /* match basename */
 +                      if (prefix == x->patternlen) {
 +                              if (!strcmp_icase(exclude, basename))
 +                                      return to_exclude;
 +                      } else if (x->flags & EXC_FLAG_ENDSWITH) {
 +                              if (x->patternlen - 1 <= pathlen &&
 +                                  !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1))
 +                                      return to_exclude;
 +                      } else {
 +                              if (fnmatch_icase(exclude, basename, 0) == 0)
 +                                      return to_exclude;
                        }
 +                      continue;
 +              }
 +
 +              /* match with FNM_PATHNAME:
 +               * exclude has base (baselen long) implicitly in front of it.
 +               */
 +              if (*exclude == '/') {
 +                      exclude++;
 +                      prefix--;
                }
 +
 +              if (pathlen < x->baselen ||
 +                  (x->baselen && pathname[x->baselen-1] != '/') ||
 +                  strncmp_icase(pathname, x->base, x->baselen))
 +                      continue;
 +
 +              namelen = x->baselen ? pathlen - x->baselen : pathlen;
 +              name = pathname + pathlen  - namelen;
 +
 +              /* if the non-wildcard part is longer than the
 +                 remaining pathname, surely it cannot match */
 +              if (prefix > namelen)
 +                      continue;
 +
 +              if (prefix) {
 +                      if (strncmp_icase(exclude, name, prefix))
 +                              continue;
 +                      exclude += prefix;
 +                      name    += prefix;
 +                      namelen -= prefix;
 +              }
 +
 +              if (!namelen || !fnmatch_icase(exclude, name, FNM_PATHNAME))
 +                      return to_exclude;
        }
        return -1; /* undecided */
  }
@@@ -1081,6 -1055,21 +1081,6 @@@ static int cmp_name(const void *p1, con
                                  e2->name, e2->len);
  }
  
 -/*
 - * Return the length of the "simple" part of a path match limiter.
 - */
 -static int simple_length(const char *match)
 -{
 -      int len = -1;
 -
 -      for (;;) {
 -              unsigned char c = *match++;
 -              len++;
 -              if (c == '\0' || is_glob_special(c))
 -                      return len;
 -      }
 -}
 -
  static struct path_simplify *create_simplify(const char **pathspec)
  {
        int nr, alloc = 0;
@@@ -1313,7 -1302,7 +1313,7 @@@ void setup_standard_excludes(struct dir
        }
        if (!access(path, R_OK))
                add_excludes_from_file(dir, path);
-       if (!access(excludes_file, R_OK))
+       if (excludes_file && !access(excludes_file, R_OK))
                add_excludes_from_file(dir, excludes_file);
  }
  
diff --combined t/test-lib.sh
index acda33d177197c4288e8b7a33385f11c63c44698,2ac95361850b383b5e8c287e01938a051a500472..5e7f435d515f9eff54f2374beb83b75f556787af
@@@ -61,6 -61,7 +61,7 @@@ unset VISUAL EMAIL LANGUAGE COLUMNS $(p
        my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
        print join("\n", @vars);
  ')
+ unset XDG_CONFIG_HOME
  GIT_AUTHOR_EMAIL=author@example.com
  GIT_AUTHOR_NAME='A U Thor'
  GIT_COMMITTER_EMAIL=committer@example.com
@@@ -494,8 -495,6 +495,8 @@@ export PATH GIT_EXEC_PATH GIT_TEMPLATE_
  
  . "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
  
 +export PERL_PATH
 +
  if test -z "$GIT_TEST_CMP"
  then
        if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT"