diff --git a/git-repository/src/easy/head.rs b/git-repository/src/easy/head.rs index 4cb699ba4c5..228fd7ef859 100644 --- a/git-repository/src/easy/head.rs +++ b/git-repository/src/easy/head.rs @@ -135,7 +135,7 @@ pub mod peel { .attach(self.access) .object() .map_err(Into::into) - .and_then(|obj| obj.peel_to_end().map_err(Into::into)) + .and_then(|obj| obj.peel_tags_to_end().map_err(Into::into)) .map(|peeled| peeled.id) { Ok(peeled) => { @@ -169,7 +169,7 @@ pub mod peel { .attach(self.access) .object() .map_err(Into::into) - .and_then(|obj| obj.peel_to_end().map_err(Into::into)) + .and_then(|obj| obj.peel_tags_to_end().map_err(Into::into)) .map(|obj| obj.id.attach(self.access)), Kind::Symbolic(r) => r.attach(self.access).peel_to_id_in_place().map_err(Into::into), }) diff --git a/git-repository/src/easy/object/mod.rs b/git-repository/src/easy/object/mod.rs index f64d90b62e6..4fae95da7c5 100644 --- a/git-repository/src/easy/object/mod.rs +++ b/git-repository/src/easy/object/mod.rs @@ -14,7 +14,6 @@ mod errors; mod impls; mod tree; pub use errors::{find, write}; - pub mod peel; impl Object { @@ -95,7 +94,7 @@ impl<'repo, A> ObjectRef<'repo, A> where A: easy::Access + Sized, { - /// Obtain a an iterator over commit tokens like in [`to_commit_iter()`][ObjectRef::to_commit_iter()], but panic if this is not a commit. + /// Obtain a an iterator over commit tokens like in [`to_commit_iter()`][ObjectRef::try_to_commit_iter()], but panic if this is not a commit. pub fn commit_iter(&self) -> CommitRefIter<'_> { git_odb::data::Object::new(self.kind, &self.data) .try_into_commit_iter() @@ -107,6 +106,13 @@ where git_odb::data::Object::new(self.kind, &self.data).try_into_commit_iter() } + /// Obtain a tag token iterator from the data in this instance, or panic if it is not a tag + pub fn tag_iter(&self) -> TagRefIter<'_> { + git_odb::data::Object::new(self.kind, &self.data) + .try_into_tag_iter() + .expect("BUG: this object must be a tag") + } + /// Obtain a tag token iterator from the data in this instance, if it is a tag. pub fn try_to_tag_iter(&self) -> Option> { git_odb::data::Object::new(self.kind, &self.data).try_into_tag_iter() diff --git a/git-repository/src/easy/object/peel.rs b/git-repository/src/easy/object/peel.rs index 224e2cbb428..567ca0f683c 100644 --- a/git-repository/src/easy/object/peel.rs +++ b/git-repository/src/easy/object/peel.rs @@ -1,4 +1,4 @@ -#![allow(missing_docs)] +//! use crate::{ easy, easy::{ @@ -9,12 +9,15 @@ use crate::{ }, }; +/// pub mod to_kind { mod error { use crate::easy::object; + /// The error returned by [`Object::peel_to_kind()`][crate::easy::ObjectRef::peel_to_kind()]. #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] pub enum Error { #[error(transparent)] FindExistingObject(#[from] object::find::existing::Error), @@ -33,6 +36,10 @@ where A: easy::Access + Sized, { // TODO: tests + /// Follow tags to their target and commits to trees until the given `kind` of object is encountered. + /// + /// Note that this object doesn't necessarily have to be the end of the chain. + /// Typical values are [`Kind::Commit`] or [`Kind::Tree`]. pub fn peel_to_kind(mut self, kind: Kind) -> Result { loop { match self.kind { @@ -50,7 +57,7 @@ where self = access.find_object(tree_id)?; } Kind::Tag => { - let target_id = self.try_to_tag_iter().expect("tag").target_id().expect("valid tag"); + let target_id = self.tag_iter().target_id().expect("valid tag"); let access = self.access; drop(self); self = access.find_object(target_id)?; @@ -66,12 +73,16 @@ where } // TODO: tests - pub fn peel_to_end(mut self) -> Result { + /// Follow all tag object targets until a commit, tree or blob is reached. + /// + /// Note that this method is different from [`peel_to_kind(…)`][ObjectRef::peel_to_kind()] as it won't + /// peel commits to their tree, but handles tags only. + pub fn peel_tags_to_end(mut self) -> Result { loop { match self.kind { Kind::Commit | Kind::Tree | Kind::Blob => break Ok(self), Kind::Tag => { - let target_id = self.try_to_tag_iter().expect("tag").target_id().expect("valid tag"); + let target_id = self.tag_iter().target_id().expect("valid tag"); let access = self.access; drop(self); self = access.find_object(target_id)?;