diff --git a/main.go b/main.go index 34411a04b..b88cd2566 100644 --- a/main.go +++ b/main.go @@ -363,7 +363,7 @@ func connect(myID string, addr string, nodeAddrs map[string][]string, m *model.M } func updateLocalModel(m *model.Model) { - files := m.FilteredWalk(!opts.NoSymlinks) + files, _ := m.Walk(!opts.NoSymlinks) m.ReplaceLocal(files) saveIndex(m) } diff --git a/model/model_test.go b/model/model_test.go index 472b92317..3323baf19 100644 --- a/model/model_test.go +++ b/model/model_test.go @@ -40,12 +40,6 @@ var testDataExpected = map[string]File{ 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}}}, }, - "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() { diff --git a/model/walk.go b/model/walk.go index 52b7d10b9..7e60675ca 100644 --- a/model/walk.go +++ b/model/walk.go @@ -49,16 +49,12 @@ func tempName(name string, modified int64) string { 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 { if err != nil { return nil } - if isTempName(p) { - return nil - } - rn, err := filepath.Rel(m.dir, p) if err != nil { return nil @@ -75,6 +71,31 @@ func (m *Model) genWalker(res *[]File, ign map[string][]string) filepath.WalkFun } } 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 } @@ -149,8 +170,11 @@ func (m *Model) genWalker(res *[]File, ign map[string][]string) filepath.WalkFun // file system. Files are blockwise hashed. func (m *Model) Walk(followSymlinks bool) (files []File, ignore 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 { 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 { 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 } -// 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 { if err != nil { return err @@ -200,19 +218,24 @@ func (m *Model) cleanTempFiles() { } func ignoreFilter(patterns map[string][]string, files []File) (filtered []File) { -nextFile: for _, f := range files { - first, last := path.Split(f.Name) - 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 { - continue nextFile - } - } - } + if !ignoreFile(patterns, f.Name) { + filtered = append(filtered, f) } - filtered = append(filtered, f) } 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 +} diff --git a/model/walk_test.go b/model/walk_test.go index 36929be43..3e706eda8 100644 --- a/model/walk_test.go +++ b/model/walk_test.go @@ -13,7 +13,6 @@ var testdata = []struct { hash string }{ {"bar", 10, "2f72cc11a6fcd0271ecef8c61056ee1eb1243be3805bf9a9df98f92f7636b05c"}, - {"baz/quux", 9, "c154d94e94ba7298a6adb0523afe34d1b6a581d6b893a763d45ddc5e209dcb83"}, {"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) { var patterns = map[string][]string{ "": {"t2"},