# HG changeset patch # User Simon Sapin # Date 1619457383 -7200 # Node ID aeb03758f37aa460fd238492925a29add5ef8313 # Parent be579775c2d91f39ea111a3641406f622d85e4fa dirstate-tree: Ignore FIFOs etc. in the status algorithm If a filesystem directory contains anything that is not: * a "normal" file * a symbolic link * or a directory … act as if that directory entry was not there. For example, if that path was previously a tracked file, mark it as deleted or removed. Differential Revision: https://phab.mercurial-scm.org/D10548 diff -r be579775c2d9 -r aeb03758f37a rust/hg-core/src/dirstate_tree/status.rs --- a/rust/hg-core/src/dirstate_tree/status.rs Fri Apr 16 12:12:41 2021 +0200 +++ b/rust/hg-core/src/dirstate_tree/status.rs Mon Apr 26 19:16:23 2021 +0200 @@ -126,17 +126,21 @@ dirstate_node: &'tree mut Node, has_ignored_ancestor: bool, ) { - if fs_entry.metadata.is_dir() { - if self.options.collect_traversed_dirs { - self.outcome.traversed.push(hg_path.into()) - } + let file_type = fs_entry.metadata.file_type(); + let file_or_symlink = file_type.is_file() || file_type.is_symlink(); + if !file_or_symlink { // If we previously had a file here, it was removed (with // `hg rm` or similar) or deleted before it could be - // replaced by a directory. + // replaced by a directory or something else. self.mark_removed_or_deleted_if_file( hg_path, dirstate_node.state(), ); + } + if file_type.is_dir() { + if self.options.collect_traversed_dirs { + self.outcome.traversed.push(hg_path.into()) + } let is_ignored = has_ignored_ancestor || (self.ignore_fn)(hg_path); let is_at_repo_root = false; self.traverse_fs_directory_and_dirstate( @@ -147,7 +151,7 @@ is_at_repo_root, ); } else { - if self.matcher.matches(hg_path) { + if file_or_symlink && self.matcher.matches(hg_path) { let full_path = Cow::from(hg_path); if let Some(entry) = &dirstate_node.entry { match entry.state { @@ -276,7 +280,9 @@ fs_entry: &DirEntry, ) { let hg_path = directory_hg_path.join(&fs_entry.base_name); - if fs_entry.metadata.is_dir() { + let file_type = fs_entry.metadata.file_type(); + let file_or_symlink = file_type.is_file() || file_type.is_symlink(); + if file_type.is_dir() { let is_ignored = has_ignored_ancestor || (self.ignore_fn)(&hg_path); let traverse_children = if is_ignored { @@ -304,7 +310,7 @@ if self.options.collect_traversed_dirs { self.outcome.traversed.push(hg_path.into()) } - } else if self.matcher.matches(&hg_path) { + } else if file_or_symlink && self.matcher.matches(&hg_path) { self.mark_unknown_or_ignored(has_ignored_ancestor, hg_path.into()) } }