diff options
| author | Carlos Martín Nieto <cmn@dwim.me> | 2015-05-13 21:43:58 +0200 |
|---|---|---|
| committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-05-13 21:43:58 +0200 |
| commit | 16d742ebdb91492b784555cb528408531995634c (patch) | |
| tree | 1ea3600aa1caacfbb825a370556fbb8688cdfa20 /src | |
| parent | cd430bc786877794b820b045ce610d2ac78036b3 (diff) | |
| parent | 882cc37f8360ef3a3d4dd60621f78375337df25f (diff) | |
| download | libgit2-16d742ebdb91492b784555cb528408531995634c.tar.gz | |
Merge pull request #3119 from ethomson/ignore
Attributes: don't match files for folders
Diffstat (limited to 'src')
| -rw-r--r-- | src/attr.c | 3 | ||||
| -rw-r--r-- | src/attr_file.c | 55 |
2 files changed, 20 insertions, 38 deletions
diff --git a/src/attr.c b/src/attr.c index 102d0248c..d43a15f50 100644 --- a/src/attr.c +++ b/src/attr.c @@ -309,7 +309,8 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session) if (error == 0) error = preload_attr_file( repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, sys.ptr); - else if (error != GIT_ENOTFOUND) + + if (error != GIT_ENOTFOUND) return error; git_buf_free(&sys); diff --git a/src/attr_file.c b/src/attr_file.c index ef98aacc2..89706865a 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,35 +396,33 @@ bool git_attr_fnmatch__match( } if ((match->flags & GIT_ATTR_FNMATCH_DIRECTORY) && !path->is_dir) { - int matchval; - char *matchpath; + bool samename; /* for attribute checks or root ignore checks, fail match */ if (!(match->flags & GIT_ATTR_FNMATCH_IGNORE) || path->basename == path->path) return false; - /* for ignore checks, use container of current item for check */ - path->basename[-1] = '\0'; flags |= FNM_LEADING_DIR; - if (match->containing_dir) - matchpath = path->basename; - else - matchpath = path->path; + /* fail match if this is a file with same name as ignored folder */ + samename = (match->flags & GIT_ATTR_FNMATCH_ICASE) ? + !strcasecmp(match->pattern, relpath) : + !strcmp(match->pattern, relpath); - matchval = p_fnmatch(match->pattern, matchpath, flags); - path->basename[-1] = '/'; - return (matchval != FNM_NOMATCH); + if (samename) + return false; + + 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; @@ -640,7 +641,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 */ @@ -650,27 +651,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); |
