diff --git a/lib/ignore/ignore.go b/lib/ignore/ignore.go index f8e81b06..2d44c1c4 100644 --- a/lib/ignore/ignore.go +++ b/lib/ignore/ignore.go @@ -140,9 +140,14 @@ func (m *Matcher) Load(file string) error { defer fd.Close() m.changeDetector.Reset() - m.changeDetector.Remember(m.fs, file, info.ModTime()) - return m.parseLocked(fd, file) + err = m.parseLocked(fd, file) + // If we failed to parse, don't cache, as next time Load is called + // we'll pretend it's all good. + if err == nil { + m.changeDetector.Remember(m.fs, file, info.ModTime()) + } + return err } func (m *Matcher) Parse(r io.Reader, file string) error { @@ -445,6 +450,12 @@ func parseIgnoreFile(fs fs.Filesystem, fd io.Reader, currentFile string, cd Chan var includePatterns []Pattern if includePatterns, err = loadParseIncludeFile(fs, includeFile, cd, linesSeen); err == nil { patterns = append(patterns, includePatterns...) + } else { + // Wrap the error, as if the include does not exist, we get a + // IsNotExists(err) == true error, which we use to check + // existance of the .stignore file, and just end up assuming + // there is none, rather than a broken include. + err = fmt.Errorf("failed to load include file %s: %s", includeFile, err.Error()) } case strings.HasSuffix(line, "/**"): err = addPattern(line) diff --git a/lib/ignore/ignore_test.go b/lib/ignore/ignore_test.go index f15ffd9b..3f7dd352 100644 --- a/lib/ignore/ignore_test.go +++ b/lib/ignore/ignore_test.go @@ -981,3 +981,42 @@ func TestIssue4689(t *testing.T) { t.Fatalf("wrong lines parsing changed comment:\n%v", lines) } } + +func TestIssue4901(t *testing.T) { + dir, err := ioutil.TempDir("", "") + if err != nil { + t.Fatal(err) + } + + defer os.RemoveAll(dir) + + stignore := ` + #include unicorn-lazor-death + puppy + ` + + if err := ioutil.WriteFile(filepath.Join(dir, ".stignore"), []byte(stignore), 0777); err != nil { + t.Fatalf(err.Error()) + } + + pats := New(fs.NewFilesystem(fs.FilesystemTypeBasic, dir), WithCache(true)) + // Cache does not suddenly make the load succeed. + for i := 0; i < 2; i++ { + err := pats.Load(".stignore") + if err == nil { + t.Fatalf("expected an error") + } + if fs.IsNotExist(err) { + t.Fatalf("unexpected error type") + } + } + + if err := ioutil.WriteFile(filepath.Join(dir, "unicorn-lazor-death"), []byte(" "), 0777); err != nil { + t.Fatalf(err.Error()) + } + + err = pats.Load(".stignore") + if err != nil { + t.Fatalf("unexpected error: %s", err.Error()) + } +} diff --git a/lib/model/model.go b/lib/model/model.go index 781ce827..ebc77e44 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -1490,11 +1490,10 @@ func (m *Model) GetIgnores(folder string) ([]string, []string, error) { } ignores, ok := m.folderIgnores[folder] - if ok { - return ignores.Lines(), ignores.Patterns(), nil + if !ok { + ignores = ignore.New(fs.NewFilesystem(cfg.FilesystemType, cfg.Path)) } - ignores = ignore.New(fs.NewFilesystem(cfg.FilesystemType, cfg.Path)) if err := ignores.Load(".stignore"); err != nil && !fs.IsNotExist(err) { return nil, nil, err }