diff --git a/lib/src/matchers.rs b/lib/src/matchers.rs index bb6b14676..c48733e82 100644 --- a/lib/src/matchers.rs +++ b/lib/src/matchers.rs @@ -143,10 +143,25 @@ impl Matcher for FilesMatcher { fn visit(&self, dir: &RepoPath) -> Visit { self.tree .get(dir) - .map_or(Visit::Nothing, RepoPathTree::to_visit_sets) + .map_or(Visit::Nothing, files_tree_to_visit_sets) } } +fn files_tree_to_visit_sets(tree: &RepoPathTree) -> Visit { + let mut dirs = HashSet::new(); + let mut files = HashSet::new(); + for (name, sub) in &tree.entries { + // should visit only intermediate directories + if !sub.entries.is_empty() { + dirs.insert(name.clone()); + } + if sub.is_file { + files.insert(name.clone()); + } + } + Visit::sets(dirs, files) +} + #[derive(Debug)] pub struct PrefixMatcher { tree: RepoPathTree, @@ -178,13 +193,26 @@ impl Matcher for PrefixMatcher { } // 'dir' found, and is an ancestor of prefix paths if tail_path.is_root() { - return sub.to_visit_sets(); + return prefix_tree_to_visit_sets(sub); } } Visit::Nothing } } +fn prefix_tree_to_visit_sets(tree: &RepoPathTree) -> Visit { + let mut dirs = HashSet::new(); + let mut files = HashSet::new(); + for (name, sub) in &tree.entries { + // should visit both intermediate and prefix directories + dirs.insert(name.clone()); + if sub.is_file { + files.insert(name.clone()); + } + } + Visit::sets(dirs, files) +} + /// Matches paths that are matched by any of the input matchers. #[derive(Clone, Debug)] pub struct UnionMatcher { @@ -380,20 +408,6 @@ impl RepoPathTree { Some((sub.entries.get(name)?, components.as_path())) }) } - - fn to_visit_sets(&self) -> Visit { - let mut dirs = HashSet::new(); - let mut files = HashSet::new(); - for (name, sub) in &self.entries { - if sub.is_dir { - dirs.insert(name.clone()); - } - if sub.is_file { - files.insert(name.clone()); - } - } - Visit::sets(dirs, files) - } } impl Debug for RepoPathTree {