aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-11-03 06:49:54 -0800
committerJunio C Hamano <gitster@pobox.com>2025-11-03 06:49:55 -0800
commit52364670907b84f91bcd42035ddd30ceac0f2771 (patch)
tree751b986b35c369f8f65dc0147e679b5f201a1d0a
parentecf2f52fe587a2a61da72c71fe9b38a0f9591029 (diff)
parent1940a02dc1122d15706a7051ee47e73f329fb4f7 (diff)
downloadgit-52364670907b84f91bcd42035ddd30ceac0f2771.tar.gz
Merge branch 'jk/match-pathname-fix'
The wildmatch code had a corner case bug that mistakenly makes "foo**/bar" match with "foobar", which has been corrected. * jk/match-pathname-fix: match_pathname(): give fnmatch one char of prefix context match_pathname(): reorder prefix-match check
-rw-r--r--dir.c17
-rwxr-xr-xt/t0008-ignores.sh11
2 files changed, 23 insertions, 5 deletions
diff --git a/dir.c b/dir.c
index f683f8ba49..b00821f294 100644
--- a/dir.c
+++ b/dir.c
@@ -1388,18 +1388,25 @@ int match_pathname(const char *pathname, int pathlen,
if (fspathncmp(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)
+ if (patternlen == prefix && namelen == prefix)
return 1;
+
+ /*
+ * Retain one character of the prefix to
+ * pass to fnmatch, which lets it distinguish
+ * the start of a directory component correctly.
+ */
+ prefix--;
+ pattern += prefix;
+ patternlen -= prefix;
+ name += prefix;
+ namelen -= prefix;
}
return fnmatch_icase_mem(pattern, patternlen,
diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh
index 273d71411f..db8bde280e 100755
--- a/t/t0008-ignores.sh
+++ b/t/t0008-ignores.sh
@@ -847,6 +847,17 @@ test_expect_success 'directories and ** matches' '
test_cmp expect actual
'
+test_expect_success '** not confused by matching leading prefix' '
+ cat >.gitignore <<-\EOF &&
+ foo**/bar
+ EOF
+ git check-ignore foobar foo/bar >actual &&
+ cat >expect <<-\EOF &&
+ foo/bar
+ EOF
+ test_cmp expect actual
+'
+
############################################################################
#
# test whitespace handling