1+ use gix_object:: bstr:: ByteSlice ;
2+ use gix_path:: RelativePath ;
13use std:: {
24 borrow:: Cow ,
35 cmp:: Ordering ,
@@ -6,11 +8,8 @@ use std::{
68 path:: { Path , PathBuf } ,
79} ;
810
9- use gix_object:: bstr:: ByteSlice ;
10- use gix_path:: RelativePath ;
11-
1211use crate :: {
13- file:: { loose, loose :: iter:: SortedLoosePaths } ,
12+ file:: loose:: { self , iter:: SortedLoosePaths } ,
1413 store_impl:: { file, packed} ,
1514 BStr , FullName , Namespace , Reference ,
1615} ;
@@ -85,25 +84,25 @@ impl<'p> LooseThenPacked<'p, '_> {
8584 }
8685
8786 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 ;
8890 let ( refpath, name) = res. map_err ( Error :: Traversal ) ?;
8991 std:: fs:: File :: open ( & refpath)
9092 . 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)
9395 } )
9496 . map_err ( |err| Error :: ReadFileContents {
9597 source : err,
9698 path : refpath. to_owned ( ) ,
9799 } ) ?;
98- loose:: Reference :: try_from_path ( name, & self . buf )
100+ loose:: Reference :: try_from_path ( name, buf)
99101 . map_err ( |err| {
100102 let relative_path = refpath
101- . strip_prefix ( self . git_dir )
103+ . strip_prefix ( git_dir)
102104 . 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 ( ) ) )
107106 . expect ( "one of our bases contains the path" ) ;
108107 Error :: ReferenceCreation {
109108 source : err,
@@ -191,9 +190,9 @@ impl Iterator for LooseThenPacked<'_, '_> {
191190}
192191
193192impl 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.
195194 ///
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.
197196 pub fn all ( & self ) -> std:: io:: Result < LooseThenPacked < ' _ , ' _ > > {
198197 self . store . iter_packed ( self . packed . as_ref ( ) . map ( |b| & * * * b) )
199198 }
@@ -210,12 +209,18 @@ impl Platform<'_> {
210209 self . store
211210 . iter_prefixed_packed ( prefix, self . packed . as_ref ( ) . map ( |b| & * * * b) )
212211 }
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+ }
213218}
214219
215220impl file:: Store {
216221 /// Return a platform to obtain iterator over all references, or prefixed ones, loose or packed, sorted by their name.
217222 ///
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.
219224 ///
220225 /// Note that since packed-refs are storing refs as precomposed unicode if [`Self::precompose_unicode`] is true, for consistency
221226 /// we also return loose references as precomposed unicode.
@@ -254,6 +259,10 @@ pub(crate) enum IterInfo<'a> {
254259 /// If `true`, we will convert decomposed into precomposed unicode.
255260 precompose_unicode : bool ,
256261 } ,
262+ Pseudo {
263+ base : & ' a Path ,
264+ precompose_unicode : bool ,
265+ } ,
257266}
258267
259268impl < ' a > IterInfo < ' a > {
@@ -263,6 +272,7 @@ impl<'a> IterInfo<'a> {
263272 IterInfo :: PrefixAndBase { prefix, .. } => Some ( gix_path:: into_bstr ( * prefix) ) ,
264273 IterInfo :: BaseAndIterRoot { prefix, .. } => Some ( gix_path:: into_bstr ( prefix. clone ( ) ) ) ,
265274 IterInfo :: ComputedIterationRoot { prefix, .. } => Some ( prefix. clone ( ) ) ,
275+ IterInfo :: Pseudo { .. } => None ,
266276 }
267277 }
268278
@@ -271,24 +281,34 @@ impl<'a> IterInfo<'a> {
271281 IterInfo :: Base {
272282 base,
273283 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) ,
275285 IterInfo :: BaseAndIterRoot {
276286 base,
277287 iter_root,
278288 prefix : _,
279289 precompose_unicode,
280- } => SortedLoosePaths :: at ( & iter_root, base. into ( ) , None , precompose_unicode) ,
290+ } => SortedLoosePaths :: at ( & iter_root, base. into ( ) , None , None , precompose_unicode) ,
281291 IterInfo :: PrefixAndBase {
282292 base,
283293 prefix,
284294 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) ,
286296 IterInfo :: ComputedIterationRoot {
287297 iter_root,
288298 base,
289299 prefix,
290300 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) ,
292312 }
293313 . peekable ( )
294314 }
@@ -321,7 +341,7 @@ impl<'a> IterInfo<'a> {
321341impl file:: Store {
322342 /// Return an iterator over all references, loose or `packed`, sorted by their name.
323343 ///
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.
325345 pub fn iter_packed < ' s , ' p > (
326346 & ' s self ,
327347 packed : Option < & ' p packed:: Buffer > ,
@@ -354,6 +374,21 @@ impl file::Store {
354374 }
355375 }
356376
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+
357392 /// As [`iter(…)`](file::Store::iter()), but filters by `prefix`, i.e. `refs/heads/` or
358393 /// `refs/heads/feature-`.
359394 /// Note that if a prefix isn't using a trailing `/`, like in `refs/heads/foo`, it will effectively
0 commit comments