Mercurial > hg-stable
changeset 50294:bae51b50a5cf stable
dirstate-v2: fix an incorrect handling of readdir errors
Make sure not to cache the results of a failed readdir call.
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Mon, 13 Mar 2023 14:15:34 +0000 |
parents | f1f3a8eb93a1 |
children | 86d2a28c018e |
files | rust/hg-core/src/dirstate_tree/status.rs tests/test-status-eacces.t |
diffstat | 2 files changed, 13 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate_tree/status.rs Fri Mar 10 18:20:50 2023 +0000 +++ b/rust/hg-core/src/dirstate_tree/status.rs Mon Mar 13 14:15:34 2023 +0000 @@ -433,16 +433,21 @@ return Ok(children_all_have_dirstate_node_or_are_ignored); } + let readdir_succeeded; let mut fs_entries = if let Ok(entries) = self.read_dir( directory_hg_path, &directory_entry.fs_path, is_at_repo_root, ) { + readdir_succeeded = true; entries } else { // Treat an unreadable directory (typically because of insufficient // permissions) like an empty directory. `self.read_dir` has // already called `self.io_error` so a warning will be emitted. + // We still need to remember that there was an error so that we + // know not to cache this result. + readdir_succeeded = false; Vec::new() }; @@ -495,6 +500,7 @@ Ok(has_dirstate_node_or_is_ignored) }) .try_reduce(|| true, |a, b| Ok(a && b)) + .map(|res| res && readdir_succeeded) } fn traverse_fs_and_dirstate<'ancestor>(
--- a/tests/test-status-eacces.t Fri Mar 10 18:20:50 2023 +0000 +++ b/tests/test-status-eacces.t Mon Mar 13 14:15:34 2023 +0000 @@ -9,6 +9,7 @@ > EOF #endif + The proliferation of status implementations can be confusing: - The pure python implementation: (no-rhg pure !) @@ -31,20 +32,17 @@ ! d1/x (rhg !) ! d1/x (no-rhg rust !) $ hg status - d1: $EACCES$ (rhg dirstate-v1 !) - d1: $EACCES$ (no-rhg rust dirstate-v1 !) + d1: $EACCES$ (rhg !) + d1: $EACCES$ (no-rhg rust !) d1: $EACCES$ (no-rust no-rhg !) - ! d1/x (rust dirstate-v1 !) - ! d1/x (no-rust rhg dirstate-v1 !) + ! d1/x (rust !) + ! d1/x (no-rust rhg !) $ chmod +r d1 $ hg status - ? d1/y (rhg dirstate-v1 !) - ? d1/y (no-rhg rust dirstate-v1 !) + ? d1/y (rhg !) + ? d1/y (no-rhg rust !) ? d1/y (no-rhg no-rust !) -TODO: make the tests marked with (dirstate-v1) above work the same way -with dirstate-v2 as well. - $ touch d1/z $ hg status ? d1/y