summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Borg <jakob@nym.se>2015-09-02 20:54:18 +0200
committerJakob Borg <jakob@nym.se>2015-09-03 08:22:53 +0200
commit66df2e57ae5ff205226cd3214e25e942c3ef4989 (patch)
tree9ffdbb8a69c6f01d60346d67f7474008a3dbf009
parent4a6e9c189cfb08565b6a19f9ad961b73d1b87c62 (diff)
Correctly handle (?i) in ignores (fixes #1953)
-rw-r--r--lib/fnmatch/fnmatch.go8
-rw-r--r--lib/fnmatch/fnmatch_test.go4
-rw-r--r--lib/ignore/ignore.go16
-rw-r--r--test/ignore_test.go16
4 files changed, 19 insertions, 25 deletions
diff --git a/lib/fnmatch/fnmatch.go b/lib/fnmatch/fnmatch.go
index 398930455..cc5fa1e91 100644
--- a/lib/fnmatch/fnmatch.go
+++ b/lib/fnmatch/fnmatch.go
@@ -38,14 +38,6 @@ func Convert(pattern string, flags int) (*regexp.Regexp, error) {
}
}
- // Support case insensitive ignores. We do the loop because we may in some
- // circumstances end up with multiple insensitivity prefixes
- // ("(?i)(?i)foo"), which should be accepted.
- for ignore := strings.TrimPrefix(pattern, "(?i)"); ignore != pattern; ignore = strings.TrimPrefix(pattern, "(?i)") {
- flags |= CaseFold
- pattern = ignore
- }
-
if flags&NoEscape != 0 {
pattern = strings.Replace(pattern, "\\", "\\\\", -1)
} else {
diff --git a/lib/fnmatch/fnmatch_test.go b/lib/fnmatch/fnmatch_test.go
index 10f989090..17679e538 100644
--- a/lib/fnmatch/fnmatch_test.go
+++ b/lib/fnmatch/fnmatch_test.go
@@ -53,10 +53,6 @@ var testcases = []testcase{
{"**/foo.txt", "bar/baz/foo.txt", PathName, true},
{"foo.txt", "foo.TXT", CaseFold, true},
- {"(?i)foo.txt", "foo.TXT", 0, true},
- {"(?i)(?i)foo.txt", "foo.TXT", 0, true}, // repeated prefix should be fine
- {"(?i)**foo.txt", "/dev/tmp/foo.TXT", 0, true},
- {"(?i)!**foo.txt", "/dev/tmp/foo.TXT", 0, false},
// These characters are literals in glob, but not in regexp.
{"hey$hello", "hey$hello", 0, true},
diff --git a/lib/ignore/ignore.go b/lib/ignore/ignore.go
index fc50f9a83..8c8cabf2c 100644
--- a/lib/ignore/ignore.go
+++ b/lib/ignore/ignore.go
@@ -206,22 +206,28 @@ func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) ([]
include = false
}
+ flags := fnmatch.PathName
+ if strings.HasPrefix(line, "(?i)") {
+ line = line[4:]
+ flags |= fnmatch.CaseFold
+ }
+
if strings.HasPrefix(line, "/") {
// Pattern is rooted in the current dir only
- exp, err := fnmatch.Convert(line[1:], fnmatch.PathName)
+ exp, err := fnmatch.Convert(line[1:], flags)
if err != nil {
return fmt.Errorf("Invalid pattern %q in ignore file", line)
}
patterns = append(patterns, Pattern{exp, include})
} else if strings.HasPrefix(line, "**/") {
// Add the pattern as is, and without **/ so it matches in current dir
- exp, err := fnmatch.Convert(line, fnmatch.PathName)
+ exp, err := fnmatch.Convert(line, flags)
if err != nil {
return fmt.Errorf("Invalid pattern %q in ignore file", line)
}
patterns = append(patterns, Pattern{exp, include})
- exp, err = fnmatch.Convert(line[3:], fnmatch.PathName)
+ exp, err = fnmatch.Convert(line[3:], flags)
if err != nil {
return fmt.Errorf("Invalid pattern %q in ignore file", line)
}
@@ -236,13 +242,13 @@ func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) ([]
} else {
// Path name or pattern, add it so it matches files both in
// current directory and subdirs.
- exp, err := fnmatch.Convert(line, fnmatch.PathName)
+ exp, err := fnmatch.Convert(line, flags)
if err != nil {
return fmt.Errorf("Invalid pattern %q in ignore file", line)
}
patterns = append(patterns, Pattern{exp, include})
- exp, err = fnmatch.Convert("**/"+line, fnmatch.PathName)
+ exp, err = fnmatch.Convert("**/"+line, flags)
if err != nil {
return fmt.Errorf("Invalid pattern %q in ignore file", line)
}
diff --git a/test/ignore_test.go b/test/ignore_test.go
index 32e9be804..8fc8edfdb 100644
--- a/test/ignore_test.go
+++ b/test/ignore_test.go
@@ -31,23 +31,23 @@ func TestIgnores(t *testing.T) {
// Create eight empty files and directories
- files := []string{"f1", "f2", "f3", "f4", "f11", "f12", "f13", "f14"}
dirs := []string{"d1", "d2", "d3", "d4", "d11", "d12", "d13", "d14"}
+ files := []string{"f1", "f2", "f3", "f4", "f11", "f12", "f13", "f14", "d1/f1.TXT"}
all := append(files, dirs...)
- for _, file := range files {
- fd, err := os.Create(filepath.Join("s1", file))
+ for _, dir := range dirs {
+ err := os.Mkdir(filepath.Join("s1", dir), 0755)
if err != nil {
t.Fatal(err)
}
- fd.Close()
}
- for _, dir := range dirs {
- err := os.Mkdir(filepath.Join("s1", dir), 0755)
+ for _, file := range files {
+ fd, err := os.Create(filepath.Join("s1", file))
if err != nil {
t.Fatal(err)
}
+ fd.Close()
}
var syms []string
@@ -81,7 +81,7 @@ func TestIgnores(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- _, err = fd.WriteString("f1*\nf2\nd1*\nd2\ns1*\ns2") // [fds][34] only non-ignored items
+ _, err = fd.WriteString("f1*\nf2\nd1*\nd2\ns1*\ns2\n(?i)*.txt") // [fds][34] only non-ignored items
if err != nil {
t.Fatal(err)
}
@@ -130,7 +130,7 @@ func TestIgnores(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- expected = len(all) * 7 / 8 // seven out of eight items of each type should remain
+ expected = len(all)*7/8 + 1 // seven out of eight items of each type should remain, plus the foo.TXT
if m.LocalFiles != expected {
t.Fatalf("Incorrect number of files after second ignore, %d != %d", m.LocalFiles, expected)
}