Mercurial > hg
changeset 47114:aeb03758f37a
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
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 26 Apr 2021 19:16:23 +0200 |
parents | be579775c2d9 |
children | 1b4f0f819f92 |
files | rust/hg-core/src/dirstate_tree/status.rs |
diffstat | 1 files changed, 14 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- 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()) } }