diff --git a/lib/ignore/ignore.go b/lib/ignore/ignore.go index 59c9be9a4..181a804a9 100644 --- a/lib/ignore/ignore.go +++ b/lib/ignore/ignore.go @@ -173,7 +173,7 @@ func (m *Matcher) parseLocked(r io.Reader, file string) error { m.skipIgnoredDirs = true for _, p := range patterns { - if p.result&resultInclude == resultInclude { + if !p.result.IsIgnored() { m.skipIgnoredDirs = false break } diff --git a/lib/ignore/ignore_test.go b/lib/ignore/ignore_test.go index 3f7dd3522..8101cf8ba 100644 --- a/lib/ignore/ignore_test.go +++ b/lib/ignore/ignore_test.go @@ -1020,3 +1020,36 @@ func TestIssue4901(t *testing.T) { t.Fatalf("unexpected error: %s", err.Error()) } } + +// TestIssue5009 checks that ignored dirs are only skipped if there are no include patterns. +// https://github.com/syncthing/syncthing/issues/5009 (rc-only bug) +func TestIssue5009(t *testing.T) { + pats := New(fs.NewFilesystem(fs.FilesystemTypeBasic, "."), WithCache(true)) + + stignore := ` + ign1 + i*2 + ` + if err := pats.Parse(bytes.NewBufferString(stignore), ".stignore"); err != nil { + t.Fatal(err) + } + if !pats.skipIgnoredDirs { + t.Error("skipIgnoredDirs should be true without includes") + } + + stignore = ` + !iex2 + !ign1/ex + ign1 + i*2 + !ign2 + ` + + if err := pats.Parse(bytes.NewBufferString(stignore), ".stignore"); err != nil { + t.Fatal(err) + } + + if pats.skipIgnoredDirs { + t.Error("skipIgnoredDirs should not be true with includes") + } +} diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index b31d33b6a..0104cd529 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -246,8 +246,8 @@ func (w *walker) walkAndHashFiles(ctx context.Context, fchan, dchan chan protoco if w.Matcher.Match(path).IsIgnored() { l.Debugln("ignored (patterns):", path) // Only descend if matcher says so and the current file is not a symlink. - if w.Matcher.SkipIgnoredDirs() || (info.IsSymlink() && info.IsDir()) { - return fs.SkipDir + if w.Matcher.SkipIgnoredDirs() || info.IsSymlink() { + return skip } // If the parent wasn't ignored already, set this path as the "highest" ignored parent if info.IsDir() && (ignoredParent == "" || !strings.HasPrefix(path, ignoredParent+string(fs.PathSeparator))) {