diff options
Diffstat (limited to 'lib/ignore/ignore.go')
-rw-r--r-- | lib/ignore/ignore.go | 81 |
1 files changed, 37 insertions, 44 deletions
diff --git a/lib/ignore/ignore.go b/lib/ignore/ignore.go index db1392f1b..4c7839a59 100644 --- a/lib/ignore/ignore.go +++ b/lib/ignore/ignore.go @@ -79,11 +79,17 @@ func (p Pattern) allowsSkippingIgnoredDirs() bool { if p.pattern[0] != '/' { return false } - if strings.Contains(p.pattern[1:], "/") { + // A "/**" at the end is allowed and doesn't have any bearing on the + // below checks; remove it before checking. + pattern := strings.TrimSuffix(p.pattern, "/**") + if len(pattern) == 0 { + return true + } + if strings.Contains(pattern[1:], "/") { return false } // Double asterisk everywhere in the path except at the end is bad - return !strings.Contains(strings.TrimSuffix(p.pattern, "**"), "**") + return !strings.Contains(strings.TrimSuffix(pattern, "**"), "**") } // The ChangeDetector is responsible for determining if files have changed @@ -99,16 +105,15 @@ type ChangeDetector interface { } type Matcher struct { - fs fs.Filesystem - lines []string // exact lines read from .stignore - patterns []Pattern // patterns including those from included files - withCache bool - matches *cache - curHash string - stop chan struct{} - changeDetector ChangeDetector - skipIgnoredDirs bool - mut sync.Mutex + fs fs.Filesystem + lines []string // exact lines read from .stignore + patterns []Pattern // patterns including those from included files + withCache bool + matches *cache + curHash string + stop chan struct{} + changeDetector ChangeDetector + mut sync.Mutex } // An Option can be passed to New() @@ -131,10 +136,9 @@ func WithChangeDetector(cd ChangeDetector) Option { func New(fs fs.Filesystem, opts ...Option) *Matcher { m := &Matcher{ - fs: fs, - stop: make(chan struct{}), - mut: sync.NewMutex(), - skipIgnoredDirs: true, + fs: fs, + stop: make(chan struct{}), + mut: sync.NewMutex(), } for _, opt := range opts { opt(m) @@ -198,23 +202,6 @@ func (m *Matcher) parseLocked(r io.Reader, file string) error { return err } - m.skipIgnoredDirs = true - var previous string - for _, p := range patterns { - // We automatically add patterns with a /** suffix, which normally - // means that we cannot skip directories. However if the same - // pattern without the /** already exists (which is true for - // automatically added patterns) we can skip. - if l := len(p.pattern); l > 3 && p.pattern[:len(p.pattern)-3] == previous { - continue - } - if !p.allowsSkippingIgnoredDirs() { - m.skipIgnoredDirs = false - break - } - previous = p.pattern - } - m.curHash = newHash m.patterns = patterns if m.withCache { @@ -228,10 +215,10 @@ func (m *Matcher) parseLocked(r io.Reader, file string) error { func (m *Matcher) Match(file string) (result ignoreresult.R) { switch { case fs.IsTemporary(file): - return ignoreresult.Ignored + return ignoreresult.IgnoreAndSkip case fs.IsInternal(file): - return ignoreresult.Ignored + return ignoreresult.IgnoreAndSkip case file == ".": return ignoreresult.NotIgnored @@ -257,19 +244,31 @@ func (m *Matcher) Match(file string) (result ignoreresult.R) { }() } - // Check all the patterns for a match. + // Check all the patterns for a match. Track whether the patterns so far + // allow skipping matched directories or not. As soon as we hit an + // exclude pattern (with some exceptions), we can't skip directories + // anymore. file = filepath.ToSlash(file) var lowercaseFile string + canSkipDir := true for _, pattern := range m.patterns { + if canSkipDir && !pattern.allowsSkippingIgnoredDirs() { + canSkipDir = false + } + + res := pattern.result + if canSkipDir { + res = res.WithSkipDir() + } if pattern.result.IsCaseFolded() { if lowercaseFile == "" { lowercaseFile = strings.ToLower(file) } if pattern.match.Match(lowercaseFile) { - return pattern.result + return res } } else if pattern.match.Match(file) { - return pattern.result + return res } } @@ -327,12 +326,6 @@ func (m *Matcher) clean(d time.Duration) { } } -func (m *Matcher) SkipIgnoredDirs() bool { - m.mut.Lock() - defer m.mut.Unlock() - return m.skipIgnoredDirs -} - func hashPatterns(patterns []Pattern) string { h := sha256.New() for _, pat := range patterns { |