diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:35 +0000 |
commit | 7e5d7eea9c580ef4b41a765bde624af431942b96 (patch) | |
tree | 2c0d9ca12878fc4525650aa4e54d77a81a07cc09 /vendor/gix-discover/src/upwards/util.rs | |
parent | Adding debian version 1.70.0+dfsg1-9. (diff) | |
download | rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.tar.xz rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-discover/src/upwards/util.rs')
-rw-r--r-- | vendor/gix-discover/src/upwards/util.rs | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/vendor/gix-discover/src/upwards/util.rs b/vendor/gix-discover/src/upwards/util.rs new file mode 100644 index 000000000..93c6e993e --- /dev/null +++ b/vendor/gix-discover/src/upwards/util.rs @@ -0,0 +1,78 @@ +use std::path::{Path, PathBuf}; + +use crate::DOT_GIT_DIR; + +pub(crate) fn shorten_path_with_cwd(cursor: PathBuf, cwd: &Path) -> PathBuf { + fn comp_len(c: std::path::Component<'_>) -> usize { + use std::path::Component::*; + match c { + Prefix(p) => p.as_os_str().len(), + CurDir => 1, + ParentDir => 2, + Normal(p) => p.len(), + RootDir => 1, + } + } + + debug_assert_eq!(cursor.file_name().and_then(|f| f.to_str()), Some(DOT_GIT_DIR)); + let parent = cursor.parent().expect(".git appended"); + cwd.strip_prefix(parent) + .ok() + .and_then(|path_relative_to_cwd| { + let relative_path_components = path_relative_to_cwd.components().count(); + let current_component_len = cursor.components().map(comp_len).sum::<usize>(); + (relative_path_components * "..".len() < current_component_len).then(|| { + std::iter::repeat("..") + .take(relative_path_components) + .chain(Some(DOT_GIT_DIR)) + .collect() + }) + }) + .unwrap_or(cursor) +} + +/// Find the number of components parenting the `search_dir` before the first directory in `ceiling_dirs`. +/// `search_dir` needs to be normalized, and we normalize every ceiling as well. +pub(crate) fn find_ceiling_height(search_dir: &Path, ceiling_dirs: &[PathBuf], cwd: &Path) -> Option<usize> { + if ceiling_dirs.is_empty() { + return None; + } + + let search_realpath; + let search_dir = if search_dir.is_absolute() { + search_dir + } else { + search_realpath = gix_path::realpath_opts(search_dir, cwd, gix_path::realpath::MAX_SYMLINKS).ok()?; + search_realpath.as_path() + }; + ceiling_dirs + .iter() + .filter_map(|ceiling_dir| { + #[cfg(windows)] + let ceiling_dir = dunce::simplified(ceiling_dir); + let mut ceiling_dir = gix_path::normalize(ceiling_dir, cwd)?; + if !ceiling_dir.is_absolute() { + ceiling_dir = gix_path::normalize(cwd.join(ceiling_dir.as_ref()), cwd)?; + } + search_dir + .strip_prefix(ceiling_dir.as_ref()) + .ok() + .map(|path_relative_to_ceiling| path_relative_to_ceiling.components().count()) + .filter(|height| *height > 0) + }) + .min() +} + +/// Returns the device ID of the directory. +#[cfg(target_os = "linux")] +pub(crate) fn device_id(m: &std::fs::Metadata) -> u64 { + use std::os::linux::fs::MetadataExt; + m.st_dev() +} + +/// Returns the device ID of the directory. +#[cfg(all(unix, not(target_os = "linux")))] +pub(crate) fn device_id(m: &std::fs::Metadata) -> u64 { + use std::os::unix::fs::MetadataExt; + m.dev() +} |