108 lines · 5.2 KB · Rust
RawDownload
#![allow(clippy::result_large_err)]use std::path::Path; pub use gix_discover::*; use crate::{ThreadSafeRepository, bstr::BString}; /// The error returned by [`crate::discover()`].#[derive(Debug, thiserror::Error)]#[expect(missing_docs)]pub enum Error {    #[error(transparent)]    Discover(#[from] upwards::Error),    #[error(transparent)]    Open(#[from] crate::open::Error),} impl ThreadSafeRepository {    /// Try to open a git repository in `directory` and search upwards through its parents until one is found,    /// using default trust options which matters in case the found repository isn't owned by the current user.    pub fn discover(directory: impl AsRef<Path>) -> Result<Self, Error> {        Self::discover_opts(directory, Default::default(), Default::default())    }     /// Try to open a git repository in `directory` and search upwards through its parents until one is found,    /// while applying `options`. Then use the `trust_map` to determine which of our own repository options to use    /// for instantiations.    ///    /// Note that [trust overrides](crate::open::Options::with()) in the `trust_map` are not effective here and we will    /// always override it with the determined trust value as per [gix_discover::upwards::Options::trust].    /// This value, however, can be set to [assume a given trust level](gix_discover::upwards::TrustPolicy::Assume) to let    /// callers control the trust level without re-determining it.    pub fn discover_opts(        directory: impl AsRef<Path>,        options: upwards::Options<'_>,        trust_map: gix_sec::trust::Mapping<crate::open::Options>,    ) -> Result<Self, Error> {        let _span = gix_trace::coarse!("ThreadSafeRepository::discover()");        let (path, trust) = upwards_opts(directory.as_ref(), options)?;        let (git_dir, worktree_dir) = path.into_repository_and_work_tree_directories();        let mut options = trust_map.into_value_by_level(trust);        options.git_dir_trust = trust.into();        // Note that we will adjust the `current_dir` later so it matches the value of `core.precomposeUnicode`.        options.current_dir = Some(gix_fs::current_dir(false).map_err(upwards::Error::CurrentDir)?);        Self::open_from_paths(git_dir, worktree_dir, options, None).map_err(Into::into)    }     /// Try to open a git repository directly from the environment.    /// If that fails, discover upwards from `directory` until one is found,    /// while applying discovery options from the environment.    ///    /// For more, see [`ThreadSafeRepository::discover_with_environment_overrides_opts()`].    pub fn discover_with_environment_overrides(directory: impl AsRef<Path>) -> Result<Self, Error> {        Self::discover_with_environment_overrides_opts(directory, Default::default(), Default::default())    }     /// Try to open a git repository directly from the environment, which reads `GIT_DIR`    /// if it is set. Once selected, the repository also honors these primary environment    /// overrides if permitted by its options:    ///    /// - `GIT_WORK_TREE`    /// - `GIT_INDEX_FILE`    /// - `GIT_SHALLOW_FILE`    /// - `GIT_NAMESPACE`    ///    /// If `GIT_DIR` is unset, discover upwards from `directory` until one is found,    /// while applying `options` with discovery overrides from the environment which includes:    ///    /// - `GIT_DISCOVERY_ACROSS_FILESYSTEM`    /// - `GIT_CEILING_DIRECTORIES`    ///    /// This is particularly useful for hooks, as Git exports repository-local environment variables    /// to them. Honoring these variables preserves the repository and worktree context established by    /// Git, including temporary overrides, instead of relying only on discovery from `directory`.    ///    /// Finally, use the `trust_map` to determine which of our own repository options to use    /// based on the trust level of the effective repository directory.    ///    /// ### Note    ///    /// Consider to set [`match_ceiling_dir_or_error = false`](gix_discover::upwards::Options::match_ceiling_dir_or_error)    /// to allow discovery if an outside environment variable sets non-matching ceiling directories for greater    /// compatibility with Git.    pub fn discover_with_environment_overrides_opts(        directory: impl AsRef<Path>,        mut options: upwards::Options<'_>,        trust_map: gix_sec::trust::Mapping<crate::open::Options>,    ) -> Result<Self, Error> {        fn apply_additional_environment(mut opts: upwards::Options<'_>) -> upwards::Options<'_> {            use crate::bstr::ByteVec;             if let Some(cross_fs) = std::env::var_os("GIT_DISCOVERY_ACROSS_FILESYSTEM")                .and_then(|v| Vec::from_os_string(v).ok().map(BString::from))                && let Ok(b) = gix_config::Boolean::try_from(cross_fs)            {                opts.cross_fs = b.into();            }            opts        }         if std::env::var_os("GIT_DIR").is_some() {            return Self::open_with_environment_overrides(directory.as_ref(), trust_map).map_err(Error::Open);        }         options = apply_additional_environment(options.apply_environment());        Self::discover_opts(directory, options, trust_map)    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t