Skip to content

Commit 117357e

Browse files
committed
feat: add Head::try_into_peeled_object() and Head::peel_to_object_in_place()
This makes it easier to peel to a specific object type, after all tags have been followed, without having to assume an intermediate commit.
1 parent 4e6a4e6 commit 117357e

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed

gix/src/head/peel.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,32 @@ pub mod into_id {
4242
pub mod to_commit {
4343
use crate::object;
4444

45-
/// The error returned by [`Head::peel_to_commit_in_place()`][super::Head::peel_to_commit_in_place()].
45+
/// The error returned by [`Head::peel_to_commit_in_place()`](super::Head::peel_to_commit_in_place()).
46+
#[derive(Debug, thiserror::Error)]
47+
#[allow(missing_docs)]
48+
pub enum Error {
49+
#[error(transparent)]
50+
PeelToObject(#[from] super::to_object::Error),
51+
#[error(transparent)]
52+
ObjectKind(#[from] object::try_into::Error),
53+
}
54+
}
55+
56+
///
57+
pub mod to_object {
58+
/// The error returned by [`Head::peel_to_object_in_place()`](super::Head::peel_to_object_in_place()).
4659
#[derive(Debug, thiserror::Error)]
4760
#[allow(missing_docs)]
4861
pub enum Error {
4962
#[error(transparent)]
5063
Peel(#[from] super::Error),
5164
#[error("Branch '{name}' does not have any commits")]
5265
Unborn { name: gix_ref::FullName },
53-
#[error(transparent)]
54-
ObjectKind(#[from] object::try_into::Error),
5566
}
5667
}
5768

5869
impl<'repo> Head<'repo> {
59-
/// Peel this instance and consume to make obtaining its final target id possible, while returning an error on unborn heads.
70+
/// Peel this instance and consume it to make obtaining its final target id possible, while returning an error on unborn heads.
6071
///
6172
/// The final target is obtained by following symbolic references and peeling tags to their final destination, which
6273
/// typically is a commit, but can be any object.
@@ -68,6 +79,14 @@ impl<'repo> Head<'repo> {
6879
})
6980
}
7081

82+
/// Peel this instance and consume it to make obtaining its final target object possible, while returning an error on unborn heads.
83+
///
84+
/// The final target is obtained by following symbolic references and peeling tags to their final destination, which
85+
/// typically is a commit, but can be any object as well.
86+
pub fn into_peeled_object(mut self) -> Result<crate::Object<'repo>, to_object::Error> {
87+
self.peel_to_object_in_place()
88+
}
89+
7190
/// Consume this instance and transform it into the final object that it points to, or `Ok(None)` if the `HEAD`
7291
/// reference is yet to be born.
7392
///
@@ -120,15 +139,21 @@ impl<'repo> Head<'repo> {
120139
/// more object to follow, transform the id into a commit if possible and return that.
121140
///
122141
/// Returns an error if the head is unborn or if it doesn't point to a commit.
123-
pub fn peel_to_commit_in_place(&mut self) -> Result<crate::Commit<'repo>, to_commit::Error> {
142+
pub fn peel_to_object_in_place(&mut self) -> Result<crate::Object<'repo>, to_object::Error> {
124143
let id = self
125144
.try_peel_to_id_in_place()?
126-
.ok_or_else(|| to_commit::Error::Unborn {
145+
.ok_or_else(|| to_object::Error::Unborn {
127146
name: self.referent_name().expect("unborn").to_owned(),
128147
})?;
129-
Ok(id
130-
.object()
131-
.map_err(|err| to_commit::Error::Peel(Error::FindExistingObject(err)))?
132-
.try_into_commit()?)
148+
id.object()
149+
.map_err(|err| to_object::Error::Peel(Error::FindExistingObject(err)))
150+
}
151+
152+
/// Follow the symbolic reference of this head until its target object and peel it by following tag objects until there is no
153+
/// more object to follow, transform the id into a commit if possible and return that.
154+
///
155+
/// Returns an error if the head is unborn or if it doesn't point to a commit.
156+
pub fn peel_to_commit_in_place(&mut self) -> Result<crate::Commit<'repo>, to_commit::Error> {
157+
Ok(self.peel_to_object_in_place()?.try_into_commit()?)
133158
}
134159
}

gix/src/reference/errors.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ pub mod head_tree_id {
6767
#[allow(missing_docs)]
6868
pub enum Error {
6969
#[error(transparent)]
70-
Head(#[from] crate::reference::find::existing::Error),
71-
#[error(transparent)]
72-
PeelToCommit(#[from] crate::head::peel::to_commit::Error),
70+
HeadCommit(#[from] crate::reference::head_commit::Error),
7371
#[error(transparent)]
7472
DecodeCommit(#[from] gix_object::decode::Error),
7573
}

gix/src/repository/reference.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ impl crate::Repository {
216216
/// is freshly initialized and doesn't have any commits yet. It could also fail if the
217217
/// head does not point to a commit.
218218
pub fn head_tree_id(&self) -> Result<crate::Id<'_>, reference::head_tree_id::Error> {
219-
Ok(self.head()?.peel_to_commit_in_place()?.tree_id()?)
219+
Ok(self.head_commit()?.tree_id()?)
220220
}
221221

222222
/// Find the reference with the given partial or full `name`, like `main`, `HEAD`, `heads/branch` or `origin/other`,

gix/tests/head/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ mod peel {
77
for name in ["detached", "symbolic", "tag-detached", "tag-symbolic"] {
88
let repo = named_subrepo_opts("make_head_repos.sh", name, gix::open::Options::isolated())?;
99
assert_eq!(repo.head()?.into_peeled_id()?, expected_commit);
10+
assert_eq!(repo.head()?.into_peeled_object()?.id, expected_commit);
1011
assert_eq!(repo.head_id()?, expected_commit);
1112
let commit = repo.head_commit()?;
1213
assert_eq!(commit.id, expected_commit);
1314
assert_eq!(repo.head_tree_id()?, commit.tree_id()?);
1415
assert_eq!(repo.head()?.try_into_peeled_id()?.expect("born"), expected_commit);
16+
assert_eq!(repo.head()?.peel_to_object_in_place()?.id, expected_commit);
1517
assert_eq!(repo.head()?.try_peel_to_id_in_place()?.expect("born"), expected_commit);
1618
}
1719
Ok(())

0 commit comments

Comments
 (0)