Prepopulate ignore patterns (fixes #21)

This commit is contained in:
Jakob Borg 2014-01-09 22:46:01 +01:00
parent a18f6c6d90
commit b9af45bc6b
4 changed files with 51 additions and 50 deletions

View File

@ -363,7 +363,7 @@ func connect(myID string, addr string, nodeAddrs map[string][]string, m *model.M
} }
func updateLocalModel(m *model.Model) { func updateLocalModel(m *model.Model) {
files := m.FilteredWalk(!opts.NoSymlinks) files, _ := m.Walk(!opts.NoSymlinks)
m.ReplaceLocal(files) m.ReplaceLocal(files)
saveIndex(m) saveIndex(m)
} }

View File

@ -40,12 +40,6 @@ var testDataExpected = map[string]File{
Modified: 0, Modified: 0,
Blocks: []Block{{Offset: 0x0, Length: 0xa, Hash: []uint8{0x2f, 0x72, 0xcc, 0x11, 0xa6, 0xfc, 0xd0, 0x27, 0x1e, 0xce, 0xf8, 0xc6, 0x10, 0x56, 0xee, 0x1e, 0xb1, 0x24, 0x3b, 0xe3, 0x80, 0x5b, 0xf9, 0xa9, 0xdf, 0x98, 0xf9, 0x2f, 0x76, 0x36, 0xb0, 0x5c}}}, Blocks: []Block{{Offset: 0x0, Length: 0xa, Hash: []uint8{0x2f, 0x72, 0xcc, 0x11, 0xa6, 0xfc, 0xd0, 0x27, 0x1e, 0xce, 0xf8, 0xc6, 0x10, 0x56, 0xee, 0x1e, 0xb1, 0x24, 0x3b, 0xe3, 0x80, 0x5b, 0xf9, 0xa9, 0xdf, 0x98, 0xf9, 0x2f, 0x76, 0x36, 0xb0, 0x5c}}},
}, },
"baz/quux": File{
Name: "baz/quux",
Flags: 0,
Modified: 0,
Blocks: []Block{{Offset: 0x0, Length: 0x9, Hash: []uint8{0xc1, 0x54, 0xd9, 0x4e, 0x94, 0xba, 0x72, 0x98, 0xa6, 0xad, 0xb0, 0x52, 0x3a, 0xfe, 0x34, 0xd1, 0xb6, 0xa5, 0x81, 0xd6, 0xb8, 0x93, 0xa7, 0x63, 0xd4, 0x5d, 0xdc, 0x5e, 0x20, 0x9d, 0xcb, 0x83}}},
},
} }
func init() { func init() {

View File

@ -49,16 +49,12 @@ func tempName(name string, modified int64) string {
return path.Join(tdir, tname) return path.Join(tdir, tname)
} }
func (m *Model) genWalker(res *[]File, ign map[string][]string) filepath.WalkFunc { func (m *Model) loadIgnoreFiles(ign map[string][]string) filepath.WalkFunc {
return func(p string, info os.FileInfo, err error) error { return func(p string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
return nil return nil
} }
if isTempName(p) {
return nil
}
rn, err := filepath.Rel(m.dir, p) rn, err := filepath.Rel(m.dir, p)
if err != nil { if err != nil {
return nil return nil
@ -75,6 +71,31 @@ func (m *Model) genWalker(res *[]File, ign map[string][]string) filepath.WalkFun
} }
} }
ign[pn] = patterns ign[pn] = patterns
}
return nil
}
}
func (m *Model) walkAndHashFiles(res *[]File, ign map[string][]string) filepath.WalkFunc {
return func(p string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if isTempName(p) {
return nil
}
rn, err := filepath.Rel(m.dir, p)
if err != nil {
return nil
}
if ignoreFile(ign, rn) {
if m.trace["file"] {
log.Println("FILE: IGNORE:", rn)
}
return nil return nil
} }
@ -149,8 +170,11 @@ func (m *Model) genWalker(res *[]File, ign map[string][]string) filepath.WalkFun
// file system. Files are blockwise hashed. // file system. Files are blockwise hashed.
func (m *Model) Walk(followSymlinks bool) (files []File, ignore map[string][]string) { func (m *Model) Walk(followSymlinks bool) (files []File, ignore map[string][]string) {
ignore = make(map[string][]string) ignore = make(map[string][]string)
fn := m.genWalker(&files, ignore)
filepath.Walk(m.dir, fn) hashFiles := m.walkAndHashFiles(&files, ignore)
filepath.Walk(m.dir, m.loadIgnoreFiles(ignore))
filepath.Walk(m.dir, hashFiles)
if followSymlinks { if followSymlinks {
d, err := os.Open(m.dir) d, err := os.Open(m.dir)
@ -166,7 +190,9 @@ func (m *Model) Walk(followSymlinks bool) (files []File, ignore map[string][]str
for _, fi := range fis { for _, fi := range fis {
if fi.Mode()&os.ModeSymlink != 0 { if fi.Mode()&os.ModeSymlink != 0 {
filepath.Walk(path.Join(m.dir, fi.Name())+"/", fn) dir := path.Join(m.dir, fi.Name()) + "/"
filepath.Walk(dir, m.loadIgnoreFiles(ignore))
filepath.Walk(dir, hashFiles)
} }
} }
} }
@ -174,14 +200,6 @@ func (m *Model) Walk(followSymlinks bool) (files []File, ignore map[string][]str
return return
} }
// Walk returns the list of files found in the local repository by scanning the
// file system. Files are blockwise hashed. Patterns marked in .stignore files
// are removed from the results.
func (m *Model) FilteredWalk(followSymlinks bool) []File {
var files, ignored = m.Walk(followSymlinks)
return ignoreFilter(ignored, files)
}
func (m *Model) cleanTempFile(path string, info os.FileInfo, err error) error { func (m *Model) cleanTempFile(path string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
@ -200,19 +218,24 @@ func (m *Model) cleanTempFiles() {
} }
func ignoreFilter(patterns map[string][]string, files []File) (filtered []File) { func ignoreFilter(patterns map[string][]string, files []File) (filtered []File) {
nextFile:
for _, f := range files { for _, f := range files {
first, last := path.Split(f.Name) if !ignoreFile(patterns, f.Name) {
for prefix, pats := range patterns { filtered = append(filtered, f)
if len(prefix) == 0 || prefix == first || strings.HasPrefix(first, prefix+"/") {
for _, pattern := range pats {
if match, _ := path.Match(pattern, last); match {
continue nextFile
}
}
}
} }
filtered = append(filtered, f)
} }
return filtered return filtered
} }
func ignoreFile(patterns map[string][]string, file string) bool {
first, last := path.Split(file)
for prefix, pats := range patterns {
if len(prefix) == 0 || prefix == first || strings.HasPrefix(first, prefix+"/") {
for _, pattern := range pats {
if match, _ := path.Match(pattern, last); match {
return true
}
}
}
}
return false
}

View File

@ -13,7 +13,6 @@ var testdata = []struct {
hash string hash string
}{ }{
{"bar", 10, "2f72cc11a6fcd0271ecef8c61056ee1eb1243be3805bf9a9df98f92f7636b05c"}, {"bar", 10, "2f72cc11a6fcd0271ecef8c61056ee1eb1243be3805bf9a9df98f92f7636b05c"},
{"baz/quux", 9, "c154d94e94ba7298a6adb0523afe34d1b6a581d6b893a763d45ddc5e209dcb83"},
{"foo", 7, "aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f"}, {"foo", 7, "aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f"},
} }
@ -50,21 +49,6 @@ func TestWalk(t *testing.T) {
} }
} }
func TestFilteredWalk(t *testing.T) {
m := NewModel("testdata")
files := m.FilteredWalk(false)
if len(files) != 2 {
t.Fatalf("Incorrect number of walked filtered files %d != 2", len(files))
}
if files[0].Name != "bar" {
t.Error("Incorrect first file", files[0])
}
if files[1].Name != "foo" {
t.Error("Incorrect second file", files[1])
}
}
func TestIgnore(t *testing.T) { func TestIgnore(t *testing.T) {
var patterns = map[string][]string{ var patterns = map[string][]string{
"": {"t2"}, "": {"t2"},