Code

Merge branch 'maint'
[git.git] / dir.c
diff --git a/dir.c b/dir.c
index 1f507daff2c278a70da768e3754a68891b946973..9501476ecdb05fb576d8acfc6a1dac02df86c9b7 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -52,6 +52,11 @@ int common_prefix(const char **pathspec)
        return prefix;
 }
 
+static inline int special_char(unsigned char c1)
+{
+       return !c1 || c1 == '*' || c1 == '[' || c1 == '?';
+}
+
 /*
  * Does 'match' matches the given name?
  * A match is found if
@@ -69,18 +74,31 @@ static int match_one(const char *match, const char *name, int namelen)
        int matchlen;
 
        /* If the match was just the prefix, we matched */
-       matchlen = strlen(match);
-       if (!matchlen)
+       if (!*match)
                return MATCHED_RECURSIVELY;
 
+       for (;;) {
+               unsigned char c1 = *match;
+               unsigned char c2 = *name;
+               if (special_char(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(match, name, matchlen))
                return !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;
 
-       if (!name[matchlen])
+       if (namelen == matchlen)
                return MATCHED_EXACTLY;
        if (match[matchlen-1] == '/' || name[matchlen] == '/')
                return MATCHED_RECURSIVELY;
@@ -704,8 +722,7 @@ static struct path_simplify *create_simplify(const char **pathspec)
 
 static void free_simplify(struct path_simplify *simplify)
 {
-       if (simplify)
-               free(simplify);
+       free(simplify);
 }
 
 int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)