From: Junio C Hamano Date: Sun, 7 Apr 2013 16:10:11 +0000 (-0700) Subject: Sync with 1.8.1.6 X-Git-Tag: v1.8.2.1~1 X-Git-Url: https://www.git.lorimer.id.au/gitweb.git/diff_plain/6466fbbeef67ec398f6f5d5b5da5d6f107a647b2 Sync with 1.8.1.6 --- 6466fbbeef67ec398f6f5d5b5da5d6f107a647b2 diff --cc Documentation/git.txt index 4307d62bd4,91299174f1..5a6178820d --- a/Documentation/git.txt +++ b/Documentation/git.txt @@@ -43,14 -43,10 +43,15 @@@ unreleased) version of Git, that is ava branch of the `git.git` repository. Documentation for older releases are available here: +* link:v1.8.2/git.html[documentation for release 1.8.2] + +* release notes for + link:RelNotes/1.8.2.txt[1.8.2]. + - * link:v1.8.1.5/git.html[documentation for release 1.8.1.5] + * link:v1.8.1.6/git.html[documentation for release 1.8.1.6] * release notes for + link:RelNotes/1.8.1.6.txt[1.8.1.6], link:RelNotes/1.8.1.5.txt[1.8.1.5], link:RelNotes/1.8.1.4.txt[1.8.1.4], link:RelNotes/1.8.1.3.txt[1.8.1.3], diff --cc dir.c index 57394e452e,6fdd3b2716..1e42b2b150 --- a/dir.c +++ b/dir.c @@@ -37,28 -34,33 +37,57 @@@ int fnmatch_icase(const char *pattern, return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0)); } +inline int git_fnmatch(const char *pattern, const char *string, + int flags, int prefix) +{ + int fnm_flags = 0; + if (flags & GFNM_PATHNAME) + fnm_flags |= FNM_PATHNAME; + if (prefix > 0) { + if (strncmp(pattern, string, prefix)) + return FNM_NOMATCH; + pattern += prefix; + string += prefix; + } + if (flags & GFNM_ONESTAR) { + int pattern_len = strlen(++pattern); + int string_len = strlen(string); + return string_len < pattern_len || + strcmp(pattern, + string + string_len - pattern_len); + } + return fnmatch(pattern, string, fnm_flags); +} + + static int fnmatch_icase_mem(const char *pattern, int patternlen, + const char *string, int stringlen, + int flags) + { + int match_status; + struct strbuf pat_buf = STRBUF_INIT; + struct strbuf str_buf = STRBUF_INIT; + const char *use_pat = pattern; + const char *use_str = string; + + if (pattern[patternlen]) { + strbuf_add(&pat_buf, pattern, patternlen); + use_pat = pat_buf.buf; + } + if (string[stringlen]) { + strbuf_add(&str_buf, string, stringlen); + use_str = str_buf.buf; + } + - match_status = fnmatch_icase(use_pat, use_str, flags); ++ if (ignore_case) ++ flags |= WM_CASEFOLD; ++ match_status = wildmatch(use_pat, use_str, flags, NULL); + + strbuf_release(&pat_buf); + strbuf_release(&str_buf); + + return match_status; + } + static size_t common_prefix_len(const char **pathspec) { const char *n, *first; @@@ -680,26 -624,30 +715,35 @@@ int match_pathname(const char *pathname if (strncmp_icase(pattern, name, prefix)) return 0; pattern += prefix; + patternlen -= prefix; name += prefix; namelen -= prefix; + + /* + * If the whole pattern did not have a wildcard, + * then our prefix match is all we need; we + * do not need to call fnmatch at all. + */ + if (!patternlen && !namelen) + return 1; } - return wildmatch(pattern, name, - WM_PATHNAME | (ignore_case ? WM_CASEFOLD : 0), - NULL) == 0; + return fnmatch_icase_mem(pattern, patternlen, + name, namelen, - FNM_PATHNAME) == 0; ++ WM_PATHNAME) == 0; } -/* Scan the list and let the last match determine the fate. - * Return 1 for exclude, 0 for include and -1 for undecided. +/* + * Scan the given exclude list in reverse to see whether pathname + * should be ignored. The first match (i.e. the last on the list), if + * any, determines the fate. Returns the exclude_list element which + * matched, or NULL for undecided. */ -int excluded_from_list(const char *pathname, - int pathlen, const char *basename, int *dtype, - struct exclude_list *el) +static struct exclude *last_exclude_matching_from_list(const char *pathname, + int pathlen, + const char *basename, + int *dtype, + struct exclude_list *el) { int i;