2525 ChangeService ,
2626 IncarnationAlreadyExists ,
2727 _construct_merge_request_conflict_description ,
28+ _is_ignored ,
29+ _load_fengine_reset_ignore ,
2830 delete_all_files_in_local_git_repository ,
2931)
3032
@@ -678,6 +680,7 @@ async def test_reset_incarnation_fails_when_incarnation_does_not_exist(change_se
678680def test_delete_all_files_in_local_git_repository_removes_hidden_directories_and_files (tmp_path ):
679681 # GIVEN
680682 (tmp_path / ".dummy_folder" ).mkdir ()
683+ (tmp_path / ".dummy_folder" / "file.txt" ).write_text ("content" )
681684 (tmp_path / "dummy_folder2" ).mkdir ()
682685 (tmp_path / "dummy_folder2" / ".myfile" ).write_text ("Hello, world!" )
683686 (tmp_path / ".config" ).write_text ("Hello, world!" )
@@ -686,24 +689,23 @@ def test_delete_all_files_in_local_git_repository_removes_hidden_directories_and
686689 delete_all_files_in_local_git_repository (tmp_path )
687690
688691 # THEN
689- assert not (tmp_path / ".dummy_folder" ).exists ()
692+ assert not (tmp_path / ".dummy_folder" / "file.txt" ).exists ()
690693 assert not (tmp_path / "dummy_folder2" / ".myfile" ).exists ()
691694 assert not (tmp_path / ".config" ).exists ()
692695
693696
694- def test_delete_all_files_in_local_git_repository_does_not_delete_git_directory_in_root_folder (tmp_path ):
697+ def test_delete_all_files_in_local_git_repository_does_not_delete_git_directory (tmp_path ):
695698 # GIVEN
696699 (tmp_path / ".git" ).mkdir ()
697- (tmp_path / "subfolder" ).mkdir ()
698- (tmp_path / "subfolder" / ".git" ).mkdir ()
700+ (tmp_path / ".git" / "config" ).write_text ("git config" )
699701 (tmp_path / "README.md" ).write_text ("Hello, world!" )
700702
701703 # WHEN
702704 delete_all_files_in_local_git_repository (tmp_path )
703705
704706 # THEN
705707 assert (tmp_path / ".git" ).exists ()
706- assert not (tmp_path / "subfolder " / ".git " ).exists ()
708+ assert (tmp_path / ".git " / "config " ).exists ()
707709 assert not (tmp_path / "README.md" ).exists ()
708710
709711
@@ -714,3 +716,161 @@ async def test_diff_should_not_include_gitrepository(
714716 diff = await change_service .diff_incarnation (initialized_incarnation .id )
715717
716718 assert diff == ""
719+
720+
721+ def test_load_fengine_reset_ignore_handles_empty_lines (tmp_path ):
722+ # GIVEN
723+ (tmp_path / ".fengine-reset-ignore" ).write_text ("keep_me.txt\n \n \n \n keep_me_too.md\n " )
724+
725+ # WHEN
726+ result = _load_fengine_reset_ignore (tmp_path )
727+
728+ # THEN
729+ assert result == frozenset ({Path ("keep_me.txt" ), Path ("keep_me_too.md" )})
730+
731+
732+ def test_load_fengine_reset_ignore_handles_whitespace (tmp_path ):
733+ # GIVEN
734+ (tmp_path / ".fengine-reset-ignore" ).write_text (" keep_me.txt \n keep_folder " )
735+
736+ # WHEN
737+ result = _load_fengine_reset_ignore (tmp_path )
738+
739+ # THEN
740+ assert result == frozenset ({Path ("keep_me.txt" ), Path ("keep_folder" )})
741+
742+
743+ def test_is_ignored_returns_true_for_exact_file_match ():
744+ # GIVEN
745+ directory = Path ("/repo" )
746+ ignore_list = frozenset ({Path ("keep_me.txt" )})
747+
748+ # WHEN / THEN
749+ assert _is_ignored (Path ("/repo/keep_me.txt" ), directory , ignore_list ) is True
750+
751+
752+ def test_is_ignored_returns_false_for_non_matching_file ():
753+ # GIVEN
754+ directory = Path ("/repo" )
755+ ignore_list = frozenset ({Path ("keep_me.txt" )})
756+
757+ # WHEN / THEN
758+ assert _is_ignored (Path ("/repo/delete_me.txt" ), directory , ignore_list ) is False
759+
760+
761+ def test_is_ignored_returns_true_for_directory_match ():
762+ # GIVEN
763+ directory = Path ("/repo" )
764+ ignore_list = frozenset ({Path ("keep_folder" )})
765+
766+ # WHEN / THEN
767+ assert _is_ignored (Path ("/repo/keep_folder" ), directory , ignore_list ) is True
768+
769+
770+ def test_is_ignored_returns_true_for_nested_file_in_ignored_directory ():
771+ # GIVEN
772+ directory = Path ("/repo" )
773+ ignore_list = frozenset ({Path ("keep_folder" )})
774+
775+ # WHEN / THEN
776+ assert _is_ignored (Path ("/repo/keep_folder/nested_file.txt" ), directory , ignore_list ) is True
777+
778+
779+ def test_is_ignored_returns_true_for_nested_path_exact_match ():
780+ # GIVEN
781+ directory = Path ("/repo" )
782+ ignore_list = frozenset ({Path ("example/file1" )})
783+
784+ # WHEN / THEN
785+ assert _is_ignored (Path ("/repo/example/file1" ), directory , ignore_list ) is True
786+
787+
788+ def test_is_ignored_returns_false_for_sibling_of_nested_ignored_path ():
789+ # GIVEN
790+ directory = Path ("/repo" )
791+ ignore_list = frozenset ({Path ("example/file1" )})
792+
793+ # WHEN / THEN
794+ assert _is_ignored (Path ("/repo/example/file2" ), directory , ignore_list ) is False
795+
796+
797+ def test_is_ignored_returns_false_for_parent_of_nested_ignored_path ():
798+ # GIVEN
799+ directory = Path ("/repo" )
800+ ignore_list = frozenset ({Path ("example/file1" )})
801+
802+ # WHEN / THEN
803+ assert _is_ignored (Path ("/repo/example" ), directory , ignore_list ) is False
804+
805+
806+ def test_is_ignored_returns_true_for_deeply_nested_path ():
807+ # GIVEN
808+ directory = Path ("/repo" )
809+ ignore_list = frozenset ({Path ("example/nested/deep_file" )})
810+
811+ # WHEN / THEN
812+ assert _is_ignored (Path ("/repo/example/nested/deep_file" ), directory , ignore_list ) is True
813+
814+
815+ def test_is_ignored_handles_multiple_ignore_entries ():
816+ # GIVEN
817+ directory = Path ("/repo" )
818+ ignore_list = frozenset ({Path ("file1.txt" ), Path ("folder1" ), Path ("nested/file2" )})
819+
820+ # WHEN / THEN
821+ assert _is_ignored (Path ("/repo/file1.txt" ), directory , ignore_list ) is True
822+ assert _is_ignored (Path ("/repo/folder1" ), directory , ignore_list ) is True
823+ assert _is_ignored (Path ("/repo/folder1/child.txt" ), directory , ignore_list ) is True
824+ assert _is_ignored (Path ("/repo/nested/file2" ), directory , ignore_list ) is True
825+ assert _is_ignored (Path ("/repo/other.txt" ), directory , ignore_list ) is False
826+
827+
828+ def test_is_ignored_returns_false_for_empty_ignore_list ():
829+ # GIVEN
830+ directory = Path ("/repo" )
831+ ignore_list = frozenset ()
832+
833+ # WHEN / THEN
834+ assert _is_ignored (Path ("/repo/any_file.txt" ), directory , ignore_list ) is False
835+
836+
837+ def test_delete_all_files_in_local_git_repository_respects_fengine_reset_ignore (tmp_path ):
838+ # GIVEN - comprehensive end-to-end test
839+ (tmp_path / ".fengine-reset-ignore" ).write_text ("keep_file.txt\n keep_folder\n example/nested/deep_file" )
840+
841+ # Files to keep
842+ (tmp_path / "keep_file.txt" ).write_text ("I should remain" )
843+ (tmp_path / "keep_folder" ).mkdir ()
844+ (tmp_path / "keep_folder" / "nested_file.txt" ).write_text ("Nested content to keep" )
845+ (tmp_path / "example" ).mkdir ()
846+ (tmp_path / "example" / "nested" ).mkdir ()
847+ (tmp_path / "example" / "nested" / "deep_file" ).write_text ("I should remain" )
848+
849+ # Files to delete
850+ (tmp_path / "delete_me.txt" ).write_text ("I should be deleted" )
851+ (tmp_path / "delete_folder" ).mkdir ()
852+ (tmp_path / "delete_folder" / "some_file.txt" ).write_text ("To be deleted" )
853+ (tmp_path / "example" / "file_to_delete.txt" ).write_text ("I should be deleted" )
854+ (tmp_path / "example" / "nested" / "other_file.txt" ).write_text ("I should be deleted" )
855+
856+ # .git directory should be preserved
857+ (tmp_path / ".git" ).mkdir ()
858+ (tmp_path / ".git" / "config" ).write_text ("git config" )
859+
860+ # WHEN
861+ delete_all_files_in_local_git_repository (tmp_path )
862+
863+ # THEN - kept files
864+ assert (tmp_path / "keep_file.txt" ).exists ()
865+ assert (tmp_path / "keep_folder" ).exists ()
866+ assert (tmp_path / "keep_folder" / "nested_file.txt" ).exists ()
867+ assert (tmp_path / "example" / "nested" / "deep_file" ).exists ()
868+ assert (tmp_path / ".git" ).exists ()
869+ assert (tmp_path / ".git" / "config" ).exists ()
870+
871+ # THEN - deleted files
872+ assert not (tmp_path / "delete_me.txt" ).exists ()
873+ assert not (tmp_path / "delete_folder" / "some_file.txt" ).exists ()
874+ assert not (tmp_path / "example" / "file_to_delete.txt" ).exists ()
875+ assert not (tmp_path / "example" / "nested" / "other_file.txt" ).exists ()
876+ assert not (tmp_path / ".fengine-reset-ignore" ).exists ()
0 commit comments