1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use crate::{
Error, Head, Result,
ext::{ObjectIdExt, ReferenceExt},
head::Kind,
};
impl<'repo> Head<'repo> {
/// 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>> {
self.try_peel_to_id()?;
self.id().ok_or_else(|| match self.kind {
Kind::Symbolic(gix_ref::Reference { name, .. }) | Kind::Unborn(name) => {
gix_error::message!("Branch '{name}' does not have any commits").not_found_error()
}
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>> {
self.peel_to_object()
}
/// 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>>> {
self.try_peel_to_id()
}
/// 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 `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.
#[deprecated = "Use `try_peel_to_id()` instead"]
pub fn try_peel_to_id_in_place(&mut self) -> Result<Option<crate::Id<'repo>>> {
self.try_peel_to_id()
}
/// 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 `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.
///
/// Note that this method mutates `self` in place.
pub fn try_peel_to_id(&mut self) -> Result<Option<crate::Id<'repo>>> {
Ok(Some(match &mut self.kind {
Kind::Unborn(_name) => return Ok(None),
Kind::Detached {
peeled: Some(peeled), ..
} => (*peeled).attach(self.repo),
Kind::Detached { peeled: None, target } => {
let id = target.attach(self.repo);
if id.header()?.kind() == gix_object::Kind::Commit {
id
} else {
{
let obj = id.object()?.peel_tags_to_end()?;
self.kind = Kind::Detached {
peeled: Some(obj.id),
target: *target,
};
obj.id()
}
}
}
Kind::Symbolic(r) => {
let mut nr = r.clone().attach(self.repo);
let peeled = nr.peel_to_id();
*r = nr.detach();
peeled?
}
}))
}
/// 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.
#[deprecated = "Use `peel_to_object()` instead"]
pub fn peel_to_object_in_place(&mut self) -> Result<crate::Object<'repo>> {
self.peel_to_object()
}
/// 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.
///
/// Note that this method mutates `self` in place.
pub fn peel_to_object(&mut self) -> Result<crate::Object<'repo>> {
let id = self.try_peel_to_id()?.ok_or_else(|| {
Error::from_error(gix_error::not_found(format!(
"Branch '{}' does not have any commits",
self.referent_name().expect("unborn")
)))
})?;
id.object()
}
/// 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.
#[deprecated = "Use `peel_to_commit()` instead"]
pub fn peel_to_commit_in_place(&mut self) -> Result<crate::Commit<'repo>> {
self.peel_to_commit()
}
/// 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.
///
/// Note that this method mutates `self` in place.
pub fn peel_to_commit(&mut self) -> Result<crate::Commit<'repo>> {
self.peel_to_object()?.try_into_commit()
}
}