##// END OF EJS Templates
status: prefer relative paths in Rust code...
Simon Sapin -
r49591:94e36b23 default
parent child Browse files
Show More
@@ -65,6 +65,26 b" pub fn status<'tree, 'on_disk: 'tree>("
65
65
66 let filesystem_time_at_status_start =
66 let filesystem_time_at_status_start =
67 filesystem_now(&root_dir).ok().map(TruncatedTimestamp::from);
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 let outcome = DirstateStatus {
88 let outcome = DirstateStatus {
69 filesystem_time_at_status_start,
89 filesystem_time_at_status_start,
70 ..Default::default()
90 ..Default::default()
@@ -752,13 +772,16 b' impl DirEntry {'
752 /// * Elsewhere, we’re listing the content of a sub-repo. Return an empty
772 /// * Elsewhere, we’re listing the content of a sub-repo. Return an empty
753 /// list instead.
773 /// list instead.
754 fn read_dir(path: &Path, is_at_repo_root: bool) -> io::Result<Vec<Self>> {
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 let mut results = Vec::new();
778 let mut results = Vec::new();
756 for entry in path.read_dir()? {
779 for entry in read_dir_path.read_dir()? {
757 let entry = entry?;
780 let entry = entry?;
758 let metadata = entry.metadata()?;
781 let metadata = entry.metadata()?;
759 let name = get_bytes_from_os_string(entry.file_name());
782 let file_name = entry.file_name();
760 // FIXME don't do this when cached
783 // FIXME don't do this when cached
761 if name == b".hg" {
784 if file_name == ".hg" {
762 if is_at_repo_root {
785 if is_at_repo_root {
763 // Skip the repo’s own .hg (might be a symlink)
786 // Skip the repo’s own .hg (might be a symlink)
764 continue;
787 continue;
@@ -768,9 +791,15 b' impl DirEntry {'
768 return Ok(Vec::new());
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 results.push(DirEntry {
800 results.push(DirEntry {
772 base_name: name.into(),
801 base_name,
773 full_path: entry.path(),
802 full_path,
774 metadata,
803 metadata,
775 })
804 })
776 }
805 }
General Comments 0
You need to be logged in to leave comments. Login now