From 4383398f25b0344fa65fe161b8c791f248af1785 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jul 2025 10:02:43 +0530 Subject: [PATCH] Fix ** matching --- tools/ignorefiles/gitignore.go | 3 ++- tools/ignorefiles/gitignore_test.go | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tools/ignorefiles/gitignore.go b/tools/ignorefiles/gitignore.go index 98aa10443..13d8b9910 100644 --- a/tools/ignorefiles/gitignore.go +++ b/tools/ignorefiles/gitignore.go @@ -65,7 +65,7 @@ func anchored_full_match(path string, parts []string) bool { for pos <= last && path != "" { var name string name, path, _ = strings.Cut(path, "/") - switch name { + switch parts[pos] { case "**": for pos+1 < len(parts) && parts[pos+1] == "**" { pos++ @@ -73,6 +73,7 @@ func anchored_full_match(path string, parts []string) bool { if pos == last { return true } + pos++ for { matches, err := filepath.Match(parts[pos], name) if err != nil { diff --git a/tools/ignorefiles/gitignore_test.go b/tools/ignorefiles/gitignore_test.go index 202791852..8276a4c56 100644 --- a/tools/ignorefiles/gitignore_test.go +++ b/tools/ignorefiles/gitignore_test.go @@ -65,6 +65,26 @@ func TestGitignore(t *testing.T) { {"foo.*", []ptest{ {"foo.txt", true}, {"foo", false}, {"a/foo.x", true}, {"foo.", true}, }}, + + {"**", []ptest{ + {"foo", true}, {"x/foo", true}, {"foo/x", true}, + }}, + + {"**/foo", []ptest{ + {"foo", true}, {"x/foo", true}, {"foo/x", false}, + }}, + {"**/foo/bar", []ptest{ + {"foo", false}, {"x/foo", false}, {"foo/bar", true}, {"a/foo/bar", true}, {"foo/bar/a", false}, + }}, + {"foo/**", []ptest{ + {"foo", false}, {"x/foo", false}, {"foo/bar", true}, {"foo/bar/a", true}, {"foo/bar/a/", true}, + }}, + {"a/**/b", []ptest{ + {"a/b", true}, {"a/x/b", true}, {"a/x/y/b", true}, {"x/a/b", false}, {"a/b/x", false}, + }}, + {"a/**/b/**/c", []ptest{ + {"a/b/c", true}, {"a/x/b/c", true}, {"a/x/y/b/m/n/c", true}, + }}, } { p, skipped := CompileGitIgnoreLine(x.line) if skipped {