]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'nd/maint-relative'
authorJunio C Hamano <gitster@pobox.com>
Thu, 16 Dec 2010 20:49:48 +0000 (12:49 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Dec 2010 20:49:48 +0000 (12:49 -0800)
* nd/maint-relative:
  get_cwd_relative(): do not misinterpret root path

1  2 
dir.c

diff --combined dir.c
index 852e60f2a8d4784bf73d044f89fe822538121286,ee9299db0536e14a6fdb78f3f5a25ea62aaf6075..38f3e3eb9770a9f3d85f175881bd2dd4ced6548b
--- 1/dir.c
--- 2/dir.c
+++ b/dir.c
@@@ -18,22 -18,6 +18,22 @@@ static int read_directory_recursive(str
        int check_only, const struct path_simplify *simplify);
  static int get_dtype(struct dirent *de, const char *path, int len);
  
 +/* helper string functions with support for the ignore_case flag */
 +int strcmp_icase(const char *a, const char *b)
 +{
 +      return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
 +}
 +
 +int strncmp_icase(const char *a, const char *b, size_t count)
 +{
 +      return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
 +}
 +
 +int fnmatch_icase(const char *pattern, const char *string, int flags)
 +{
 +      return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
 +}
 +
  static int common_prefix(const char **pathspec)
  {
        const char *path, *slash, *next;
@@@ -107,30 -91,16 +107,30 @@@ static int match_one(const char *match
        if (!*match)
                return MATCHED_RECURSIVELY;
  
 -      for (;;) {
 -              unsigned char c1 = *match;
 -              unsigned char c2 = *name;
 -              if (c1 == '\0' || is_glob_special(c1))
 -                      break;
 -              if (c1 != c2)
 -                      return 0;
 -              match++;
 -              name++;
 -              namelen--;
 +      if (ignore_case) {
 +              for (;;) {
 +                      unsigned char c1 = tolower(*match);
 +                      unsigned char c2 = tolower(*name);
 +                      if (c1 == '\0' || 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' || is_glob_special(c1))
 +                              break;
 +                      if (c1 != c2)
 +                              return 0;
 +                      match++;
 +                      name++;
 +                      namelen--;
 +              }
        }
  
  
         * we need to match by fnmatch
         */
        matchlen = strlen(match);
 -      if (strncmp(match, name, matchlen))
 -              return !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;
 +      if (strncmp_icase(match, name, matchlen))
 +              return !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0;
  
        if (namelen == matchlen)
                return MATCHED_EXACTLY;
@@@ -262,7 -232,7 +262,7 @@@ int add_excludes_from_file_to_list(cons
  {
        struct stat st;
        int fd, i;
 -      size_t size;
 +      size_t size = 0;
        char *buf, *entry;
  
        fd = open(fname, O_RDONLY);
@@@ -390,8 -360,7 +390,8 @@@ int excluded_from_list(const char *path
  
                        if (x->flags & EXC_FLAG_MUSTBEDIR) {
                                if (!dtype) {
 -                                      if (!prefixcmp(pathname, exclude))
 +                                      if (!prefixcmp(pathname, exclude) &&
 +                                          pathname[x->patternlen] == '/')
                                                return to_exclude;
                                        else
                                                continue;
                        if (x->flags & EXC_FLAG_NODIR) {
                                /* match basename */
                                if (x->flags & EXC_FLAG_NOWILDCARD) {
 -                                      if (!strcmp(exclude, basename))
 +                                      if (!strcmp_icase(exclude, basename))
                                                return to_exclude;
                                } else if (x->flags & EXC_FLAG_ENDSWITH) {
                                        if (x->patternlen - 1 <= pathlen &&
 -                                          !strcmp(exclude + 1, pathname + pathlen - x->patternlen + 1))
 +                                          !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1))
                                                return to_exclude;
                                } else {
 -                                      if (fnmatch(exclude, basename, 0) == 0)
 +                                      if (fnmatch_icase(exclude, basename, 0) == 0)
                                                return to_exclude;
                                }
                        }
  
                                if (pathlen < baselen ||
                                    (baselen && pathname[baselen-1] != '/') ||
 -                                  strncmp(pathname, x->base, baselen))
 +                                  strncmp_icase(pathname, x->base, baselen))
                                    continue;
  
                                if (x->flags & EXC_FLAG_NOWILDCARD) {
 -                                      if (!strcmp(exclude, pathname + baselen))
 +                                      if (!strcmp_icase(exclude, pathname + baselen))
                                                return to_exclude;
                                } else {
 -                                      if (fnmatch(exclude, pathname+baselen,
 +                                      if (fnmatch_icase(exclude, pathname+baselen,
                                                    FNM_PATHNAME) == 0)
                                            return to_exclude;
                                }
@@@ -484,7 -453,7 +484,7 @@@ static struct dir_entry *dir_add_name(s
        return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
  }
  
 -static struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
 +struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
  {
        if (!cache_name_is_other(pathname, len))
                return NULL;
  enum exist_status {
        index_nonexistent = 0,
        index_directory,
 -      index_gitdir,
 +      index_gitdir
  };
  
 +/*
 + * Do not use the alphabetically stored index to look up
 + * the directory name; instead, use the case insensitive
 + * name hash.
 + */
 +static enum exist_status directory_exists_in_index_icase(const char *dirname, int len)
 +{
 +      struct cache_entry *ce = index_name_exists(&the_index, dirname, len + 1, ignore_case);
 +      unsigned char endchar;
 +
 +      if (!ce)
 +              return index_nonexistent;
 +      endchar = ce->name[len];
 +
 +      /*
 +       * The cache_entry structure returned will contain this dirname
 +       * and possibly additional path components.
 +       */
 +      if (endchar == '/')
 +              return index_directory;
 +
 +      /*
 +       * If there are no additional path components, then this cache_entry
 +       * represents a submodule.  Submodules, despite being directories,
 +       * are stored in the cache without a closing slash.
 +       */
 +      if (!endchar && S_ISGITLINK(ce->ce_mode))
 +              return index_gitdir;
 +
 +      /* This should never be hit, but it exists just in case. */
 +      return index_nonexistent;
 +}
 +
  /*
   * The index sorts alphabetically by entry name, which
   * means that a gitlink sorts as '\0' at the end, while
   */
  static enum exist_status directory_exists_in_index(const char *dirname, int len)
  {
 -      int pos = cache_name_pos(dirname, len);
 +      int pos;
 +
 +      if (ignore_case)
 +              return directory_exists_in_index_icase(dirname, len);
 +
 +      pos = cache_name_pos(dirname, len);
        if (pos < 0)
                pos = -pos-1;
        while (pos < active_nr) {
  enum directory_treatment {
        show_directory,
        ignore_directory,
 -      recurse_into_directory,
 +      recurse_into_directory
  };
  
  static enum directory_treatment treat_directory(struct dir_struct *dir,
@@@ -753,7 -684,7 +753,7 @@@ static int get_dtype(struct dirent *de
  enum path_treatment {
        path_ignored,
        path_handled,
 -      path_recurse,
 +      path_recurse
  };
  
  static enum path_treatment treat_one_path(struct dir_struct *dir,
@@@ -1033,6 -964,12 +1033,12 @@@ char *get_relative_cwd(char *buffer, in
        case '/':
                return cwd + 1;
        default:
+               /*
+                * dir can end with a path separator when it's root
+                * directory. Return proper prefix in that case.
+                */
+               if (dir[-1] == '/')
+                       return cwd;
                return NULL;
        }
  }