filepathfilter: teach path patterns to match subdirectories

This commit is contained in:
risk danger olson 2017-05-18 06:51:12 -06:00
parent 9be82140cc
commit ed2d59f071
3 changed files with 35 additions and 6 deletions

@ -10,7 +10,7 @@ import (
"github.com/git-lfs/git-lfs/tools"
)
func BenchmarkFilterNoWildcard(b *testing.B) {
func BenchmarkFilterSimplePath(b *testing.B) {
files := benchmarkTree(b)
filter := filepathfilter.New([]string{"lfs"}, nil)
for i := 0; i < b.N; i++ {
@ -20,7 +20,7 @@ func BenchmarkFilterNoWildcard(b *testing.B) {
}
}
func BenchmarkFilterIncludeWildcardOnly(b *testing.B) {
func BenchmarkFilterSimpleExtension(b *testing.B) {
files := benchmarkTree(b)
filter := filepathfilter.New([]string{"*.go"}, nil)
for i := 0; i < b.N; i++ {
@ -30,7 +30,17 @@ func BenchmarkFilterIncludeWildcardOnly(b *testing.B) {
}
}
func BenchmarkFilterIncludeDoubleAsterisk(b *testing.B) {
func BenchmarkFilterComplexExtension(b *testing.B) {
files := benchmarkTree(b)
filter := filepathfilter.New([]string{"*.travis.yml"}, nil)
for i := 0; i < b.N; i++ {
for _, f := range files {
filter.Allows(f)
}
}
}
func BenchmarkFilterDoubleAsterisk(b *testing.B) {
files := benchmarkTree(b)
filter := filepathfilter.New([]string{"**/README.md"}, nil)
for i := 0; i < b.N; i++ {

@ -91,7 +91,13 @@ func NewPattern(rawpattern string) Pattern {
wildcardRE: regexp.MustCompile(regpattern),
}
} else {
return &basicPattern{rawPattern: cleanpattern}
s := string(filepath.Separator)
return &basicPattern{
rawPattern: cleanpattern,
prefix: cleanpattern + s,
suffix: s + cleanpattern,
inner: s + cleanpattern + s,
}
}
}
@ -105,14 +111,19 @@ func convertToPatterns(rawpatterns []string) []Pattern {
type basicPattern struct {
rawPattern string
prefix string
suffix string
inner string
}
// Match is a revised version of filepath.Match which makes it behave more
// like gitignore
func (p *basicPattern) Match(name string) bool {
matched, _ := filepath.Match(p.rawPattern, name)
// Also support matching a parent directory without a wildcard
return matched || strings.HasPrefix(name, p.rawPattern+string(filepath.Separator))
return matched ||
strings.HasPrefix(name, p.prefix) ||
strings.HasSuffix(name, p.suffix) ||
strings.Contains(name, p.inner)
}
type pathlessWildcardPattern struct {

@ -32,8 +32,16 @@ func TestPatternMatch(t *testing.T) {
assert.False(t, patternMatch("*.ign", "sub/shouldignoreme.txt"))
// Path specific
assert.True(t, patternMatch("sub", "sub/"))
assert.True(t, patternMatch("sub", "sub"))
assert.True(t, patternMatch("sub", "sub/filename.txt"))
assert.True(t, patternMatch("sub/", "sub/filename.txt"))
assert.True(t, patternMatch("sub", "top/sub/filename.txt"))
assert.True(t, patternMatch("sub/", "top/sub/filename.txt"))
assert.True(t, patternMatch("sub", "top/sub/"))
assert.True(t, patternMatch("sub", "top/sub"))
assert.False(t, patternMatch("sub", "subfilename.txt"))
assert.False(t, patternMatch("sub/", "subfilename.txt"))
// Absolute
assert.True(t, patternMatch("*.dat", "/path/to/sub/.git/test.dat"))