Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 attr.c |  4 +++-
 dir.c  | 19 ++++++++++++++-----
 dir.h  |  6 +++++-
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/attr.c b/attr.c
index 1818ba5..b89da33 100644
--- a/attr.c
+++ b/attr.c
@@ -249,12 +249,14 @@ static struct match_attr *parse_attr_line(const char 
*line, const char *src,
                res->u.attr = git_attr_internal(name, namelen);
        else {
                char *p = (char *)&(res->state[num_attr]);
+               int pattern_baselen;
                memcpy(p, name, namelen);
                res->u.pat.pattern = p;
                parse_exclude_pattern(&res->u.pat.pattern,
                                      &res->u.pat.patternlen,
                                      &res->u.pat.flags,
-                                     &res->u.pat.nowildcardlen);
+                                     &res->u.pat.nowildcardlen,
+                                     &pattern_baselen);
                if (res->u.pat.flags & EXC_FLAG_MUSTBEDIR)
                        res->u.pat.patternlen++;
                if (res->u.pat.flags & EXC_FLAG_NEGATIVE) {
diff --git a/dir.c b/dir.c
index f8f7a7e..932fd2f 100644
--- a/dir.c
+++ b/dir.c
@@ -390,10 +390,11 @@ static int no_wildcard(const char *string)
 void parse_exclude_pattern(const char **pattern,
                           int *patternlen,
                           int *flags,
-                          int *nowildcardlen)
+                          int *nowildcardlen,
+                          int *pattern_baselen)
 {
        const char *p = *pattern;
-       size_t i, len;
+       int i, len;
 
        *flags = 0;
        if (*p == '!') {
@@ -405,12 +406,15 @@ void parse_exclude_pattern(const char **pattern,
                len--;
                *flags |= EXC_FLAG_MUSTBEDIR;
        }
-       for (i = 0; i < len; i++) {
+       for (i = len - 1; i >= 0; i--) {
                if (p[i] == '/')
                        break;
        }
-       if (i == len)
+       if (i < 0) {
                *flags |= EXC_FLAG_NODIR;
+               *pattern_baselen = -1;
+       } else
+               *pattern_baselen = i;
        *nowildcardlen = simple_length(p);
        /*
         * we should have excluded the trailing slash from 'p' too,
@@ -421,6 +425,8 @@ void parse_exclude_pattern(const char **pattern,
                *nowildcardlen = len;
        if (*p == '*' && no_wildcard(p + 1))
                *flags |= EXC_FLAG_ENDSWITH;
+       else if (*nowildcardlen != len)
+               *pattern_baselen = -1;
        *pattern = p;
        *patternlen = len;
 }
@@ -432,8 +438,10 @@ void add_exclude(const char *string, const char *base,
        int patternlen;
        int flags;
        int nowildcardlen;
+       int pattern_baselen;
 
-       parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen);
+       parse_exclude_pattern(&string, &patternlen, &flags,
+                             &nowildcardlen, &pattern_baselen);
        if (flags & EXC_FLAG_MUSTBEDIR) {
                char *s;
                x = xmalloc(sizeof(*x) + patternlen + 1);
@@ -449,6 +457,7 @@ void add_exclude(const char *string, const char *base,
        x->nowildcardlen = nowildcardlen;
        x->base = base;
        x->baselen = baselen;
+       x->pattern_baselen = pattern_baselen;
        x->flags = flags;
        x->srcpos = srcpos;
        ALLOC_GROW(el->excludes, el->nr + 1, el->alloc);
diff --git a/dir.h b/dir.h
index 0748407..cb50a85 100644
--- a/dir.h
+++ b/dir.h
@@ -44,6 +44,7 @@ struct exclude_list {
                int nowildcardlen;
                const char *base;
                int baselen;
+               int pattern_baselen;
                int flags;
 
                /*
@@ -172,7 +173,10 @@ extern struct exclude_list *add_exclude_list(struct 
dir_struct *dir,
 extern int add_excludes_from_file_to_list(const char *fname, const char *base, 
int baselen,
                                          struct exclude_list *el, int 
check_index);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);
-extern void parse_exclude_pattern(const char **string, int *patternlen, int 
*flags, int *nowildcardlen);
+extern void parse_exclude_pattern(const char **string,
+                                 int *patternlen, int *flags,
+                                 int *nowildcardlen,
+                                 int *pattern_baselen);
 extern void add_exclude(const char *string, const char *base,
                        int baselen, struct exclude_list *el, int srcpos);
 extern void clear_exclude_list(struct exclude_list *el);
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to