comparison rust/hg-core/src/dirstate_tree/status.rs @ 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
comparison
equal deleted inserted replaced
47113:be579775c2d9 47114:aeb03758f37a
124 fs_entry: &DirEntry, 124 fs_entry: &DirEntry,
125 hg_path: &'tree HgPath, 125 hg_path: &'tree HgPath,
126 dirstate_node: &'tree mut Node, 126 dirstate_node: &'tree mut Node,
127 has_ignored_ancestor: bool, 127 has_ignored_ancestor: bool,
128 ) { 128 ) {
129 if fs_entry.metadata.is_dir() { 129 let file_type = fs_entry.metadata.file_type();
130 if self.options.collect_traversed_dirs { 130 let file_or_symlink = file_type.is_file() || file_type.is_symlink();
131 self.outcome.traversed.push(hg_path.into()) 131 if !file_or_symlink {
132 }
133 // If we previously had a file here, it was removed (with 132 // If we previously had a file here, it was removed (with
134 // `hg rm` or similar) or deleted before it could be 133 // `hg rm` or similar) or deleted before it could be
135 // replaced by a directory. 134 // replaced by a directory or something else.
136 self.mark_removed_or_deleted_if_file( 135 self.mark_removed_or_deleted_if_file(
137 hg_path, 136 hg_path,
138 dirstate_node.state(), 137 dirstate_node.state(),
139 ); 138 );
139 }
140 if file_type.is_dir() {
141 if self.options.collect_traversed_dirs {
142 self.outcome.traversed.push(hg_path.into())
143 }
140 let is_ignored = has_ignored_ancestor || (self.ignore_fn)(hg_path); 144 let is_ignored = has_ignored_ancestor || (self.ignore_fn)(hg_path);
141 let is_at_repo_root = false; 145 let is_at_repo_root = false;
142 self.traverse_fs_directory_and_dirstate( 146 self.traverse_fs_directory_and_dirstate(
143 is_ignored, 147 is_ignored,
144 &mut dirstate_node.children, 148 &mut dirstate_node.children,
145 hg_path, 149 hg_path,
146 &fs_entry.full_path, 150 &fs_entry.full_path,
147 is_at_repo_root, 151 is_at_repo_root,
148 ); 152 );
149 } else { 153 } else {
150 if self.matcher.matches(hg_path) { 154 if file_or_symlink && self.matcher.matches(hg_path) {
151 let full_path = Cow::from(hg_path); 155 let full_path = Cow::from(hg_path);
152 if let Some(entry) = &dirstate_node.entry { 156 if let Some(entry) = &dirstate_node.entry {
153 match entry.state { 157 match entry.state {
154 EntryState::Added => { 158 EntryState::Added => {
155 self.outcome.added.push(full_path) 159 self.outcome.added.push(full_path)
274 has_ignored_ancestor: bool, 278 has_ignored_ancestor: bool,
275 directory_hg_path: &HgPath, 279 directory_hg_path: &HgPath,
276 fs_entry: &DirEntry, 280 fs_entry: &DirEntry,
277 ) { 281 ) {
278 let hg_path = directory_hg_path.join(&fs_entry.base_name); 282 let hg_path = directory_hg_path.join(&fs_entry.base_name);
279 if fs_entry.metadata.is_dir() { 283 let file_type = fs_entry.metadata.file_type();
284 let file_or_symlink = file_type.is_file() || file_type.is_symlink();
285 if file_type.is_dir() {
280 let is_ignored = 286 let is_ignored =
281 has_ignored_ancestor || (self.ignore_fn)(&hg_path); 287 has_ignored_ancestor || (self.ignore_fn)(&hg_path);
282 let traverse_children = if is_ignored { 288 let traverse_children = if is_ignored {
283 // Descendants of an ignored directory are all ignored 289 // Descendants of an ignored directory are all ignored
284 self.options.list_ignored 290 self.options.list_ignored
302 } 308 }
303 } 309 }
304 if self.options.collect_traversed_dirs { 310 if self.options.collect_traversed_dirs {
305 self.outcome.traversed.push(hg_path.into()) 311 self.outcome.traversed.push(hg_path.into())
306 } 312 }
307 } else if self.matcher.matches(&hg_path) { 313 } else if file_or_symlink && self.matcher.matches(&hg_path) {
308 self.mark_unknown_or_ignored(has_ignored_ancestor, hg_path.into()) 314 self.mark_unknown_or_ignored(has_ignored_ancestor, hg_path.into())
309 } 315 }
310 } 316 }
311 317
312 fn mark_unknown_or_ignored( 318 fn mark_unknown_or_ignored(