From af05e290cf2035e6edd68dbd9f079758d1818305 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Mon, 14 Oct 2019 16:06:13 +0100 Subject: [PATCH] Fix --files-from without --no-traverse doing a recursive scan In a28239f005aeb290 we made --files-from obey --no-traverse. In the process this caused --files-from without --no-traverse to do a complete recursive scan unecessarily. This was only noticeable in users of fs/march, so sync/copy/move/etc not in ls/lsf/etc. This fix makes sure that we use conventional directory listings in fs/march unless `--files-from` and `--no-traverse` is set or `--fast-list` is active. Fixes #3619 --- fs/march/march.go | 9 +++++++-- fs/walk/walk.go | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/fs/march/march.go b/fs/march/march.go index 25642abca..4969a7e21 100644 --- a/fs/march/march.go +++ b/fs/march/march.go @@ -69,13 +69,18 @@ func (m *March) init() { // list a directory into entries, err type listDirFn func(dir string) (entries fs.DirEntries, err error) -// makeListDir makes a listing function for the given fs and includeAll flags +// makeListDir makes constructs a listing function for the given fs +// and includeAll flags for marching through the file system. func (m *March) makeListDir(f fs.Fs, includeAll bool) listDirFn { - if (!fs.Config.UseListR || f.Features().ListR == nil) && !filter.Active.HaveFilesFrom() { + if !(fs.Config.UseListR && f.Features().ListR != nil) && // !--fast-list active and + !(fs.Config.NoTraverse && filter.Active.HaveFilesFrom()) { // !(--files-from and --no-traverse) return func(dir string) (entries fs.DirEntries, err error) { return list.DirSorted(m.Ctx, f, includeAll, dir) } } + + // This returns a closure for use when --fast-list is active or for when + // --files-from and --no-traverse is set var ( mu sync.Mutex started bool diff --git a/fs/walk/walk.go b/fs/walk/walk.go index a424e3a33..273c22456 100644 --- a/fs/walk/walk.go +++ b/fs/walk/walk.go @@ -553,12 +553,15 @@ func walkNDirTree(ctx context.Context, f fs.Fs, path string, includeAll bool, ma // // NB (f, path) to be replaced by fs.Dir at some point func NewDirTree(ctx context.Context, f fs.Fs, path string, includeAll bool, maxLevel int) (dirtree.DirTree, error) { + // if --no-traverse and --files-from build DirTree just from files if fs.Config.NoTraverse && filter.Active.HaveFilesFrom() { return walkRDirTree(ctx, f, path, includeAll, maxLevel, filter.Active.MakeListR(ctx, f.NewObject)) } - if ListR := f.Features().ListR; (maxLevel < 0 || maxLevel > 1) && ListR != nil { + // if have ListR; and recursing; and not using --files-from; then build a DirTree with ListR + if ListR := f.Features().ListR; (maxLevel < 0 || maxLevel > 1) && ListR != nil && !filter.Active.HaveFilesFrom() { return walkRDirTree(ctx, f, path, includeAll, maxLevel, ListR) } + // otherwise just use List return walkNDirTree(ctx, f, path, includeAll, maxLevel, list.DirSorted) }