summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/revision/spec/parse/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix/src/revision/spec/parse/types.rs')
-rw-r--r--vendor/gix/src/revision/spec/parse/types.rs182
1 files changed, 182 insertions, 0 deletions
diff --git a/vendor/gix/src/revision/spec/parse/types.rs b/vendor/gix/src/revision/spec/parse/types.rs
new file mode 100644
index 000000000..4e523ab14
--- /dev/null
+++ b/vendor/gix/src/revision/spec/parse/types.rs
@@ -0,0 +1,182 @@
+use crate::{bstr::BString, object, reference};
+
+/// A hint to know what to do if refs and object names are equal.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum RefsHint {
+ /// This is the default, and leads to specs that look like objects identified by full hex sha and are objects to be used
+ /// instead of similarly named references. The latter is not typical but can absolutely happen by accident.
+ /// If the object prefix is shorter than the maximum hash length of the repository, use the reference instead, which is
+ /// preferred as there are many valid object names like `beef` and `cafe` that are short and both valid and typical prefixes
+ /// for objects.
+ /// Git chooses this as default as well, even though it means that every object prefix is also looked up as ref.
+ PreferObjectOnFullLengthHexShaUseRefOtherwise,
+ /// No matter what, if it looks like an object prefix and has an object, use it.
+ /// Note that no ref-lookup is made here which is the fastest option.
+ PreferObject,
+ /// When an object is found for a given prefix, also check if a reference exists with that name and if it does,
+ /// use that moving forward.
+ PreferRef,
+ /// If there is an ambiguous situation, instead of silently choosing one over the other, fail instead.
+ Fail,
+}
+
+/// A hint to know which object kind to prefer if multiple objects match a prefix.
+///
+/// This disambiguation mechanism is applied only if there is no disambiguation hints in the spec itself.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum ObjectKindHint {
+ /// Pick objects that are commits themselves.
+ Commit,
+ /// Pick objects that can be peeled into a commit, i.e. commits themselves or tags which are peeled until a commit is found.
+ Committish,
+ /// Pick objects that are trees themselves.
+ Tree,
+ /// Pick objects that can be peeled into a tree, i.e. trees themselves or tags which are peeled until a tree is found or commits
+ /// whose tree is chosen.
+ Treeish,
+ /// Pick objects that are blobs.
+ Blob,
+}
+
+impl Default for RefsHint {
+ fn default() -> Self {
+ RefsHint::PreferObjectOnFullLengthHexShaUseRefOtherwise
+ }
+}
+
+/// Options for use in [`revision::Spec::from_bstr()`][crate::revision::Spec::from_bstr()].
+#[derive(Debug, Default, Copy, Clone)]
+pub struct Options {
+ /// What to do if both refs and object names match the same input.
+ pub refs_hint: RefsHint,
+ /// The hint to use when encountering multiple object matching a prefix.
+ ///
+ /// If `None`, the rev-spec itself must disambiguate the object by drilling down to desired kinds or applying
+ /// other disambiguating transformations.
+ pub object_kind_hint: Option<ObjectKindHint>,
+}
+
+/// The error returned by [`crate::Repository::rev_parse()`].
+#[derive(Debug, thiserror::Error)]
+#[allow(missing_docs)]
+pub enum Error {
+ #[error("The rev-spec is malformed and misses a ref name")]
+ Malformed,
+ #[error("Unborn heads do not have a reflog yet")]
+ UnbornHeadsHaveNoRefLog,
+ #[error("This feature will be implemented once {dependency}")]
+ Planned { dependency: &'static str },
+ #[error("Reference {reference:?} does not have a reference log, cannot {action}")]
+ MissingRefLog { reference: BString, action: &'static str },
+ #[error("HEAD has {available} prior checkouts and checkout number {desired} is out of range")]
+ PriorCheckoutOutOfRange { desired: usize, available: usize },
+ #[error("Reference {:?} has {available} ref-log entries and entry number {desired} is out of range", reference.name.as_bstr())]
+ RefLogEntryOutOfRange {
+ reference: gix_ref::Reference,
+ desired: usize,
+ available: usize,
+ },
+ #[error(
+ "Commit {oid} has {available} ancestors along the first parent and ancestor number {desired} is out of range"
+ )]
+ AncestorOutOfRange {
+ oid: gix_hash::Prefix,
+ desired: usize,
+ available: usize,
+ },
+ #[error("Commit {oid} has {available} parents and parent number {desired} is out of range")]
+ ParentOutOfRange {
+ oid: gix_hash::Prefix,
+ desired: usize,
+ available: usize,
+ },
+ #[error("Path {desired_path:?} did not exist in index at stage {desired_stage}{}{}", stage_hint.map(|actual|format!(". It does exist at stage {actual}")).unwrap_or_default(), exists.then(|| ". It exists on disk").unwrap_or(". It does not exist on disk"))]
+ IndexLookup {
+ desired_path: BString,
+ desired_stage: gix_index::entry::Stage,
+ stage_hint: Option<gix_index::entry::Stage>,
+ exists: bool,
+ },
+ #[error(transparent)]
+ FindHead(#[from] reference::find::existing::Error),
+ #[error(transparent)]
+ Index(#[from] crate::worktree::open_index::Error),
+ #[error(transparent)]
+ RevWalkIterInit(#[from] crate::reference::iter::init::Error),
+ #[error(transparent)]
+ RevWalkAllReferences(#[from] gix_ref::packed::buffer::open::Error),
+ #[cfg(feature = "regex")]
+ #[error(transparent)]
+ InvalidRegex(#[from] regex::Error),
+ #[cfg_attr(
+ feature = "regex",
+ error("None of {commits_searched} commits from {oid} matched regex {regex:?}")
+ )]
+ #[cfg_attr(
+ not(feature = "regex"),
+ error("None of {commits_searched} commits from {oid} matched text {regex:?}")
+ )]
+ NoRegexMatch {
+ regex: BString,
+ oid: gix_hash::Prefix,
+ commits_searched: usize,
+ },
+ #[cfg_attr(
+ feature = "regex",
+ error("None of {commits_searched} commits reached from all references matched regex {regex:?}")
+ )]
+ #[cfg_attr(
+ not(feature = "regex"),
+ error("None of {commits_searched} commits reached from all references matched text {regex:?}")
+ )]
+ NoRegexMatchAllRefs { regex: BString, commits_searched: usize },
+ #[error(
+ "The short hash {prefix} matched both the reference {} and at least one object", reference.name)]
+ AmbiguousRefAndObject {
+ /// The prefix to look for.
+ prefix: gix_hash::Prefix,
+ /// The reference matching the prefix.
+ reference: gix_ref::Reference,
+ },
+ #[error(transparent)]
+ IdFromHex(#[from] gix_hash::decode::Error),
+ #[error(transparent)]
+ FindReference(#[from] gix_ref::file::find::existing::Error),
+ #[error(transparent)]
+ FindObject(#[from] object::find::existing::Error),
+ #[error(transparent)]
+ LookupPrefix(#[from] gix_odb::store::prefix::lookup::Error),
+ #[error(transparent)]
+ PeelToKind(#[from] object::peel::to_kind::Error),
+ #[error("Object {oid} was a {actual}, but needed it to be a {expected}")]
+ ObjectKind {
+ oid: gix_hash::Prefix,
+ actual: gix_object::Kind,
+ expected: gix_object::Kind,
+ },
+ #[error(transparent)]
+ Parse(#[from] gix_revision::spec::parse::Error),
+ #[error("An object prefixed {prefix} could not be found")]
+ PrefixNotFound { prefix: gix_hash::Prefix },
+ #[error("Short id {prefix} is ambiguous. Candidates are:\n{}", info.iter().map(|(oid, info)| format!("\t{oid} {info}")).collect::<Vec<_>>().join("\n"))]
+ AmbiguousPrefix {
+ prefix: gix_hash::Prefix,
+ info: Vec<(gix_hash::Prefix, super::error::CandidateInfo)>,
+ },
+ #[error("Could not find path {path:?} in tree {tree} of parent object {object}")]
+ PathNotFound {
+ object: gix_hash::Prefix,
+ tree: gix_hash::Prefix,
+ path: BString,
+ },
+ #[error("{current}")]
+ Multi {
+ current: Box<dyn std::error::Error + Send + Sync + 'static>,
+ #[source]
+ next: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
+ },
+ #[error(transparent)]
+ Traverse(#[from] gix_traverse::commit::ancestors::Error),
+ #[error("Spec does not contain a single object id")]
+ SingleNotFound,
+}