summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/head
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/gix/src/head
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix/src/head')
-rw-r--r--vendor/gix/src/head/peel.rs158
1 files changed, 97 insertions, 61 deletions
diff --git a/vendor/gix/src/head/peel.rs b/vendor/gix/src/head/peel.rs
index 88e23636f..4ee116ed0 100644
--- a/vendor/gix/src/head/peel.rs
+++ b/vendor/gix/src/head/peel.rs
@@ -1,12 +1,14 @@
use crate::{
ext::{ObjectIdExt, ReferenceExt},
+ head::Kind,
Head,
};
mod error {
use crate::{object, reference};
- /// The error returned by [`Head::peel_to_id_in_place()`][super::Head::peel_to_id_in_place()] and [`Head::into_fully_peeled_id()`][super::Head::into_fully_peeled_id()].
+ /// The error returned by [`Head::peel_to_id_in_place()`](super::Head::try_peel_to_id_in_place())
+ /// and [`Head::into_fully_peeled_id()`](super::Head::try_into_peeled_id()).
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
@@ -19,13 +21,11 @@ mod error {
pub use error::Error;
-use crate::head::Kind;
-
///
-pub mod to_commit {
+pub mod into_id {
use crate::object;
- /// The error returned by [`Head::peel_to_commit_in_place()`][super::Head::peel_to_commit_in_place()].
+ /// The error returned by [`Head::into_peeled_id()`](super::Head::into_peeled_id()).
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
@@ -38,86 +38,122 @@ pub mod to_commit {
}
}
+///
+pub mod to_commit {
+ use crate::object;
+
+ /// The error returned by [`Head::peel_to_commit_in_place()`](super::Head::peel_to_commit_in_place()).
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error(transparent)]
+ PeelToObject(#[from] super::to_object::Error),
+ #[error(transparent)]
+ ObjectKind(#[from] object::try_into::Error),
+ }
+}
+
+///
+pub mod to_object {
+ /// The error returned by [`Head::peel_to_object_in_place()`](super::Head::peel_to_object_in_place()).
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error(transparent)]
+ Peel(#[from] super::Error),
+ #[error("Branch '{name}' does not have any commits")]
+ Unborn { name: gix_ref::FullName },
+ }
+}
+
impl<'repo> Head<'repo> {
- // TODO: tests
- /// Peel this instance to make obtaining its final target id possible, while returning an error on unborn heads.
- pub fn peeled(mut self) -> Result<Self, Error> {
- self.peel_to_id_in_place().transpose()?;
- Ok(self)
+ /// Peel this instance and consume it to make obtaining its final target id possible, while returning an error on unborn heads.
+ ///
+ /// The final target is obtained by following symbolic references and peeling tags to their final destination, which
+ /// typically is a commit, but can be any object.
+ pub fn into_peeled_id(mut self) -> Result<crate::Id<'repo>, into_id::Error> {
+ self.try_peel_to_id_in_place()?;
+ self.id().ok_or_else(|| match self.kind {
+ Kind::Symbolic(gix_ref::Reference { name, .. }) | Kind::Unborn(name) => into_id::Error::Unborn { name },
+ Kind::Detached { .. } => unreachable!("id can be returned after peeling"),
+ })
+ }
+
+ /// Peel this instance and consume it to make obtaining its final target object possible, while returning an error on unborn heads.
+ ///
+ /// The final target is obtained by following symbolic references and peeling tags to their final destination, which
+ /// typically is a commit, but can be any object as well.
+ pub fn into_peeled_object(mut self) -> Result<crate::Object<'repo>, to_object::Error> {
+ self.peel_to_object_in_place()
+ }
+
+ /// Consume this instance and transform it into the final object that it points to, or `Ok(None)` if the `HEAD`
+ /// reference is yet to be born.
+ ///
+ /// The final target is obtained by following symbolic references and peeling tags to their final destination, which
+ /// typically is a commit, but can be any object.
+ pub fn try_into_peeled_id(mut self) -> Result<Option<crate::Id<'repo>>, Error> {
+ self.try_peel_to_id_in_place()
}
- // TODO: tests
- // TODO: Fix this! It's not consistently peeling tags. The whole peeling business should be reconsidered to do what people usually
- // want which is to peel references, if present, and then peel objects with control over which object type to end at.
- // Finding a good interface for that isn't easy as ideally, it's an iterator that shows the intermediate objects so the user
- // can select which tag of a chain to choose.
/// Follow the symbolic reference of this head until its target object and peel it by following tag objects until there is no
/// more object to follow, and return that object id.
///
- /// Returns `None` if the head is unborn.
- pub fn peel_to_id_in_place(&mut self) -> Option<Result<crate::Id<'repo>, Error>> {
- Some(match &mut self.kind {
- Kind::Unborn(_name) => return None,
+ /// Returns `Ok(None)` if the head is unborn.
+ ///
+ /// The final target is obtained by following symbolic references and peeling tags to their final destination, which
+ /// typically is a commit, but can be any object.
+ pub fn try_peel_to_id_in_place(&mut self) -> Result<Option<crate::Id<'repo>>, Error> {
+ Ok(Some(match &mut self.kind {
+ Kind::Unborn(_name) => return Ok(None),
Kind::Detached {
peeled: Some(peeled), ..
- } => Ok((*peeled).attach(self.repo)),
+ } => (*peeled).attach(self.repo),
Kind::Detached { peeled: None, target } => {
- match target
- .attach(self.repo)
- .object()
- .map_err(Into::into)
- .and_then(|obj| obj.peel_tags_to_end().map_err(Into::into))
- .map(|peeled| peeled.id)
- {
- Ok(peeled) => {
- self.kind = Kind::Detached {
- peeled: Some(peeled),
- target: *target,
- };
- Ok(peeled.attach(self.repo))
+ let id = target.attach(self.repo);
+ if id.header()?.kind() == gix_object::Kind::Commit {
+ id
+ } else {
+ match id.object()?.peel_tags_to_end() {
+ Ok(obj) => {
+ self.kind = Kind::Detached {
+ peeled: Some(obj.id),
+ target: *target,
+ };
+ obj.id()
+ }
+ Err(err) => return Err(err.into()),
}
- Err(err) => Err(err),
}
}
Kind::Symbolic(r) => {
let mut nr = r.clone().attach(self.repo);
- let peeled = nr.peel_to_id_in_place().map_err(Into::into);
+ let peeled = nr.peel_to_id_in_place();
*r = nr.detach();
- peeled
+ peeled?
}
- })
+ }))
}
- // TODO: tests
- // TODO: something similar in `crate::Reference`
/// Follow the symbolic reference of this head until its target object and peel it by following tag objects until there is no
/// more object to follow, transform the id into a commit if possible and return that.
///
/// Returns an error if the head is unborn or if it doesn't point to a commit.
- pub fn peel_to_commit_in_place(&mut self) -> Result<crate::Commit<'repo>, to_commit::Error> {
- let id = self.peel_to_id_in_place().ok_or_else(|| to_commit::Error::Unborn {
- name: self.referent_name().expect("unborn").to_owned(),
- })??;
+ pub fn peel_to_object_in_place(&mut self) -> Result<crate::Object<'repo>, to_object::Error> {
+ let id = self
+ .try_peel_to_id_in_place()?
+ .ok_or_else(|| to_object::Error::Unborn {
+ name: self.referent_name().expect("unborn").to_owned(),
+ })?;
id.object()
- .map_err(|err| to_commit::Error::Peel(Error::FindExistingObject(err)))
- .and_then(|object| object.try_into_commit().map_err(Into::into))
+ .map_err(|err| to_object::Error::Peel(Error::FindExistingObject(err)))
}
- /// Consume this instance and transform it into the final object that it points to, or `None` if the `HEAD`
- /// reference is yet to be born.
- pub fn into_fully_peeled_id(self) -> Option<Result<crate::Id<'repo>, Error>> {
- Some(match self.kind {
- Kind::Unborn(_name) => return None,
- Kind::Detached {
- peeled: Some(peeled), ..
- } => Ok(peeled.attach(self.repo)),
- Kind::Detached { peeled: None, target } => target
- .attach(self.repo)
- .object()
- .map_err(Into::into)
- .and_then(|obj| obj.peel_tags_to_end().map_err(Into::into))
- .map(|obj| obj.id.attach(self.repo)),
- Kind::Symbolic(r) => r.attach(self.repo).peel_to_id_in_place().map_err(Into::into),
- })
+ /// Follow the symbolic reference of this head until its target object and peel it by following tag objects until there is no
+ /// more object to follow, transform the id into a commit if possible and return that.
+ ///
+ /// Returns an error if the head is unborn or if it doesn't point to a commit.
+ pub fn peel_to_commit_in_place(&mut self) -> Result<crate::Commit<'repo>, to_commit::Error> {
+ Ok(self.peel_to_object_in_place()?.try_into_commit()?)
}
}