@@ -4550,3 +4550,100 @@ fn in_repo_worktree() -> crate::Result {
45504550 ) ;
45514551 Ok ( ( ) )
45524552}
4553+
4554+ #[ test]
4555+ fn in_repo_hidden_worktree ( ) -> crate :: Result {
4556+ let root = fixture ( "in-repo-hidden-worktree" ) ;
4557+ let ( ( out, _root) , entries) = collect ( & root, None , |keep, ctx| walk ( & root, ctx, options_emit_all ( ) , keep) ) ;
4558+ assert_eq ! (
4559+ out,
4560+ walk:: Outcome {
4561+ read_dir_calls: 2 ,
4562+ returned_entries: entries. len( ) ,
4563+ seen_entries: 4 ,
4564+ }
4565+ ) ;
4566+ assert_eq ! (
4567+ entries,
4568+ & [
4569+ entry_nokind( ".git" , Pruned ) . with_property( DotGit ) . with_match( Always ) ,
4570+ entry( ".gitignore" , Untracked , File ) ,
4571+ entry( "dir/file" , Tracked , File ) ,
4572+ entry( "hidden" , Ignored ( Expendable ) , Directory ) ,
4573+ ] ,
4574+ "if worktree information isn't provided, they would not be discovered in hidden directories"
4575+ ) ;
4576+
4577+ let ( ( out, _root) , entries) = collect ( & root, None , |keep, ctx| {
4578+ walk (
4579+ & root,
4580+ ctx,
4581+ walk:: Options {
4582+ for_deletion : None ,
4583+ worktree_relative_worktree_dirs : Some ( & BTreeSet :: from ( [ "hidden/subdir/worktree" . into ( ) ] ) ) ,
4584+ ..options_emit_all ( )
4585+ } ,
4586+ keep,
4587+ )
4588+ } ) ;
4589+ assert_eq ! (
4590+ out,
4591+ walk:: Outcome {
4592+ read_dir_calls: 2 ,
4593+ returned_entries: entries. len( ) ,
4594+ seen_entries: 4 ,
4595+ }
4596+ ) ;
4597+ assert_eq ! (
4598+ entries,
4599+ & [
4600+ entry_nokind( ".git" , Pruned ) . with_property( DotGit ) . with_match( Always ) ,
4601+ entry( ".gitignore" , Untracked , File ) ,
4602+ entry( "dir/file" , Tracked , File ) ,
4603+ entry( "hidden" , Ignored ( Expendable ) , Directory ) ,
4604+ ] ,
4605+ "Without the intend to delete, the worktree remains hidden, which is what we want to see in a `status` for example"
4606+ ) ;
4607+
4608+ for ignored_emission_mode in [ Matching , CollapseDirectory ] {
4609+ for deletion_mode in [
4610+ ForDeletionMode :: IgnoredDirectoriesCanHideNestedRepositories ,
4611+ ForDeletionMode :: FindRepositoriesInIgnoredDirectories ,
4612+ ForDeletionMode :: FindNonBareRepositoriesInIgnoredDirectories ,
4613+ ] {
4614+ let ( ( out, _root) , entries) = collect ( & root, None , |keep, ctx| {
4615+ walk (
4616+ & root,
4617+ ctx,
4618+ walk:: Options {
4619+ emit_ignored : Some ( ignored_emission_mode) ,
4620+ for_deletion : Some ( deletion_mode) ,
4621+ worktree_relative_worktree_dirs : Some ( & BTreeSet :: from ( [ "hidden/subdir/worktree" . into ( ) ] ) ) ,
4622+ ..options_emit_all ( )
4623+ } ,
4624+ keep,
4625+ )
4626+ } ) ;
4627+ assert_eq ! (
4628+ out,
4629+ walk:: Outcome {
4630+ read_dir_calls: 4 ,
4631+ returned_entries: entries. len( ) ,
4632+ seen_entries: 5 ,
4633+ }
4634+ ) ;
4635+ assert_eq ! (
4636+ entries,
4637+ & [
4638+ entry_nokind( ".git" , Pruned ) . with_property( DotGit ) . with_match( Always ) ,
4639+ entry( ".gitignore" , Untracked , File ) ,
4640+ entry( "dir/file" , Tracked , File ) ,
4641+ entry( "hidden/file" , Ignored ( Expendable ) , File ) ,
4642+ entry( "hidden/subdir/worktree" , Tracked , Repository ) . no_index_kind( ) ,
4643+ ] ,
4644+ "Worktrees within hidden directories are also detected and protected by counting them as tracked (like submodules)"
4645+ ) ;
4646+ }
4647+ }
4648+ Ok ( ( ) )
4649+ }
0 commit comments