1
+ use gix_object:: bstr:: ByteSlice ;
2
+ use gix_path:: RelativePath ;
1
3
use std:: {
2
4
borrow:: Cow ,
3
5
cmp:: Ordering ,
@@ -6,11 +8,8 @@ use std::{
6
8
path:: { Path , PathBuf } ,
7
9
} ;
8
10
9
- use gix_object:: bstr:: ByteSlice ;
10
- use gix_path:: RelativePath ;
11
-
12
11
use crate :: {
13
- file:: { loose, loose :: iter:: SortedLoosePaths } ,
12
+ file:: loose:: { self , iter:: SortedLoosePaths } ,
14
13
store_impl:: { file, packed} ,
15
14
BStr , FullName , Namespace , Reference ,
16
15
} ;
@@ -85,25 +84,25 @@ impl<'p> LooseThenPacked<'p, '_> {
85
84
}
86
85
87
86
fn convert_loose ( & mut self , res : std:: io:: Result < ( PathBuf , FullName ) > ) -> Result < Reference , Error > {
87
+ let buf = & mut self . buf ;
88
+ let git_dir = self . git_dir ;
89
+ let common_dir = self . common_dir ;
88
90
let ( refpath, name) = res. map_err ( Error :: Traversal ) ?;
89
91
std:: fs:: File :: open ( & refpath)
90
92
. and_then ( |mut f| {
91
- self . buf . clear ( ) ;
92
- f. read_to_end ( & mut self . buf )
93
+ buf. clear ( ) ;
94
+ f. read_to_end ( buf)
93
95
} )
94
96
. map_err ( |err| Error :: ReadFileContents {
95
97
source : err,
96
98
path : refpath. to_owned ( ) ,
97
99
} ) ?;
98
- loose:: Reference :: try_from_path ( name, & self . buf )
100
+ loose:: Reference :: try_from_path ( name, buf)
99
101
. map_err ( |err| {
100
102
let relative_path = refpath
101
- . strip_prefix ( self . git_dir )
103
+ . strip_prefix ( git_dir)
102
104
. ok ( )
103
- . or_else ( || {
104
- self . common_dir
105
- . and_then ( |common_dir| refpath. strip_prefix ( common_dir) . ok ( ) )
106
- } )
105
+ . or_else ( || common_dir. and_then ( |common_dir| refpath. strip_prefix ( common_dir) . ok ( ) ) )
107
106
. expect ( "one of our bases contains the path" ) ;
108
107
Error :: ReferenceCreation {
109
108
source : err,
@@ -191,9 +190,9 @@ impl Iterator for LooseThenPacked<'_, '_> {
191
190
}
192
191
193
192
impl Platform < ' _ > {
194
- /// Return an iterator over all references, loose or ` packed` , sorted by their name.
193
+ /// Return an iterator over all references, loose or packed, sorted by their name.
195
194
///
196
- /// Errors are returned similarly to what would happen when loose and packed refs where iterated by themselves.
195
+ /// Errors are returned similarly to what would happen when loose and packed refs were iterated by themselves.
197
196
pub fn all ( & self ) -> std:: io:: Result < LooseThenPacked < ' _ , ' _ > > {
198
197
self . store . iter_packed ( self . packed . as_ref ( ) . map ( |b| & * * * b) )
199
198
}
@@ -210,12 +209,18 @@ impl Platform<'_> {
210
209
self . store
211
210
. iter_prefixed_packed ( prefix, self . packed . as_ref ( ) . map ( |b| & * * * b) )
212
211
}
212
+
213
+ /// Return an iterator over the pseudo references, like `HEAD` or `FETCH_HEAD`, or anything else suffixed with `HEAD`
214
+ /// in the root of the `.git` directory, sorted by name.
215
+ pub fn pseudo ( & self ) -> std:: io:: Result < LooseThenPacked < ' _ , ' _ > > {
216
+ self . store . iter_pseudo ( )
217
+ }
213
218
}
214
219
215
220
impl file:: Store {
216
221
/// Return a platform to obtain iterator over all references, or prefixed ones, loose or packed, sorted by their name.
217
222
///
218
- /// Errors are returned similarly to what would happen when loose and packed refs where iterated by themselves.
223
+ /// Errors are returned similarly to what would happen when loose and packed refs were iterated by themselves.
219
224
///
220
225
/// Note that since packed-refs are storing refs as precomposed unicode if [`Self::precompose_unicode`] is true, for consistency
221
226
/// we also return loose references as precomposed unicode.
@@ -254,6 +259,10 @@ pub(crate) enum IterInfo<'a> {
254
259
/// If `true`, we will convert decomposed into precomposed unicode.
255
260
precompose_unicode : bool ,
256
261
} ,
262
+ Pseudo {
263
+ base : & ' a Path ,
264
+ precompose_unicode : bool ,
265
+ } ,
257
266
}
258
267
259
268
impl < ' a > IterInfo < ' a > {
@@ -263,6 +272,7 @@ impl<'a> IterInfo<'a> {
263
272
IterInfo :: PrefixAndBase { prefix, .. } => Some ( gix_path:: into_bstr ( * prefix) ) ,
264
273
IterInfo :: BaseAndIterRoot { prefix, .. } => Some ( gix_path:: into_bstr ( prefix. clone ( ) ) ) ,
265
274
IterInfo :: ComputedIterationRoot { prefix, .. } => Some ( prefix. clone ( ) ) ,
275
+ IterInfo :: Pseudo { .. } => None ,
266
276
}
267
277
}
268
278
@@ -271,24 +281,34 @@ impl<'a> IterInfo<'a> {
271
281
IterInfo :: Base {
272
282
base,
273
283
precompose_unicode,
274
- } => SortedLoosePaths :: at ( & base. join ( "refs" ) , base. into ( ) , None , precompose_unicode) ,
284
+ } => SortedLoosePaths :: at ( & base. join ( "refs" ) , base. into ( ) , None , None , precompose_unicode) ,
275
285
IterInfo :: BaseAndIterRoot {
276
286
base,
277
287
iter_root,
278
288
prefix : _,
279
289
precompose_unicode,
280
- } => SortedLoosePaths :: at ( & iter_root, base. into ( ) , None , precompose_unicode) ,
290
+ } => SortedLoosePaths :: at ( & iter_root, base. into ( ) , None , None , precompose_unicode) ,
281
291
IterInfo :: PrefixAndBase {
282
292
base,
283
293
prefix,
284
294
precompose_unicode,
285
- } => SortedLoosePaths :: at ( & base. join ( prefix) , base. into ( ) , None , precompose_unicode) ,
295
+ } => SortedLoosePaths :: at ( & base. join ( prefix) , base. into ( ) , None , None , precompose_unicode) ,
286
296
IterInfo :: ComputedIterationRoot {
287
297
iter_root,
288
298
base,
289
299
prefix,
290
300
precompose_unicode,
291
- } => SortedLoosePaths :: at ( & iter_root, base. into ( ) , Some ( prefix. into_owned ( ) ) , precompose_unicode) ,
301
+ } => SortedLoosePaths :: at (
302
+ & iter_root,
303
+ base. into ( ) ,
304
+ Some ( prefix. into_owned ( ) ) ,
305
+ None ,
306
+ precompose_unicode,
307
+ ) ,
308
+ IterInfo :: Pseudo {
309
+ base,
310
+ precompose_unicode,
311
+ } => SortedLoosePaths :: at ( base, base. into ( ) , None , Some ( "HEAD" . into ( ) ) , precompose_unicode) ,
292
312
}
293
313
. peekable ( )
294
314
}
@@ -321,7 +341,7 @@ impl<'a> IterInfo<'a> {
321
341
impl file:: Store {
322
342
/// Return an iterator over all references, loose or `packed`, sorted by their name.
323
343
///
324
- /// Errors are returned similarly to what would happen when loose and packed refs where iterated by themselves.
344
+ /// Errors are returned similarly to what would happen when loose and packed refs were iterated by themselves.
325
345
pub fn iter_packed < ' s , ' p > (
326
346
& ' s self ,
327
347
packed : Option < & ' p packed:: Buffer > ,
@@ -354,6 +374,21 @@ impl file::Store {
354
374
}
355
375
}
356
376
377
+ /// Return an iterator over the pseudo references, like `HEAD` or `FETCH_HEAD`, or anything else suffixed with `HEAD`
378
+ /// in the root of the `.git` directory, sorted by name.
379
+ ///
380
+ /// Errors are returned similarly to what would happen when loose refs were iterated by themselves.
381
+ pub fn iter_pseudo < ' p > ( & ' _ self ) -> std:: io:: Result < LooseThenPacked < ' p , ' _ > > {
382
+ self . iter_from_info (
383
+ IterInfo :: Pseudo {
384
+ base : self . git_dir ( ) ,
385
+ precompose_unicode : self . precompose_unicode ,
386
+ } ,
387
+ None ,
388
+ None ,
389
+ )
390
+ }
391
+
357
392
/// As [`iter(…)`](file::Store::iter()), but filters by `prefix`, i.e. `refs/heads/` or
358
393
/// `refs/heads/feature-`.
359
394
/// Note that if a prefix isn't using a trailing `/`, like in `refs/heads/foo`, it will effectively
0 commit comments