From 9918693037dce8aa4bb6f08741b6812923486c18 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 11:26:03 +0200 Subject: Merging upstream version 1.76.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/gix/src/revision/spec/mod.rs | 9 +++++++++ vendor/gix/src/revision/spec/parse/delegate/mod.rs | 2 ++ .../gix/src/revision/spec/parse/delegate/navigate.rs | 20 +++++++++++++++++--- vendor/gix/src/revision/spec/parse/mod.rs | 4 ++++ 4 files changed, 32 insertions(+), 3 deletions(-) (limited to 'vendor/gix/src/revision/spec') diff --git a/vendor/gix/src/revision/spec/mod.rs b/vendor/gix/src/revision/spec/mod.rs index a6a6eb739..af58ecdff 100644 --- a/vendor/gix/src/revision/spec/mod.rs +++ b/vendor/gix/src/revision/spec/mod.rs @@ -1,3 +1,4 @@ +use crate::bstr::BStr; use crate::{ext::ReferenceExt, revision::Spec, Id, Reference}; /// @@ -37,6 +38,7 @@ impl<'repo> Spec<'repo> { pub fn from_id(id: Id<'repo>) -> Self { Spec { inner: gix_revision::Spec::Include(id.inner), + path: None, repo: id.repo, first_ref: None, second_ref: None, @@ -62,6 +64,13 @@ impl<'repo> Spec<'repo> { ) } + /// Return the path encountered in specs like `@:` or `:`, along with the kind of object it represents. + /// + /// Note that there can only be one as paths always terminates further revspec parsing. + pub fn path_and_mode(&self) -> Option<(&BStr, gix_object::tree::EntryMode)> { + self.path.as_ref().map(|(p, mode)| (p.as_ref(), *mode)) + } + /// Return the name of the first reference we encountered while resolving the rev-spec, or `None` if a short hash /// was used. For example, `@` might yield `Some(HEAD)`, but `abcd` yields `None`. pub fn first_reference(&self) -> Option<&gix_ref::Reference> { diff --git a/vendor/gix/src/revision/spec/parse/delegate/mod.rs b/vendor/gix/src/revision/spec/parse/delegate/mod.rs index eaf7f5fd6..374906eaf 100644 --- a/vendor/gix/src/revision/spec/parse/delegate/mod.rs +++ b/vendor/gix/src/revision/spec/parse/delegate/mod.rs @@ -17,6 +17,7 @@ impl<'repo> Delegate<'repo> { Delegate { refs: Default::default(), objs: Default::default(), + paths: Default::default(), ambiguous_objects: Default::default(), idx: 0, kind: None, @@ -100,6 +101,7 @@ impl<'repo> Delegate<'repo> { let range = zero_or_one_objects_or_ambiguity_err(self.objs, self.prefix, self.err, self.repo)?; Ok(crate::revision::Spec { + path: self.paths[0].take().or(self.paths[1].take()), first_ref: self.refs[0].take(), second_ref: self.refs[1].take(), inner: kind_to_spec(self.kind, range)?, diff --git a/vendor/gix/src/revision/spec/parse/delegate/navigate.rs b/vendor/gix/src/revision/spec/parse/delegate/navigate.rs index 51feb1d76..731a24136 100644 --- a/vendor/gix/src/revision/spec/parse/delegate/navigate.rs +++ b/vendor/gix/src/revision/spec/parse/delegate/navigate.rs @@ -121,7 +121,7 @@ impl<'repo> delegate::Navigate for Delegate<'repo> { let lookup_path = |obj: &ObjectId| { let tree_id = peel(repo, obj, gix_object::Kind::Tree)?; if path.is_empty() { - return Ok(tree_id); + return Ok((tree_id, gix_object::tree::EntryKind::Tree.into())); } let mut tree = repo.find_object(tree_id)?.into_tree(); let entry = @@ -131,11 +131,17 @@ impl<'repo> delegate::Navigate for Delegate<'repo> { object: obj.attach(repo).shorten_or_id(), tree: tree_id.attach(repo).shorten_or_id(), })?; - Ok(entry.object_id()) + Ok((entry.object_id(), entry.mode())) }; for obj in objs.iter() { match lookup_path(obj) { - Ok(replace) => replacements.push((*obj, replace)), + Ok((replace, mode)) => { + if !path.is_empty() { + // Technically this is letting the last one win, but so be it. + self.paths[self.idx] = Some((path.to_owned(), mode)); + } + replacements.push((*obj, replace)) + } Err(err) => errors.push((*obj, err)), } } @@ -306,6 +312,14 @@ impl<'repo> delegate::Navigate for Delegate<'repo> { self.objs[self.idx] .get_or_insert_with(HashSet::default) .insert(entry.id); + + self.paths[self.idx] = Some(( + path.to_owned(), + entry + .mode + .to_tree_entry_mode() + .unwrap_or(gix_object::tree::EntryKind::Blob.into()), + )); Some(()) } None => { diff --git a/vendor/gix/src/revision/spec/parse/mod.rs b/vendor/gix/src/revision/spec/parse/mod.rs index 950dfa004..e45847763 100644 --- a/vendor/gix/src/revision/spec/parse/mod.rs +++ b/vendor/gix/src/revision/spec/parse/mod.rs @@ -7,6 +7,7 @@ use gix_revision::spec::parse; use crate::{bstr::BStr, revision::Spec, Repository}; mod types; +use crate::bstr::BString; pub use types::{Error, ObjectKindHint, Options, RefsHint}; /// @@ -45,6 +46,9 @@ impl<'repo> Spec<'repo> { struct Delegate<'repo> { refs: [Option; 2], objs: [Option>; 2], + /// Path specified like `@:` or `:` for later use when looking up specs. + /// Note that it terminates spec parsing, so it's either `0` or `1`, never both. + paths: [Option<(BString, gix_object::tree::EntryMode)>; 2], /// The originally encountered ambiguous objects for potential later use in errors. ambiguous_objects: [Option>; 2], idx: usize, -- cgit v1.2.3