aboutsummaryrefslogtreecommitdiff
path: root/lib/ignore/ignore.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ignore/ignore.go')
-rw-r--r--lib/ignore/ignore.go81
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 {