Show More
@@ -65,6 +65,26 b" pub fn status<'tree, 'on_disk: 'tree>(" | |||
|
65 | 65 | |
|
66 | 66 | let filesystem_time_at_status_start = |
|
67 | 67 | filesystem_now(&root_dir).ok().map(TruncatedTimestamp::from); |
|
68 | ||
|
69 | // If the repository is under the current directory, prefer using a | |
|
70 | // relative path, so the kernel needs to traverse fewer directory in every | |
|
71 | // call to `read_dir` or `symlink_metadata`. | |
|
72 | // This is effective in the common case where the current directory is the | |
|
73 | // repository root. | |
|
74 | ||
|
75 | // TODO: Better yet would be to use libc functions like `openat` and | |
|
76 | // `fstatat` to remove such repeated traversals entirely, but the standard | |
|
77 | // library does not provide APIs based on those. | |
|
78 | // Maybe with a crate like https://crates.io/crates/openat instead? | |
|
79 | let root_dir = if let Some(relative) = std::env::current_dir() | |
|
80 | .ok() | |
|
81 | .and_then(|cwd| root_dir.strip_prefix(cwd).ok()) | |
|
82 | { | |
|
83 | relative | |
|
84 | } else { | |
|
85 | &root_dir | |
|
86 | }; | |
|
87 | ||
|
68 | 88 | let outcome = DirstateStatus { |
|
69 | 89 | filesystem_time_at_status_start, |
|
70 | 90 | ..Default::default() |
@@ -752,13 +772,16 b' impl DirEntry {' | |||
|
752 | 772 | /// * Elsewhere, we’re listing the content of a sub-repo. Return an empty |
|
753 | 773 | /// list instead. |
|
754 | 774 | fn read_dir(path: &Path, is_at_repo_root: bool) -> io::Result<Vec<Self>> { |
|
775 | // `read_dir` returns a "not found" error for the empty path | |
|
776 | let at_cwd = path == Path::new(""); | |
|
777 | let read_dir_path = if at_cwd { Path::new(".") } else { path }; | |
|
755 | 778 | let mut results = Vec::new(); |
|
756 | for entry in path.read_dir()? { | |
|
779 | for entry in read_dir_path.read_dir()? { | |
|
757 | 780 | let entry = entry?; |
|
758 | 781 | let metadata = entry.metadata()?; |
|
759 |
let name = |
|
|
782 | let file_name = entry.file_name(); | |
|
760 | 783 | // FIXME don't do this when cached |
|
761 |
if name == |
|
|
784 | if file_name == ".hg" { | |
|
762 | 785 | if is_at_repo_root { |
|
763 | 786 | // Skip the repo’s own .hg (might be a symlink) |
|
764 | 787 | continue; |
@@ -768,9 +791,15 b' impl DirEntry {' | |||
|
768 | 791 | return Ok(Vec::new()); |
|
769 | 792 | } |
|
770 | 793 | } |
|
794 | let full_path = if at_cwd { | |
|
795 | file_name.clone().into() | |
|
796 | } else { | |
|
797 | entry.path() | |
|
798 | }; | |
|
799 | let base_name = get_bytes_from_os_string(file_name).into(); | |
|
771 | 800 | results.push(DirEntry { |
|
772 |
base_name |
|
|
773 |
full_path |
|
|
801 | base_name, | |
|
802 | full_path, | |
|
774 | 803 | metadata, |
|
775 | 804 | }) |
|
776 | 805 | } |
General Comments 0
You need to be logged in to leave comments.
Login now