diff --git a/src/attr_file.c b/src/attr_file.c index 5ec5b4408..dcf54fdd4 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -359,6 +359,7 @@ bool git_attr_fnmatch__match( git_attr_fnmatch *match, git_attr_path *path) { + const char *relpath = path->path; const char *filename; int flags = 0; @@ -375,6 +376,8 @@ bool git_attr_fnmatch__match( if (git__prefixcmp(path->path, match->containing_dir)) return 0; } + + relpath += match->containing_dir_length; } if (match->flags & GIT_ATTR_FNMATCH_ICASE) @@ -383,7 +386,7 @@ bool git_attr_fnmatch__match( flags |= FNM_LEADING_DIR; if (match->flags & GIT_ATTR_FNMATCH_FULLPATH) { - filename = path->path; + filename = relpath; flags |= FNM_PATHNAME; } else { filename = path->basename; @@ -393,9 +396,6 @@ bool git_attr_fnmatch__match( } if ((match->flags & GIT_ATTR_FNMATCH_DIRECTORY) && !path->is_dir) { - int matchval; - char *matchpath; - /* for attribute checks or root ignore checks, fail match */ if (!(match->flags & GIT_ATTR_FNMATCH_IGNORE) || path->basename == path->path) @@ -403,32 +403,24 @@ bool git_attr_fnmatch__match( flags |= FNM_LEADING_DIR; - /* for ignore checks, use container of current item for check */ - if (match->containing_dir) - matchpath = path->basename; - else - matchpath = path->path; - /* fail match if this is a file with same name as ignored folder */ bool samename = (match->flags & GIT_ATTR_FNMATCH_ICASE) ? - !strcasecmp(match->pattern, matchpath) : - !strcmp(match->pattern, matchpath); + !strcasecmp(match->pattern, relpath) : + !strcmp(match->pattern, relpath); if (samename) return false; - matchval = p_fnmatch(match->pattern, matchpath, flags); - - return (matchval != FNM_NOMATCH); + return (p_fnmatch(match->pattern, relpath, flags) != FNM_NOMATCH); } /* if path is a directory prefix of a negated pattern, then match */ if ((match->flags & GIT_ATTR_FNMATCH_NEGATIVE) && path->is_dir) { - size_t pathlen = strlen(path->path); + size_t pathlen = strlen(relpath); bool prefixed = (pathlen <= match->length) && ((match->flags & GIT_ATTR_FNMATCH_ICASE) ? - !strncasecmp(match->pattern, path->path, pathlen) : - !strncmp(match->pattern, path->path, pathlen)); + !strncasecmp(match->pattern, relpath, pathlen) : + !strncmp(match->pattern, relpath, pathlen)); if (prefixed && git_path_at_end_of_segment(&match->pattern[pathlen])) return true; @@ -647,7 +639,7 @@ int git_attr_fnmatch__parse( } if (context) { - char *slash = strchr(context, '/'); + char *slash = strrchr(context, '/'); size_t len; if (slash) { /* include the slash for easier matching */ @@ -657,27 +649,7 @@ int git_attr_fnmatch__parse( } } - if ((spec->flags & GIT_ATTR_FNMATCH_FULLPATH) != 0 && - context != NULL && git_path_root(pattern) < 0) - { - /* use context path minus the trailing filename */ - char *slash = strrchr(context, '/'); - size_t contextlen = slash ? slash - context + 1 : 0; - - /* given an unrooted fullpath match from a file inside a repo, - * prefix the pattern with the relative directory of the source file - */ - spec->pattern = git_pool_malloc( - pool, (uint32_t)(contextlen + spec->length + 1)); - if (spec->pattern) { - memcpy(spec->pattern, context, contextlen); - memcpy(spec->pattern + contextlen, pattern, spec->length); - spec->length += contextlen; - spec->pattern[spec->length] = '\0'; - } - } else { - spec->pattern = git_pool_strndup(pool, pattern, spec->length); - } + spec->pattern = git_pool_strndup(pool, pattern, spec->length); if (!spec->pattern) { *base = git__next_line(pattern);