strncmp provides length information, compared to strcmp, which could be taken advantage by the implementation. Even better, we could check if the lengths are equal before calling strncmp, eliminating a bit of strncmp calls. before after user 0m0.519s 0m0.489s user 0m0.521s 0m0.504s user 0m0.523s 0m0.507s user 0m0.532s 0m0.510s user 0m0.534s 0m0.513s user 0m0.536s 0m0.514s user 0m0.537s 0m0.522s user 0m0.545s 0m0.523s user 0m0.546s 0m0.527s user 0m0.548s 0m0.529s While at there, fix an inconsistency about pattern/patternlen in how attr handles EXC_FLAG_MUSTBEDIR. When parse_exclude_pattern detects this flag, it sets patternlen _not_ to include the trailing slash and expects the caller to trim it. add_exclude does, parse_attr_line does not. In attr.c, the pattern could be "foo/" while patternlen tells us it only has 3 chars. Some functions do not care about patternlen and will see the pattern as "foo/" while others may see it as "foo". This patch makes patternlen 4 in this case. (Although for a piece of mind, perhaps we should trim it to "foo" like exclude, and never pass a pathname like "abc/" to match_{base,path}name) Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- attr.c | 2 ++ dir.c | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/attr.c b/attr.c index e2f9377..1818ba5 100644 --- a/attr.c +++ b/attr.c @@ -255,6 +255,8 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, &res->u.pat.patternlen, &res->u.pat.flags, &res->u.pat.nowildcardlen); + if (res->u.pat.flags & EXC_FLAG_MUSTBEDIR) + res->u.pat.patternlen++; if (res->u.pat.flags & EXC_FLAG_NEGATIVE) { warning(_("Negative patterns are ignored in git attributes\n" "Use '\\!' for literal leading exclamation.")); diff --git a/dir.c b/dir.c index f58320d..2a91d14 100644 --- a/dir.c +++ b/dir.c @@ -610,12 +610,14 @@ int match_basename(const char *basename, int basenamelen, int flags) { if (prefix == patternlen) { - if (!strcmp_icase(pattern, basename)) + if (patternlen == basenamelen && + !strncmp_icase(pattern, basename, patternlen)) return 1; } else if (flags & EXC_FLAG_ENDSWITH) { if (patternlen - 1 <= basenamelen && - !strcmp_icase(pattern + 1, - basename + basenamelen - patternlen + 1)) + !strncmp_icase(pattern + 1, + basename + basenamelen - patternlen + 1, + patternlen - 1)) return 1; } else { if (fnmatch_icase(pattern, basename, 0) == 0) -- 1.8.1.2.536.gf441e6d -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html