summaryrefslogtreecommitdiffstats
path: root/vendor/gix-worktree/src/cache/mod.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/gix-worktree/src/cache/mod.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-worktree/src/cache/mod.rs')
-rw-r--r--vendor/gix-worktree/src/cache/mod.rs178
1 files changed, 178 insertions, 0 deletions
diff --git a/vendor/gix-worktree/src/cache/mod.rs b/vendor/gix-worktree/src/cache/mod.rs
new file mode 100644
index 000000000..7984b2c4c
--- /dev/null
+++ b/vendor/gix-worktree/src/cache/mod.rs
@@ -0,0 +1,178 @@
+#![allow(missing_docs)]
+use std::path::{Path, PathBuf};
+
+use bstr::{BStr, ByteSlice};
+use gix_hash::oid;
+
+use super::Cache;
+use crate::PathIdMapping;
+
+/// Various aggregate numbers collected from when the corresponding [`Cache`] was instantiated.
+#[derive(Default, Clone, Copy, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+pub struct Statistics {
+ /// The amount of platforms created to do further matching.
+ pub platforms: usize,
+ /// Information about the stack delegate.
+ pub delegate: delegate::Statistics,
+ /// Information about attributes
+ pub attributes: state::attributes::Statistics,
+ /// Information about the ignore stack
+ pub ignore: state::ignore::Statistics,
+}
+
+#[derive(Clone)]
+pub enum State {
+ /// Useful for checkout where directories need creation, but we need to access attributes as well.
+ CreateDirectoryAndAttributesStack {
+ /// If there is a symlink or a file in our path, try to unlink it before creating the directory.
+ unlink_on_collision: bool,
+ /// State to handle attribute information
+ attributes: state::Attributes,
+ },
+ /// Used when adding files, requiring access to both attributes and ignore information, for example during add operations.
+ AttributesAndIgnoreStack {
+ /// State to handle attribute information
+ attributes: state::Attributes,
+ /// State to handle exclusion information
+ ignore: state::Ignore,
+ },
+ /// Used when providing worktree status information.
+ IgnoreStack(state::Ignore),
+}
+
+#[must_use]
+pub struct Platform<'a> {
+ parent: &'a Cache,
+ is_dir: Option<bool>,
+}
+
+/// Initialization
+impl Cache {
+ /// Create a new instance with `worktree_root` being the base for all future paths we match.
+ /// `state` defines the capabilities of the cache.
+ /// The `case` configures attribute and exclusion case sensitivity at *query time*, which should match the case that
+ /// `state` might be configured with.
+ /// `buf` is used when reading files, and `id_mappings` should have been created with [State::id_mappings_from_index()].
+ pub fn new(
+ worktree_root: impl Into<PathBuf>,
+ state: State,
+ case: gix_glob::pattern::Case,
+ buf: Vec<u8>,
+ id_mappings: Vec<PathIdMapping>,
+ ) -> Self {
+ let root = worktree_root.into();
+ Cache {
+ stack: gix_fs::Stack::new(root),
+ state,
+ case,
+ buf,
+ id_mappings,
+ statistics: Statistics::default(),
+ }
+ }
+}
+
+/// Entry points for attribute query
+impl Cache {
+ /// Append the `relative` path to the root directory of the cache and efficiently create leading directories, while assuring that no
+ /// symlinks are in that path.
+ /// Unless `is_dir` is known with `Some(…)`, then `relative` points to a directory itself in which case the entire resulting
+ /// path is created as directory. If it's not known it is assumed to be a file.
+ /// `find` maybe used to lookup objects from an [id mapping][crate::cache::State::id_mappings_from_index()], with mappnigs
+ ///
+ /// Provide access to cached information for that `relative` path via the returned platform.
+ pub fn at_path<Find, E>(
+ &mut self,
+ relative: impl AsRef<Path>,
+ is_dir: Option<bool>,
+ find: Find,
+ ) -> std::io::Result<Platform<'_>>
+ where
+ Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E>,
+ E: std::error::Error + Send + Sync + 'static,
+ {
+ self.statistics.platforms += 1;
+ let mut delegate = StackDelegate {
+ state: &mut self.state,
+ buf: &mut self.buf,
+ is_dir: is_dir.unwrap_or(false),
+ id_mappings: &self.id_mappings,
+ find,
+ case: self.case,
+ statistics: &mut self.statistics,
+ };
+ self.stack.make_relative_path_current(relative, &mut delegate)?;
+ Ok(Platform { parent: self, is_dir })
+ }
+
+ /// Obtain a platform for lookups from a repo-`relative` path, typically obtained from an index entry. `is_dir` should reflect
+ /// whether it's a directory or not, or left at `None` if unknown.
+ /// `find` maybe used to lookup objects from an [id mapping][crate::cache::State::id_mappings_from_index()].
+ /// All effects are similar to [`at_path()`][Self::at_path()].
+ ///
+ /// If `relative` ends with `/` and `is_dir` is `None`, it is automatically assumed to be a directory.
+ ///
+ /// ### Panics
+ ///
+ /// on illformed UTF8 in `relative`
+ pub fn at_entry<'r, Find, E>(
+ &mut self,
+ relative: impl Into<&'r BStr>,
+ is_dir: Option<bool>,
+ find: Find,
+ ) -> std::io::Result<Platform<'_>>
+ where
+ Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E>,
+ E: std::error::Error + Send + Sync + 'static,
+ {
+ let relative = relative.into();
+ let relative_path = gix_path::from_bstr(relative);
+
+ self.at_path(
+ relative_path,
+ is_dir.or_else(|| relative.ends_with_str("/").then_some(true)),
+ find,
+ )
+ }
+}
+
+/// Mutation
+impl Cache {
+ /// Reset the statistics after returning them.
+ pub fn take_statistics(&mut self) -> Statistics {
+ std::mem::take(&mut self.statistics)
+ }
+
+ /// Return our state for applying changes.
+ pub fn state_mut(&mut self) -> &mut State {
+ &mut self.state
+ }
+}
+
+/// Access
+impl Cache {
+ /// Return the statistics we gathered thus far.
+ pub fn statistics(&self) -> &Statistics {
+ &self.statistics
+ }
+ /// Return the state for introspection.
+ pub fn state(&self) -> &State {
+ &self.state
+ }
+
+ /// Return the base path against which all entries or paths should be relative to when querying.
+ ///
+ /// Note that this path _may_ not be canonicalized.
+ pub fn base(&self) -> &Path {
+ self.stack.root()
+ }
+}
+
+///
+pub mod delegate;
+use delegate::StackDelegate;
+
+mod platform;
+///
+pub mod state;