@@ -7,9 +7,9 @@ use std::{
77} ;
88
99use crate :: {
10- file:: { loose, loose:: iter:: SortedLoosePaths , path_to_name } ,
10+ file:: { loose, loose:: iter:: SortedLoosePaths } ,
1111 store_impl:: { file, packed} ,
12- BString , FullName , Namespace , Reference ,
12+ BStr , FullName , Namespace , Reference ,
1313} ;
1414
1515/// An iterator stepping through sorted input of loose references and packed references, preferring loose refs over otherwise
@@ -195,10 +195,9 @@ impl Platform<'_> {
195195 self . store . iter_packed ( self . packed . as_ref ( ) . map ( |b| & * * * b) )
196196 }
197197
198- /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads".
199- ///
200- /// Please note that "refs/heads" or "refs\\heads" is equivalent to "refs/heads/"
201- pub fn prefixed ( & self , prefix : & Path ) -> std:: io:: Result < LooseThenPacked < ' _ , ' _ > > {
198+ /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads/" or
199+ /// "refs/heads/feature-".
200+ pub fn prefixed ( & self , prefix : Cow < ' _ , BStr > ) -> std:: io:: Result < LooseThenPacked < ' _ , ' _ > > {
202201 self . store
203202 . iter_prefixed_packed ( prefix, self . packed . as_ref ( ) . map ( |b| & * * * b) )
204203 }
@@ -242,22 +241,19 @@ pub(crate) enum IterInfo<'a> {
242241 /// The top-level directory as boundary of all references, used to create their short-names after iteration
243242 base : & ' a Path ,
244243 /// The original prefix
245- prefix : Cow < ' a , Path > ,
246- /// The remainder of the prefix that wasn't a valid path
247- remainder : Option < BString > ,
244+ prefix : Cow < ' a , BStr > ,
248245 /// If `true`, we will convert decomposed into precomposed unicode.
249246 precompose_unicode : bool ,
250247 } ,
251248}
252249
253250impl < ' a > IterInfo < ' a > {
254- fn prefix ( & self ) -> Option < & Path > {
251+ fn prefix ( & self ) -> Option < Cow < ' _ , BStr > > {
255252 match self {
256253 IterInfo :: Base { .. } => None ,
257- IterInfo :: PrefixAndBase { prefix, .. } => Some ( * prefix) ,
258- IterInfo :: ComputedIterationRoot { prefix, .. } | IterInfo :: BaseAndIterRoot { prefix, .. } => {
259- prefix. as_ref ( ) . into ( )
260- }
254+ IterInfo :: PrefixAndBase { prefix, .. } => Some ( gix_path:: into_bstr ( * prefix) ) ,
255+ IterInfo :: BaseAndIterRoot { prefix, .. } => Some ( gix_path:: into_bstr ( prefix. clone ( ) ) ) ,
256+ IterInfo :: ComputedIterationRoot { prefix, .. } => Some ( prefix. clone ( ) ) ,
261257 }
262258 }
263259
@@ -281,48 +277,37 @@ impl<'a> IterInfo<'a> {
281277 IterInfo :: ComputedIterationRoot {
282278 iter_root,
283279 base,
284- prefix : _,
285- remainder,
280+ prefix,
286281 precompose_unicode,
287- } => SortedLoosePaths :: at ( & iter_root, base. into ( ) , remainder , precompose_unicode) ,
282+ } => SortedLoosePaths :: at ( & iter_root, base. into ( ) , Some ( prefix . into_owned ( ) ) , precompose_unicode) ,
288283 }
289284 . peekable ( )
290285 }
291286
292- fn from_prefix ( base : & ' a Path , prefix : Cow < ' a , Path > , precompose_unicode : bool ) -> std:: io:: Result < Self > {
293- if prefix. is_absolute ( ) {
287+ fn from_prefix ( base : & ' a Path , prefix : Cow < ' a , BStr > , precompose_unicode : bool ) -> std:: io:: Result < Self > {
288+ let prefix_path = gix_path:: from_bstring ( prefix. as_ref ( ) ) ;
289+ if prefix_path. is_absolute ( ) {
294290 return Err ( std:: io:: Error :: new (
295291 std:: io:: ErrorKind :: InvalidInput ,
296- "prefix must be a relative path, like 'refs/heads'" ,
292+ "prefix must be a relative path, like 'refs/heads/ '" ,
297293 ) ) ;
298294 }
299295 use std:: path:: Component :: * ;
300- if prefix . components ( ) . any ( |c| matches ! ( c, CurDir | ParentDir ) ) {
296+ if prefix_path . components ( ) . any ( |c| matches ! ( c, CurDir | ParentDir ) ) {
301297 return Err ( std:: io:: Error :: new (
302298 std:: io:: ErrorKind :: InvalidInput ,
303299 "Refusing to handle prefixes with relative path components" ,
304300 ) ) ;
305301 }
306- let iter_root = base. join ( prefix . as_ref ( ) ) ;
307- if iter_root . is_dir ( ) {
302+ let iter_root = base. join ( & prefix_path ) ;
303+ if prefix . ends_with ( b"/" ) {
308304 Ok ( IterInfo :: BaseAndIterRoot {
309305 base,
310306 iter_root,
311- prefix,
307+ prefix : prefix_path . into ( ) ,
312308 precompose_unicode,
313309 } )
314310 } else {
315- let filename_prefix = iter_root
316- . file_name ( )
317- . map ( ToOwned :: to_owned)
318- . map ( |p| {
319- gix_path:: try_into_bstr ( PathBuf :: from ( p) )
320- . map ( std:: borrow:: Cow :: into_owned)
321- . map_err ( |_| {
322- std:: io:: Error :: new ( std:: io:: ErrorKind :: InvalidInput , "prefix contains ill-formed UTF-8" )
323- } )
324- } )
325- . transpose ( ) ?;
326311 let iter_root = iter_root
327312 . parent ( )
328313 . expect ( "a parent is always there unless empty" )
@@ -331,7 +316,6 @@ impl<'a> IterInfo<'a> {
331316 base,
332317 prefix,
333318 iter_root,
334- remainder : filename_prefix,
335319 precompose_unicode,
336320 } )
337321 }
@@ -374,30 +358,28 @@ impl file::Store {
374358 }
375359 }
376360
377- /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads".
378- ///
379- /// Please note that "refs/heads" or "refs\\heads" is equivalent to "refs/heads/"
361+ /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads/" or
362+ /// "refs/heads/feature-".
380363 pub fn iter_prefixed_packed < ' s , ' p > (
381364 & ' s self ,
382- prefix : & Path ,
365+ prefix : Cow < ' _ , BStr > ,
383366 packed : Option < & ' p packed:: Buffer > ,
384367 ) -> std:: io:: Result < LooseThenPacked < ' p , ' s > > {
385368 match self . namespace . as_ref ( ) {
386369 None => {
387- let git_dir_info = IterInfo :: from_prefix ( self . git_dir ( ) , prefix. into ( ) , self . precompose_unicode ) ?;
370+ let git_dir_info = IterInfo :: from_prefix ( self . git_dir ( ) , prefix. clone ( ) , self . precompose_unicode ) ?;
388371 let common_dir_info = self
389372 . common_dir ( )
390- . map ( |base| IterInfo :: from_prefix ( base, prefix. into ( ) , self . precompose_unicode ) )
373+ . map ( |base| IterInfo :: from_prefix ( base, prefix, self . precompose_unicode ) )
391374 . transpose ( ) ?;
392375 self . iter_from_info ( git_dir_info, common_dir_info, packed)
393376 }
394377 Some ( namespace) => {
395- let prefix = namespace. to_owned ( ) . into_namespaced_prefix ( prefix) ;
396- let git_dir_info =
397- IterInfo :: from_prefix ( self . git_dir ( ) , prefix. clone ( ) . into ( ) , self . precompose_unicode ) ?;
378+ let prefix = namespace. to_owned ( ) . into_namespaced_prefix ( prefix. as_ref ( ) ) ;
379+ let git_dir_info = IterInfo :: from_prefix ( self . git_dir ( ) , prefix. clone ( ) , self . precompose_unicode ) ?;
398380 let common_dir_info = self
399381 . common_dir ( )
400- . map ( |base| IterInfo :: from_prefix ( base, prefix. into ( ) , self . precompose_unicode ) )
382+ . map ( |base| IterInfo :: from_prefix ( base, prefix, self . precompose_unicode ) )
401383 . transpose ( ) ?;
402384 self . iter_from_info ( git_dir_info, common_dir_info, packed)
403385 }
@@ -416,7 +398,7 @@ impl file::Store {
416398 iter_packed : match packed {
417399 Some ( packed) => Some (
418400 match git_dir_info. prefix ( ) {
419- Some ( prefix) => packed. iter_prefixed ( path_to_name ( prefix) . into_owned ( ) ) ,
401+ Some ( prefix) => packed. iter_prefixed ( prefix. into_owned ( ) ) ,
420402 None => packed. iter ( ) ,
421403 }
422404 . map_err ( |err| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , err) ) ?
0 commit comments