@@ -728,6 +728,151 @@ def test_deinit_calls_git_submodule(self, rwdir):
728728
729729 git_submodule .assert_called_once_with ("deinit" , "--force" , "--" , submodule .path )
730730
731+ @with_rw_directory
732+ def test_update_after_deinit (self , rwdir ):
733+ source_path = osp .join (rwdir , "source" )
734+ source_repo = git .Repo .init (source_path )
735+ touch (osp .join (source_path , "file" ))
736+ source_repo .index .add (["file" ])
737+ source_repo .index .commit ("initial commit" )
738+
739+ parent_path = osp .join (rwdir , "parent" )
740+ parent_repo = git .Repo .init (parent_path )
741+ submodule = parent_repo .create_submodule ("module" , "module" , source_path )
742+ parent_repo .index .commit ("add submodule" )
743+
744+ submodule .deinit ()
745+ assert not submodule .module_exists ()
746+ assert osp .isdir (osp .join (parent_repo .git_dir , "modules" , submodule .name ))
747+
748+ submodule .update ()
749+
750+ assert submodule .module_exists ()
751+ assert submodule .module ().head .commit == source_repo .head .commit
752+ assert osp .isfile (osp .join (submodule .abspath , "file" ))
753+
754+ @with_rw_directory
755+ def test_update_to_latest_revision_after_deinit_fetches_remote (self , rwdir ):
756+ source_path = osp .join (rwdir , "source" )
757+ source_repo = git .Repo .init (source_path )
758+ source_repo .git .commit (m = "initial commit" , allow_empty = True )
759+
760+ parent_repo = git .Repo .init (osp .join (rwdir , "parent" ))
761+ submodule = parent_repo .create_submodule ("module" , "module" , source_path )
762+ parent_repo .index .commit ("add submodule" )
763+ submodule .deinit ()
764+
765+ touch (osp .join (source_path , "new-file" ))
766+ source_repo .index .add (["new-file" ])
767+ source_repo .index .commit ("advance remote" )
768+
769+ submodule .update (to_latest_revision = True )
770+
771+ assert submodule .module ().head .commit == source_repo .head .commit
772+ assert osp .isfile (osp .join (submodule .abspath , "new-file" ))
773+
774+ @with_rw_directory
775+ def test_update_after_deinit_fetches_new_gitlink_commit (self , rwdir ):
776+ source_path = osp .join (rwdir , "source" )
777+ source_repo = git .Repo .init (source_path )
778+ source_repo .git .commit (m = "initial commit" , allow_empty = True )
779+
780+ parent_repo = git .Repo .init (osp .join (rwdir , "parent" ))
781+ submodule = parent_repo .create_submodule ("module" , "module" , source_path )
782+ parent_repo .index .commit ("add submodule" )
783+ submodule .deinit ()
784+
785+ touch (osp .join (source_path , "new-file" ))
786+ source_repo .index .add (["new-file" ])
787+ source_repo .index .commit ("advance remote" )
788+ parent_repo .git .update_index (
789+ "--cacheinfo" ,
790+ f"160000,{ source_repo .head .commit .hexsha } ,{ submodule .path } " ,
791+ )
792+ parent_repo .index .commit ("advance submodule" )
793+
794+ submodule = parent_repo .submodule (submodule .name )
795+ submodule .update ()
796+
797+ assert submodule .module ().head .commit == source_repo .head .commit
798+ assert osp .isfile (osp .join (submodule .abspath , "new-file" ))
799+
800+ @with_rw_directory
801+ def test_update_after_deinit_refuses_non_empty_checkout (self , rwdir ):
802+ source_path = osp .join (rwdir , "source" )
803+ source_repo = git .Repo .init (source_path )
804+ tracked_file = osp .join (source_path , "file" )
805+ with open (tracked_file , "w" ) as fp :
806+ fp .write ("submodule content" )
807+ source_repo .index .add (["file" ])
808+ source_repo .index .commit ("initial commit" )
809+
810+ parent_repo = git .Repo .init (osp .join (rwdir , "parent" ))
811+ submodule = parent_repo .create_submodule ("module" , "module" , source_path )
812+ parent_repo .index .commit ("add submodule" )
813+ submodule .deinit ()
814+
815+ checkout_file = osp .join (submodule .abspath , "file" )
816+ with open (checkout_file , "w" ) as fp :
817+ fp .write ("user content" )
818+
819+ with pytest .raises (OSError , match = "does already exist and is non-empty" ):
820+ submodule .update ()
821+
822+ with open (checkout_file ) as fp :
823+ assert fp .read () == "user content"
824+ assert not osp .exists (osp .join (submodule .abspath , ".git" ))
825+
826+ @with_rw_directory
827+ def test_update_after_deinit_without_init_does_not_restore_checkout (self , rwdir ):
828+ source_path = osp .join (rwdir , "source" )
829+ source_repo = git .Repo .init (source_path )
830+ source_repo .git .commit (m = "initial commit" , allow_empty = True )
831+
832+ parent_repo = git .Repo .init (osp .join (rwdir , "parent" ))
833+ submodule = parent_repo .create_submodule ("module" , "module" , source_path )
834+ parent_repo .index .commit ("add submodule" )
835+ submodule .deinit ()
836+
837+ assert submodule .update (init = False ) is submodule
838+ assert not submodule .module_exists ()
839+ assert not osp .exists (osp .join (submodule .abspath , ".git" ))
840+
841+ @with_rw_directory
842+ def test_dry_run_update_after_deinit_does_not_restore_checkout (self , rwdir ):
843+ source_path = osp .join (rwdir , "source" )
844+ source_repo = git .Repo .init (source_path )
845+ source_repo .git .commit (m = "initial commit" , allow_empty = True )
846+
847+ parent_repo = git .Repo .init (osp .join (rwdir , "parent" ))
848+ submodule = parent_repo .create_submodule ("module" , "module" , source_path )
849+ parent_repo .index .commit ("add submodule" )
850+ submodule .deinit ()
851+
852+ assert submodule .update (dry_run = True ) is submodule
853+ assert not submodule .module_exists ()
854+ assert not osp .exists (osp .join (submodule .abspath , ".git" ))
855+
856+ @with_rw_directory
857+ def test_update_after_deinit_restores_nested_checkout (self , rwdir ):
858+ source_path = osp .join (rwdir , "source" )
859+ source_repo = git .Repo .init (source_path )
860+ touch (osp .join (source_path , "file" ))
861+ source_repo .index .add (["file" ])
862+ source_repo .index .commit ("initial commit" )
863+
864+ parent_repo = git .Repo .init (osp .join (rwdir , "parent" ))
865+ submodule = parent_repo .create_submodule ("nested/module" , "deps/module" , source_path )
866+ parent_repo .index .commit ("add nested submodule" )
867+ submodule .deinit ()
868+
869+ submodule .update ()
870+
871+ module_repo = submodule .module ()
872+ assert module_repo .head .commit == source_repo .head .commit
873+ assert osp .isfile (osp .join (submodule .abspath , "file" ))
874+ assert osp .samefile (module_repo .git_dir , osp .join (parent_repo .git_dir , "modules" , submodule .name ))
875+
731876 @with_rw_repo (k_no_subm_tag , bare = False )
732877 def test_first_submodule (self , rwrepo ):
733878 assert len (list (rwrepo .iter_submodules ())) == 0
0 commit comments