@@ -20,8 +20,8 @@ use super::prune::PruneParameters;
2020use crate :: io:: Pluralize ;
2121use crate :: prelude:: * ;
2222use crate :: runtime:: makedirs_with_perms;
23- use crate :: storage:: TagNamespaceBuf ;
2423use crate :: storage:: fs:: OpenFsRepository ;
24+ use crate :: storage:: { TagNamespace , TagNamespaceBuf } ;
2525use crate :: { Digest , Error , Result , encoding, graph, storage, tracking} ;
2626
2727#[ cfg( test) ]
@@ -319,6 +319,7 @@ where
319319 /// partially complete depending on the nature of the errors.
320320 pub async fn prune_all_tags_and_clean ( & self ) -> Result < CleanResult > {
321321 let mut result = CleanResult :: default ( ) ;
322+ let tag_namespace_to_prune = self . repo . get_tag_namespace ( ) ;
322323 let namespaces = self . repo . ls_tag_namespaces ( ) ;
323324 let mut stream = namespaces
324325 . map ( |ns| {
@@ -346,7 +347,11 @@ where
346347 futures. try_next ( ) . await ?;
347348 }
348349 }
349- futures. push ( self . prune_tag_stream_and_walk ( tag_namespace, tag_spec) ) ;
350+ futures. push ( self . prune_tag_stream_and_walk (
351+ tag_namespace_to_prune. as_ref ( ) ,
352+ tag_namespace,
353+ tag_spec,
354+ ) ) ;
350355 }
351356 drop ( stream) ;
352357 while let Some ( r) = futures. try_next ( ) . await ? {
@@ -375,12 +380,18 @@ where
375380 Ok ( result)
376381 }
377382
378- async fn prune_tag_stream_and_walk (
383+ async fn prune_tag_stream_and_walk < T > (
379384 & self ,
380- tag_namespace : Option < TagNamespaceBuf > ,
385+ tag_namespace_to_prune : Option < T > ,
386+ tag_namespace_to_visit : Option < TagNamespaceBuf > ,
381387 tag_spec : tracking:: TagSpec ,
382- ) -> Result < CleanResult > {
383- let ( mut result, to_keep) = self . prune_tag_stream ( tag_namespace, tag_spec) . await ?;
388+ ) -> Result < CleanResult >
389+ where
390+ T : AsRef < TagNamespace > ,
391+ {
392+ let ( mut result, to_keep) = self
393+ . prune_tag_stream ( tag_namespace_to_prune, tag_namespace_to_visit, tag_spec)
394+ . await ?;
384395 result += self . walk_attached_objects ( & to_keep) . await ?;
385396
386397 Ok ( result)
@@ -404,14 +415,31 @@ where
404415 /// Visit the tag and its history, pruning as configured and
405416 /// returning a cleaning (pruning) result and list of tags that
406417 /// were kept.
407- pub async fn prune_tag_stream (
418+ pub async fn prune_tag_stream < T > (
408419 & self ,
409- tag_namespace : Option < TagNamespaceBuf > ,
420+ tag_namespace_to_prune : Option < T > ,
421+ tag_namespace_to_visit : Option < TagNamespaceBuf > ,
410422 tag_spec : tracking:: TagSpec ,
411- ) -> Result < ( CleanResult , Vec < encoding:: Digest > ) > {
423+ ) -> Result < ( CleanResult , Vec < encoding:: Digest > ) >
424+ where
425+ T : AsRef < TagNamespace > ,
426+ {
427+ // The Cleaner needs to visit all namespaces to learn what objects are
428+ // still alive, but if the repo passed to the Cleaner has a namespace
429+ // set on it then one would expect that only tags in that namespace are
430+ // pruned.
431+ let should_prune_this_namespace = match (
432+ tag_namespace_to_prune. as_ref ( ) ,
433+ tag_namespace_to_visit. as_deref ( ) ,
434+ ) {
435+ ( Some ( prune) , Some ( visit) ) if prune. as_ref ( ) == visit => true ,
436+ ( None , None ) => true ,
437+ _ => false ,
438+ } ;
439+
412440 let history = self
413441 . repo
414- . read_tag_in_namespace ( tag_namespace . as_deref ( ) , & tag_spec)
442+ . read_tag_in_namespace ( tag_namespace_to_visit . as_deref ( ) , & tag_spec)
415443 . await ?
416444 . try_collect :: < Vec < _ > > ( )
417445 . await ?;
@@ -423,7 +451,7 @@ where
423451 self . reporter . visit_tag ( & tag) ;
424452 let count = if let Some ( seen_count) = seen_targets. get ( & tag. target ) {
425453 if let Some ( keep_number) = self . prune_repeated_tags {
426- if * seen_count >= keep_number. get ( ) {
454+ if should_prune_this_namespace && * seen_count >= keep_number. get ( ) {
427455 to_prune. push ( tag) ;
428456 continue ;
429457 }
@@ -435,7 +463,7 @@ where
435463
436464 seen_targets. insert ( tag. target , count) ;
437465
438- if self . prune_params . should_prune ( & spec, & tag) {
466+ if should_prune_this_namespace && self . prune_params . should_prune ( & spec, & tag) {
439467 to_prune. push ( tag) ;
440468 } else {
441469 to_keep. push ( tag. target ) ;
@@ -450,15 +478,15 @@ where
450478 for tag in to_prune. iter ( ) {
451479 if !self . dry_run {
452480 self . repo
453- . remove_tag_in_namespace ( tag_namespace . as_deref ( ) , tag)
481+ . remove_tag_in_namespace ( tag_namespace_to_visit . as_deref ( ) , tag)
454482 . await ?;
455483 }
456484 self . reporter . tag_removed ( tag) ;
457485 }
458486
459487 result
460488 . pruned_tags
461- . entry ( tag_namespace )
489+ . entry ( tag_namespace_to_visit )
462490 . or_default ( )
463491 . insert ( tag_spec, to_prune) ;
464492
0 commit comments