3
3
4
4
use gix_ref:: file:: ReferenceExt ;
5
5
6
- use crate :: { Id , Reference } ;
6
+ use crate :: { Blob , Commit , Id , Object , Reference , Tag , Tree } ;
7
7
8
8
pub mod iter;
9
9
///
@@ -65,19 +65,21 @@ impl<'repo> Reference<'repo> {
65
65
66
66
/// Peeling
67
67
impl < ' repo > Reference < ' repo > {
68
- /// Follow all symbolic targets this reference might point to and peel the underlying object
69
- /// to the end of the chain , and return it.
68
+ /// Follow all symbolic targets this reference might point to and peel all annotated tags
69
+ /// to their first non-tag target , and return it,
70
70
///
71
- /// This is useful to learn where this reference is ultimately pointing to.
71
+ /// This is useful to learn where this reference is ultimately pointing to after following
72
+ /// the chain of symbolic refs and annotated tags.
72
73
pub fn peel_to_id_in_place ( & mut self ) -> Result < Id < ' repo > , peel:: Error > {
73
74
let oid = self . inner . peel_to_id_in_place ( & self . repo . refs , & self . repo . objects ) ?;
74
75
Ok ( Id :: from_id ( oid, self . repo ) )
75
76
}
76
77
77
- /// Follow all symbolic targets this reference might point to and peel the underlying object
78
- /// to the end of the chain , and return it, reusing the `packed` buffer if available.
78
+ /// Follow all symbolic targets this reference might point to and peel all annotated tags
79
+ /// to their first non-tag target , and return it, reusing the `packed` buffer if available.
79
80
///
80
- /// This is useful to learn where this reference is ultimately pointing to.
81
+ /// This is useful to learn where this reference is ultimately pointing to after following
82
+ /// the chain of symbolic refs and annotated tags.
81
83
pub fn peel_to_id_in_place_packed (
82
84
& mut self ,
83
85
packed : Option < & gix_ref:: packed:: Buffer > ,
@@ -88,11 +90,69 @@ impl<'repo> Reference<'repo> {
88
90
Ok ( Id :: from_id ( oid, self . repo ) )
89
91
}
90
92
91
- /// Similar to [`peel_to_id_in_place()`][ Reference::peel_to_id_in_place()] , but consumes this instance.
93
+ /// Similar to [`peel_to_id_in_place()`]( Reference::peel_to_id_in_place()) , but consumes this instance.
92
94
pub fn into_fully_peeled_id ( mut self ) -> Result < Id < ' repo > , peel:: Error > {
93
95
self . peel_to_id_in_place ( )
94
96
}
95
97
98
+ /// Follow this reference's target until it points at an object directly, and peel that object until
99
+ /// its type matches the given `kind`. It's an error to try to peel to a kind that this ref doesn't point to.
100
+ ///
101
+ /// Note that this ref will point to the first target object afterward, which may be a tag. This is different
102
+ /// from [`peel_to_id_in_place()`](Self::peel_to_id_in_place()) where it will point to the first non-tag object.
103
+ #[ doc( alias = "peel" , alias = "git2" ) ]
104
+ pub fn peel_to_kind ( & mut self , kind : gix_object:: Kind ) -> Result < Object < ' repo > , peel:: to_kind:: Error > {
105
+ let packed = self . repo . refs . cached_packed_buffer ( ) . map_err ( |err| {
106
+ peel:: to_kind:: Error :: FollowToObject ( gix_ref:: peel:: to_object:: Error :: Follow (
107
+ file:: find:: existing:: Error :: Find ( file:: find:: Error :: PackedOpen ( err) ) ,
108
+ ) )
109
+ } ) ?;
110
+ self . peel_to_kind_packed ( kind, packed. as_ref ( ) . map ( |p| & * * * p) )
111
+ }
112
+
113
+ /// Peel this ref until the first commit.
114
+ ///
115
+ /// For details, see [`peel_to_kind`()](Self::peel_to_kind()).
116
+ pub fn peel_to_commit ( & mut self ) -> Result < Commit < ' repo > , peel:: to_kind:: Error > {
117
+ Ok ( self . peel_to_kind ( gix_object:: Kind :: Commit ) ?. into_commit ( ) )
118
+ }
119
+
120
+ /// Peel this ref until the first annotated tag.
121
+ ///
122
+ /// For details, see [`peel_to_kind`()](Self::peel_to_kind()).
123
+ pub fn peel_to_tag ( & mut self ) -> Result < Tag < ' repo > , peel:: to_kind:: Error > {
124
+ Ok ( self . peel_to_kind ( gix_object:: Kind :: Tag ) ?. into_tag ( ) )
125
+ }
126
+
127
+ /// Peel this ref until the first tree.
128
+ ///
129
+ /// For details, see [`peel_to_kind`()](Self::peel_to_kind()).
130
+ pub fn peel_to_tree ( & mut self ) -> Result < Tree < ' repo > , peel:: to_kind:: Error > {
131
+ Ok ( self . peel_to_kind ( gix_object:: Kind :: Tree ) ?. into_tree ( ) )
132
+ }
133
+
134
+ /// Peel this ref until it points to a blob. Note that this is highly uncommon to happen
135
+ /// as it would require an annotated tag to point to a blob, instead of a commit.
136
+ ///
137
+ /// For details, see [`peel_to_kind`()](Self::peel_to_kind()).
138
+ pub fn peel_to_blob ( & mut self ) -> Result < Blob < ' repo > , peel:: to_kind:: Error > {
139
+ Ok ( self . peel_to_kind ( gix_object:: Kind :: Blob ) ?. into_blob ( ) )
140
+ }
141
+
142
+ /// Like [`peel_to_kind()`](Self::peel_to_kind), but allows to provide `packed` for best possible performance
143
+ /// when peeling many refs.
144
+ pub fn peel_to_kind_packed (
145
+ & mut self ,
146
+ kind : gix_object:: Kind ,
147
+ packed : Option < & gix_ref:: packed:: Buffer > ,
148
+ ) -> Result < Object < ' repo > , peel:: to_kind:: Error > {
149
+ let target = self
150
+ . inner
151
+ . follow_to_object_in_place_packed ( & self . repo . refs , packed) ?
152
+ . attach ( self . repo ) ;
153
+ Ok ( target. object ( ) ?. peel_to_kind ( kind) ?)
154
+ }
155
+
96
156
/// Follow this symbolic reference one level and return the ref it refers to.
97
157
///
98
158
/// Returns `None` if this is not a symbolic reference, hence the leaf of the chain.
@@ -108,3 +168,4 @@ impl<'repo> Reference<'repo> {
108
168
109
169
mod edits;
110
170
pub use edits:: { delete, set_target_id} ;
171
+ use gix_ref:: file;
0 commit comments