@@ -4550,3 +4550,100 @@ fn in_repo_worktree() -> crate::Result {
4550
4550
) ;
4551
4551
Ok ( ( ) )
4552
4552
}
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