diff options
Diffstat (limited to 'test/test_submodule.py')
-rw-r--r-- | test/test_submodule.py | 567 |
1 files changed, 363 insertions, 204 deletions
diff --git a/test/test_submodule.py b/test/test_submodule.py index a79123dc..fc96391d 100644 --- a/test/test_submodule.py +++ b/test/test_submodule.py @@ -9,20 +9,11 @@ import git from git.cmd import Git from git.compat import is_win from git.config import GitConfigParser, cp -from git.exc import ( - InvalidGitRepositoryError, - RepositoryDirtyError -) +from git.exc import InvalidGitRepositoryError, RepositoryDirtyError from git.objects.submodule.base import Submodule from git.objects.submodule.root import RootModule, RootUpdateProgress -from git.repo.fun import ( - find_submodule_git_dir, - touch -) -from test.lib import ( - TestBase, - with_rw_repo -) +from git.repo.fun import find_submodule_git_dir, touch +from test.lib import TestBase, with_rw_repo from test.lib import with_rw_directory from git.util import HIDE_WINDOWS_KNOWN_ERRORS from git.util import to_native_path_linux, join_path_native @@ -32,7 +23,7 @@ import os.path as osp class TestRootProgress(RootUpdateProgress): """Just prints messages, for now without checking the correctness of the states""" - def update(self, op, cur_count, max_count, message=''): + def update(self, op, cur_count, max_count, message=""): print(op, cur_count, max_count, message) @@ -40,9 +31,9 @@ prog = TestRootProgress() class TestSubmodule(TestBase): - def tearDown(self): import gc + gc.collect() k_subm_current = "c15a6e1923a14bc760851913858a3942a4193cdb" @@ -54,7 +45,7 @@ class TestSubmodule(TestBase): # manual instantiation smm = Submodule(rwrepo, "\0" * 20) # name needs to be set in advance - self.assertRaises(AttributeError, getattr, smm, 'name') + self.assertRaises(AttributeError, getattr, smm, "name") # iterate - 1 submodule sms = Submodule.list_items(rwrepo, self.k_subm_current) @@ -64,11 +55,13 @@ class TestSubmodule(TestBase): # at a different time, there is None assert len(Submodule.list_items(rwrepo, self.k_no_subm_tag)) == 0 - assert sm.path == 'git/ext/gitdb' - assert sm.path != sm.name # in our case, we have ids there, which don't equal the path - assert sm.url.endswith('github.com/gitpython-developers/gitdb.git') - assert sm.branch_path == 'refs/heads/master' # the default ... - assert sm.branch_name == 'master' + assert sm.path == "git/ext/gitdb" + assert ( + sm.path != sm.name + ) # in our case, we have ids there, which don't equal the path + assert sm.url.endswith("github.com/gitpython-developers/gitdb.git") + assert sm.branch_path == "refs/heads/master" # the default ... + assert sm.branch_name == "master" assert sm.parent_commit == rwrepo.head.commit # size is always 0 assert sm.size == 0 @@ -76,7 +69,7 @@ class TestSubmodule(TestBase): self.assertRaises(InvalidGitRepositoryError, sm.module) # which is why we can't get the branch either - it points into the module() repository - self.assertRaises(InvalidGitRepositoryError, getattr, sm, 'branch') + self.assertRaises(InvalidGitRepositoryError, getattr, sm, "branch") # branch_path works, as its just a string assert isinstance(sm.branch_path, str) @@ -84,16 +77,16 @@ class TestSubmodule(TestBase): # some commits earlier we still have a submodule, but its at a different commit smold = next(Submodule.iter_items(rwrepo, self.k_subm_changed)) assert smold.binsha != sm.binsha - assert smold != sm # the name changed + assert smold != sm # the name changed # force it to reread its information - del(smold._url) + del smold._url smold.url == sm.url # @NoEffect # test config_reader/writer methods sm.config_reader() - new_smclone_path = None # keep custom paths for later - new_csmclone_path = None # + new_smclone_path = None # keep custom paths for later + new_csmclone_path = None # if rwrepo.bare: with self.assertRaises(InvalidGitRepositoryError): with sm.config_writer() as cw: @@ -101,10 +94,12 @@ class TestSubmodule(TestBase): else: with sm.config_writer() as writer: # for faster checkout, set the url to the local path - new_smclone_path = Git.polish_url(osp.join(self.rorepo.working_tree_dir, sm.path)) - writer.set_value('url', new_smclone_path) + new_smclone_path = Git.polish_url( + osp.join(self.rorepo.working_tree_dir, sm.path) + ) + writer.set_value("url", new_smclone_path) writer.release() - assert sm.config_reader().get_value('url') == new_smclone_path + assert sm.config_reader().get_value("url") == new_smclone_path assert sm.url == new_smclone_path # END handle bare repo smold.config_reader() @@ -134,7 +129,9 @@ class TestSubmodule(TestBase): if rwrepo.bare: self.assertRaises(InvalidGitRepositoryError, sm.module) self.assertRaises(InvalidGitRepositoryError, sm.remove) - self.assertRaises(InvalidGitRepositoryError, sm.add, rwrepo, 'here', 'there') + self.assertRaises( + InvalidGitRepositoryError, sm.add, rwrepo, "here", "there" + ) else: # its not checked out in our case self.assertRaises(InvalidGitRepositoryError, sm.module) @@ -152,13 +149,15 @@ class TestSubmodule(TestBase): assert sma.path == sm.path # no url and no module at path fails - self.assertRaises(ValueError, Submodule.add, rwrepo, "newsubm", "pathtorepo", url=None) + self.assertRaises( + ValueError, Submodule.add, rwrepo, "newsubm", "pathtorepo", url=None + ) # CONTINUE UPDATE ################# # lets update it - its a recursive one too - newdir = osp.join(sm.abspath, 'dir') + newdir = osp.join(sm.abspath, "dir") os.makedirs(newdir) # update fails if the path already exists non-empty @@ -170,7 +169,7 @@ class TestSubmodule(TestBase): assert not sm.module_exists() assert sm.update() is sm - sm_repopath = sm.path # cache for later + sm_repopath = sm.path # cache for later assert sm.module_exists() assert isinstance(sm.module(), git.Repo) assert sm.module().working_tree_dir == sm.abspath @@ -179,7 +178,14 @@ class TestSubmodule(TestBase): ##################### # url must match the one in the existing repository ( if submodule name suggests a new one ) # or we raise - self.assertRaises(ValueError, Submodule.add, rwrepo, "newsubm", sm.path, "git://someurl/repo.git") + self.assertRaises( + ValueError, + Submodule.add, + rwrepo, + "newsubm", + sm.path, + "git://someurl/repo.git", + ) # CONTINUE UPDATE ################# @@ -197,15 +203,17 @@ class TestSubmodule(TestBase): sm.update(recursive=False) assert len(list(rwrepo.iter_submodules())) == 2 - assert len(sm.children()) == 1 # its not checked out yet + assert len(sm.children()) == 1 # its not checked out yet csm = sm.children()[0] assert not csm.module_exists() csm_repopath = csm.path # adjust the path of the submodules module to point to the local destination - new_csmclone_path = Git.polish_url(osp.join(self.rorepo.working_tree_dir, sm.path, csm.path)) + new_csmclone_path = Git.polish_url( + osp.join(self.rorepo.working_tree_dir, sm.path, csm.path) + ) with csm.config_writer() as writer: - writer.set_value('url', new_csmclone_path) + writer.set_value("url", new_csmclone_path) assert csm.url == new_csmclone_path # dry-run does nothing @@ -226,26 +234,34 @@ class TestSubmodule(TestBase): # reset both heads to the previous version, verify that to_latest_revision works smods = (sm.module(), csm.module()) for repo in smods: - repo.head.reset('HEAD~2', working_tree=1) + repo.head.reset("HEAD~2", working_tree=1) # END for each repo to reset # dry run does nothing - self.assertRaises(RepositoryDirtyError, sm.update, recursive=True, dry_run=True, progress=prog) + self.assertRaises( + RepositoryDirtyError, + sm.update, + recursive=True, + dry_run=True, + progress=prog, + ) sm.update(recursive=True, dry_run=True, progress=prog, force=True) for repo in smods: assert repo.head.commit != repo.head.ref.tracking_branch().commit # END for each repo to check - self.assertRaises(RepositoryDirtyError, sm.update, recursive=True, to_latest_revision=True) + self.assertRaises( + RepositoryDirtyError, sm.update, recursive=True, to_latest_revision=True + ) sm.update(recursive=True, to_latest_revision=True, force=True) for repo in smods: assert repo.head.commit == repo.head.ref.tracking_branch().commit # END for each repo to check - del(smods) + del smods # if the head is detached, it still works ( but warns ) smref = sm.module().head.ref - sm.module().head.ref = 'HEAD~1' + sm.module().head.ref = "HEAD~1" # if there is no tracking branch, we get a warning as well csm_tracking_branch = csm.module().head.ref.tracking_branch() csm.module().head.ref.set_tracking_branch(None) @@ -268,8 +284,10 @@ class TestSubmodule(TestBase): # to GitHub. To save time, we will change it to csm.set_parent_commit(csm.repo.head.commit) with csm.config_writer() as cw: - cw.set_value('url', self._small_repo_url()) - csm.repo.index.commit("adjusted URL to point to local source, instead of the internet") + cw.set_value("url", self._small_repo_url()) + csm.repo.index.commit( + "adjusted URL to point to local source, instead of the internet" + ) # We have modified the configuration, hence the index is dirty, and the # deletion will fail @@ -301,7 +319,7 @@ class TestSubmodule(TestBase): # but ... we have untracked files in the child submodule fn = join_path_native(csm.module().working_tree_dir, "newfile") - with open(fn, 'w') as fd: + with open(fn, "w") as fd: fd.write("hi") self.assertRaises(InvalidGitRepositoryError, sm.remove) @@ -323,14 +341,14 @@ class TestSubmodule(TestBase): sm.remove(configuration=False, force=True) assert sm.exists() assert not sm.module_exists() - assert sm.config_reader().get_value('url') + assert sm.config_reader().get_value("url") # delete the rest sm_path = sm.path sm.remove() assert not sm.exists() assert not sm.module_exists() - self.assertRaises(ValueError, getattr, sm, 'path') + self.assertRaises(ValueError, getattr, sm, "path") assert len(rwrepo.submodules) == 0 @@ -339,20 +357,35 @@ class TestSubmodule(TestBase): # add a simple remote repo - trailing slashes are no problem smid = "newsub" osmid = "othersub" - nsm = Submodule.add(rwrepo, smid, sm_repopath, new_smclone_path + "/", None, no_checkout=True) + nsm = Submodule.add( + rwrepo, + smid, + sm_repopath, + new_smclone_path + "/", + None, + no_checkout=True, + ) assert nsm.name == smid assert nsm.module_exists() assert nsm.exists() # its not checked out - assert not osp.isfile(join_path_native(nsm.module().working_tree_dir, Submodule.k_modules_file)) + assert not osp.isfile( + join_path_native( + nsm.module().working_tree_dir, Submodule.k_modules_file + ) + ) assert len(rwrepo.submodules) == 1 # add another submodule, but into the root, not as submodule - osm = Submodule.add(rwrepo, osmid, csm_repopath, new_csmclone_path, Submodule.k_head_default) + osm = Submodule.add( + rwrepo, osmid, csm_repopath, new_csmclone_path, Submodule.k_head_default + ) assert osm != nsm assert osm.module_exists() assert osm.exists() - assert osp.isfile(join_path_native(osm.module().working_tree_dir, 'setup.py')) + assert osp.isfile( + join_path_native(osm.module().working_tree_dir, "setup.py") + ) assert len(rwrepo.submodules) == 2 @@ -368,7 +401,9 @@ class TestSubmodule(TestBase): # MOVE MODULE ############# # invalid input - self.assertRaises(ValueError, nsm.move, 'doesntmatter', module=False, configuration=False) + self.assertRaises( + ValueError, nsm.move, "doesntmatter", module=False, configuration=False + ) # renaming to the same path does nothing assert nsm.move(sm_path) is nsm @@ -377,14 +412,14 @@ class TestSubmodule(TestBase): nmp = join_path_native("new", "module", "dir") + "/" # new module path pmp = nsm.path assert nsm.move(nmp) is nsm - nmp = nmp[:-1] # cut last / + nmp = nmp[:-1] # cut last / nmpl = to_native_path_linux(nmp) assert nsm.path == nmpl assert rwrepo.submodules[0].path == nmpl - mpath = 'newsubmodule' + mpath = "newsubmodule" absmpath = join_path_native(rwrepo.working_tree_dir, mpath) - open(absmpath, 'w').write('') + open(absmpath, "w").write("") self.assertRaises(ValueError, nsm.move, mpath) os.remove(absmpath) @@ -402,11 +437,19 @@ class TestSubmodule(TestBase): for remote in osmod.remotes: remote.remove(osmod, remote.name) assert not osm.exists() - self.assertRaises(ValueError, Submodule.add, rwrepo, osmid, csm_repopath, url=None) + self.assertRaises( + ValueError, Submodule.add, rwrepo, osmid, csm_repopath, url=None + ) # END handle bare mode # Error if there is no submodule file here - self.assertRaises(IOError, Submodule._config_parser, rwrepo, rwrepo.commit(self.k_no_subm_tag), True) + self.assertRaises( + IOError, + Submodule._config_parser, + rwrepo, + rwrepo.commit(self.k_no_subm_tag), + True, + ) # @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, ## ACTUALLY skipped by `git.submodule.base#L869`. # "FIXME: fails with: PermissionError: [WinError 32] The process cannot access the file because" @@ -420,11 +463,14 @@ class TestSubmodule(TestBase): def test_base_bare(self, rwrepo): self._do_base_tests(rwrepo) - @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, """ + @skipIf( + HIDE_WINDOWS_KNOWN_ERRORS, + """ File "C:\\projects\\gitpython\\git\\cmd.py", line 559, in execute raise GitCommandNotFound(command, err) git.exc.GitCommandNotFound: Cmd('git') not found due to: OSError('[WinError 6] The handle is invalid') - cmdline: git clone -n --shared -v C:\\projects\\gitpython\\.git Users\\appveyor\\AppData\\Local\\Temp\\1\\tmplyp6kr_rnon_bare_test_root_module""") # noqa E501 + cmdline: git clone -n --shared -v C:\\projects\\gitpython\\.git Users\\appveyor\\AppData\\Local\\Temp\\1\\tmplyp6kr_rnon_bare_test_root_module""", + ) # noqa E501 @with_rw_repo(k_subm_current, bare=False) def test_root_module(self, rwrepo): # Can query everything without problems @@ -447,10 +493,12 @@ class TestSubmodule(TestBase): # deep traversal gitdb / async rsmsp = [sm.path for sm in rm.traverse()] - assert len(rsmsp) >= 2 # gitdb and async [and smmap], async being a child of gitdb + assert ( + len(rsmsp) >= 2 + ) # gitdb and async [and smmap], async being a child of gitdb # cannot set the parent commit as root module's path didn't exist - self.assertRaises(ValueError, rm.set_parent_commit, 'HEAD') + self.assertRaises(ValueError, rm.set_parent_commit, "HEAD") # TEST UPDATE ############# @@ -460,16 +508,18 @@ class TestSubmodule(TestBase): # modify path without modifying the index entry # ( which is what the move method would do properly ) - #================================================== + # ================================================== sm = rm.children()[0] pp = "path/prefix" fp = join_path_native(pp, sm.path) prep = sm.path - assert not sm.module_exists() # was never updated after rwrepo's clone + assert not sm.module_exists() # was never updated after rwrepo's clone # assure we clone from a local source with sm.config_writer() as writer: - writer.set_value('url', Git.polish_url(osp.join(self.rorepo.working_tree_dir, sm.path))) + writer.set_value( + "url", Git.polish_url(osp.join(self.rorepo.working_tree_dir, sm.path)) + ) # dry-run does nothing sm.update(recursive=False, dry_run=True, progress=prog) @@ -478,7 +528,9 @@ class TestSubmodule(TestBase): sm.update(recursive=False) assert sm.module_exists() with sm.config_writer() as writer: - writer.set_value('path', fp) # change path to something with prefix AFTER url change + writer.set_value( + "path", fp + ) # change path to something with prefix AFTER url change # update doesn't fail, because list_items ignores the wrong path in such situations. rm.update(recursive=False) @@ -488,7 +540,7 @@ class TestSubmodule(TestBase): self.assertRaises(InvalidGitRepositoryError, sm.move, pp) # reset the path(cache) to where it was, now it works sm.path = prep - sm.move(fp, module=False) # leave it at the old location + sm.move(fp, module=False) # leave it at the old location assert not sm.module_exists() cpathchange = rwrepo.index.commit("changed sm path") # finally we can commit @@ -499,12 +551,16 @@ class TestSubmodule(TestBase): assert sm.module_exists() # add submodule - #================ + # ================ nsmn = "newsubmodule" nsmp = "submrepo" - subrepo_url = Git.polish_url(osp.join(self.rorepo.working_tree_dir, rsmsp[0], rsmsp[1])) + subrepo_url = Git.polish_url( + osp.join(self.rorepo.working_tree_dir, rsmsp[0], rsmsp[1]) + ) nsm = Submodule.add(rwrepo, nsmn, nsmp, url=subrepo_url) - csmadded = rwrepo.index.commit("Added submodule").hexsha # make sure we don't keep the repo reference + csmadded = rwrepo.index.commit( + "Added submodule" + ).hexsha # make sure we don't keep the repo reference nsm.set_parent_commit(csmadded) assert nsm.module_exists() # in our case, the module should not exist, which happens if we update a parent @@ -520,11 +576,11 @@ class TestSubmodule(TestBase): assert nsm.module_exists() # remove submodule - the previous one - #==================================== + # ==================================== sm.set_parent_commit(csmadded) smp = sm.abspath assert not sm.remove(module=False).exists() - assert osp.isdir(smp) # module still exists + assert osp.isdir(smp) # module still exists csmremoved = rwrepo.index.commit("Removed submodule") # an update will remove the module @@ -535,37 +591,45 @@ class TestSubmodule(TestBase): # when removing submodules, we may get new commits as nested submodules are auto-committing changes # to allow deletions without force, as the index would be dirty otherwise. # QUESTION: Why does this seem to work in test_git_submodule_compatibility() ? - self.assertRaises(InvalidGitRepositoryError, rm.update, recursive=False, force_remove=False) + self.assertRaises( + InvalidGitRepositoryError, rm.update, recursive=False, force_remove=False + ) rm.update(recursive=False, force_remove=True) assert not osp.isdir(smp) # 'apply work' to the nested submodule and assure this is not removed/altered during updates # Need to commit first, otherwise submodule.update wouldn't have a reason to change the head - touch(osp.join(nsm.module().working_tree_dir, 'new-file')) + touch(osp.join(nsm.module().working_tree_dir, "new-file")) # We cannot expect is_dirty to even run as we wouldn't reset a head to the same location assert nsm.module().head.commit.hexsha == nsm.hexsha nsm.module().index.add([nsm]) nsm.module().index.commit("added new file") - rm.update(recursive=False, dry_run=True, progress=prog) # would not change head, and thus doesn't fail + rm.update( + recursive=False, dry_run=True, progress=prog + ) # would not change head, and thus doesn't fail # Everything we can do from now on will trigger the 'future' check, so no is_dirty() check will even run # This would only run if our local branch is in the past and we have uncommitted changes prev_commit = nsm.module().head.commit rm.update(recursive=False, dry_run=False, progress=prog) - assert prev_commit == nsm.module().head.commit, "head shouldn't change, as it is in future of remote branch" + assert ( + prev_commit == nsm.module().head.commit + ), "head shouldn't change, as it is in future of remote branch" # this kills the new file rm.update(recursive=True, progress=prog, force_reset=True) - assert prev_commit != nsm.module().head.commit, "head changed, as the remote url and its commit changed" + assert ( + prev_commit != nsm.module().head.commit + ), "head changed, as the remote url and its commit changed" # change url ... - #=============== + # =============== # ... to the first repository, this way we have a fast checkout, and a completely different # repository at the different url nsm.set_parent_commit(csmremoved) nsmurl = Git.polish_url(osp.join(self.rorepo.working_tree_dir, rsmsp[0])) with nsm.config_writer() as writer: - writer.set_value('url', nsmurl) + writer.set_value("url", nsmurl) csmpathchange = rwrepo.index.commit("changed url") nsm.set_parent_commit(csmpathchange) @@ -579,7 +643,9 @@ class TestSubmodule(TestBase): assert nsm.module().remotes.origin.url == nsmurl assert prev_commit != nsm.module().head.commit, "Should now point to gitdb" assert len(rwrepo.submodules) == 1 - assert not rwrepo.submodules[0].children()[0].module_exists(), "nested submodule should not be checked out" + assert ( + not rwrepo.submodules[0].children()[0].module_exists() + ), "nested submodule should not be checked out" # add the submodule's changed commit to the index, which is what the # user would do @@ -588,7 +654,7 @@ class TestSubmodule(TestBase): rwrepo.index.add([nsm]) # change branch - #================= + # ================= # we only have one branch, so we switch to a virtual one, and back # to the current one to trigger the difference cur_branch = nsm.branch @@ -603,7 +669,7 @@ class TestSubmodule(TestBase): # Lets remove our tracking branch to simulate some changes nsmmh = nsmm.head - assert nsmmh.ref.tracking_branch() is None # never set it up until now + assert nsmmh.ref.tracking_branch() is None # never set it up until now assert not nsmmh.is_detached # dry run does nothing @@ -625,8 +691,8 @@ class TestSubmodule(TestBase): # assure we pull locally only nsmc = nsm.children()[0] with nsmc.config_writer() as writer: - writer.set_value('url', subrepo_url) - rm.update(recursive=True, progress=prog, dry_run=True) # just to run the code + writer.set_value("url", subrepo_url) + rm.update(recursive=True, progress=prog, dry_run=True) # just to run the code rm.update(recursive=True, progress=prog) # gitdb: has either 1 or 2 submodules depending on the version @@ -636,41 +702,57 @@ class TestSubmodule(TestBase): def test_first_submodule(self, rwrepo): assert len(list(rwrepo.iter_submodules())) == 0 - for sm_name, sm_path in (('first', 'submodules/first'), - ('second', osp.join(rwrepo.working_tree_dir, 'submodules/second'))): - sm = rwrepo.create_submodule(sm_name, sm_path, rwrepo.git_dir, no_checkout=True) + for sm_name, sm_path in ( + ("first", "submodules/first"), + ("second", osp.join(rwrepo.working_tree_dir, "submodules/second")), + ): + sm = rwrepo.create_submodule( + sm_name, sm_path, rwrepo.git_dir, no_checkout=True + ) assert sm.exists() and sm.module_exists() rwrepo.index.commit("Added submodule " + sm_name) # end for each submodule path to add - self.assertRaises(ValueError, rwrepo.create_submodule, 'fail', osp.expanduser('~')) - self.assertRaises(ValueError, rwrepo.create_submodule, 'fail-too', - rwrepo.working_tree_dir + osp.sep) + self.assertRaises( + ValueError, rwrepo.create_submodule, "fail", osp.expanduser("~") + ) + self.assertRaises( + ValueError, + rwrepo.create_submodule, + "fail-too", + rwrepo.working_tree_dir + osp.sep, + ) @with_rw_directory def test_add_empty_repo(self, rwdir): - empty_repo_dir = osp.join(rwdir, 'empty-repo') + empty_repo_dir = osp.join(rwdir, "empty-repo") - parent = git.Repo.init(osp.join(rwdir, 'parent')) + parent = git.Repo.init(osp.join(rwdir, "parent")) git.Repo.init(empty_repo_dir) for checkout_mode in range(2): - name = 'empty' + str(checkout_mode) - self.assertRaises(ValueError, parent.create_submodule, name, name, - url=empty_repo_dir, no_checkout=checkout_mode and True or False) + name = "empty" + str(checkout_mode) + self.assertRaises( + ValueError, + parent.create_submodule, + name, + name, + url=empty_repo_dir, + no_checkout=checkout_mode and True or False, + ) # end for each checkout mode @with_rw_directory def test_list_only_valid_submodules(self, rwdir): - repo_path = osp.join(rwdir, 'parent') + repo_path = osp.join(rwdir, "parent") repo = git.Repo.init(repo_path) - repo.git.submodule('add', self._small_repo_url(), 'module') + repo.git.submodule("add", self._small_repo_url(), "module") repo.index.commit("add submodule") assert len(repo.submodules) == 1 # Delete the directory from submodule - submodule_path = osp.join(repo_path, 'module') + submodule_path = osp.join(repo_path, "module") shutil.rmtree(submodule_path) repo.git.add([submodule_path]) repo.index.commit("remove submodule") @@ -678,18 +760,20 @@ class TestSubmodule(TestBase): repo = git.Repo(repo_path) assert len(repo.submodules) == 0 - @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, - """FIXME on cygwin: File "C:\\projects\\gitpython\\git\\cmd.py", line 671, in execute + @skipIf( + HIDE_WINDOWS_KNOWN_ERRORS, + """FIXME on cygwin: File "C:\\projects\\gitpython\\git\\cmd.py", line 671, in execute raise GitCommandError(command, status, stderr_value, stdout_value) GitCommandError: Cmd('git') failed due to: exit code(128) cmdline: git add 1__Xava verbXXten 1_test _myfile 1_test_other_file 1_XXava-----verbXXten stderr: 'fatal: pathspec '"1__çava verböten"' did not match any files' FIXME on appveyor: see https://ci.appveyor.com/project/Byron/gitpython/build/1.0.185 - """) + """, + ) @with_rw_directory def test_git_submodules_and_add_sm_with_new_commit(self, rwdir): - parent = git.Repo.init(osp.join(rwdir, 'parent')) - parent.git.submodule('add', self._small_repo_url(), 'module') + parent = git.Repo.init(osp.join(rwdir, "parent")) + parent.git.submodule("add", self._small_repo_url(), "module") parent.index.commit("added submodule") assert len(parent.submodules) == 1 @@ -697,9 +781,11 @@ class TestSubmodule(TestBase): assert sm.exists() and sm.module_exists() - clone = git.Repo.clone_from(self._small_repo_url(), - osp.join(parent.working_tree_dir, 'existing-subrepository')) - sm2 = parent.create_submodule('nongit-file-submodule', clone.working_tree_dir) + clone = git.Repo.clone_from( + self._small_repo_url(), + osp.join(parent.working_tree_dir, "existing-subrepository"), + ) + sm2 = parent.create_submodule("nongit-file-submodule", clone.working_tree_dir) assert len(parent.submodules) == 2 for _ in range(2): @@ -709,26 +795,28 @@ class TestSubmodule(TestBase): # end for each init state # end for each iteration - sm.move(sm.path + '_moved') - sm2.move(sm2.path + '_moved') + sm.move(sm.path + "_moved") + sm2.move(sm2.path + "_moved") parent.index.commit("moved submodules") with sm.config_writer() as writer: - writer.set_value('user.email', 'example@example.com') - writer.set_value('user.name', 'me') + writer.set_value("user.email", "example@example.com") + writer.set_value("user.name", "me") smm = sm.module() - fp = osp.join(smm.working_tree_dir, 'empty-file') - with open(fp, 'w'): + fp = osp.join(smm.working_tree_dir, "empty-file") + with open(fp, "w"): pass smm.git.add(Git.polish_url(fp)) smm.git.commit(m="new file added") # submodules are retrieved from the current commit's tree, therefore we can't really get a new submodule # object pointing to the new submodule commit - sm_too = parent.submodules['module_moved'] + sm_too = parent.submodules["module_moved"] assert parent.head.commit.tree[sm.path].binsha == sm.binsha - assert sm_too.binsha == sm.binsha, "cached submodule should point to the same commit as updated one" + assert ( + sm_too.binsha == sm.binsha + ), "cached submodule should point to the same commit as updated one" added_bies = parent.index.add([sm]) # added base-index-entries assert len(added_bies) == 1 @@ -751,21 +839,24 @@ class TestSubmodule(TestBase): # "'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\test_work_tree_unsupportedryfa60di\\master_repo\\.git\\objects\\pack\\pack-bc9e0787aef9f69e1591ef38ea0a6f566ec66fe3.idx") # noqa E501 @with_rw_directory def test_git_submodule_compatibility(self, rwdir): - parent = git.Repo.init(osp.join(rwdir, 'parent')) - sm_path = join_path_native('submodules', 'intermediate', 'one') - sm = parent.create_submodule('mymodules/myname', sm_path, url=self._small_repo_url()) + parent = git.Repo.init(osp.join(rwdir, "parent")) + sm_path = join_path_native("submodules", "intermediate", "one") + sm = parent.create_submodule( + "mymodules/myname", sm_path, url=self._small_repo_url() + ) parent.index.commit("added submodule") def assert_exists(sm, value=True): assert sm.exists() == value assert sm.module_exists() == value + # end # As git is backwards compatible itself, it would still recognize what we do here ... unless we really # muss it up. That's the only reason why the test is still here ... . assert len(parent.git.submodule().splitlines()) == 1 - module_repo_path = osp.join(sm.module().working_tree_dir, '.git') + module_repo_path = osp.join(sm.module().working_tree_dir, ".git") assert module_repo_path.startswith(osp.join(parent.working_tree_dir, sm_path)) if not sm._need_gitfile_submodules(parent.git): assert osp.isdir(module_repo_path) @@ -773,17 +864,22 @@ class TestSubmodule(TestBase): else: assert osp.isfile(module_repo_path) assert sm.module().has_separate_working_tree() - assert find_submodule_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid" + assert ( + find_submodule_git_dir(module_repo_path) is not None + ), "module pointed to by .git file must be valid" # end verify submodule 'style' # test move - new_sm_path = join_path_native('submodules', 'one') + new_sm_path = join_path_native("submodules", "one") sm.move(new_sm_path) assert_exists(sm) # Add additional submodule level - csm = sm.module().create_submodule('nested-submodule', join_path_native('nested-submodule', 'working-tree'), - url=self._small_repo_url()) + csm = sm.module().create_submodule( + "nested-submodule", + join_path_native("nested-submodule", "working-tree"), + url=self._small_repo_url(), + ) sm.module().index.commit("added nested submodule") sm_head_commit = sm.module().commit() assert_exists(csm) @@ -796,24 +892,36 @@ class TestSubmodule(TestBase): # rename nested submodule # This name would move itself one level deeper - needs special handling internally - new_name = csm.name + '/mine' + new_name = csm.name + "/mine" assert csm.rename(new_name).name == new_name assert_exists(csm) - assert csm.repo.is_dirty(index=True, working_tree=False), "index must contain changed .gitmodules file" + assert csm.repo.is_dirty( + index=True, working_tree=False + ), "index must contain changed .gitmodules file" csm.repo.index.commit("renamed module") # keep_going evaluation rsm = parent.submodule_update() assert_exists(sm) assert_exists(csm) - with csm.config_writer().set_value('url', 'bar'): + with csm.config_writer().set_value("url", "bar"): pass - csm.repo.index.commit("Have to commit submodule change for algorithm to pick it up") - assert csm.url == 'bar' - - self.assertRaises(Exception, rsm.update, recursive=True, to_latest_revision=True, progress=prog) + csm.repo.index.commit( + "Have to commit submodule change for algorithm to pick it up" + ) + assert csm.url == "bar" + + self.assertRaises( + Exception, + rsm.update, + recursive=True, + to_latest_revision=True, + progress=prog, + ) assert_exists(csm) - rsm.update(recursive=True, to_latest_revision=True, progress=prog, keep_going=True) + rsm.update( + recursive=True, to_latest_revision=True, progress=prog, keep_going=True + ) # remove sm_module_path = sm.module().git_dir @@ -826,8 +934,8 @@ class TestSubmodule(TestBase): @with_rw_directory def test_remove_norefs(self, rwdir): - parent = git.Repo.init(osp.join(rwdir, 'parent')) - sm_name = 'mymodules/myname' + parent = git.Repo.init(osp.join(rwdir, "parent")) + sm_name = "mymodules/myname" sm = parent.create_submodule(sm_name, sm_name, url=self._small_repo_url()) assert sm.exists() @@ -835,24 +943,26 @@ class TestSubmodule(TestBase): assert sm.repo is parent # yoh was surprised since expected sm repo!! # so created a new instance for submodule - smrepo = git.Repo(osp.join(rwdir, 'parent', sm.path)) + smrepo = git.Repo(osp.join(rwdir, "parent", sm.path)) # Adding a remote without fetching so would have no references - smrepo.create_remote('special', 'git@server-shouldnotmatter:repo.git') + smrepo.create_remote("special", "git@server-shouldnotmatter:repo.git") # And we should be able to remove it just fine sm.remove() assert not sm.exists() @with_rw_directory def test_rename(self, rwdir): - parent = git.Repo.init(osp.join(rwdir, 'parent')) - sm_name = 'mymodules/myname' + parent = git.Repo.init(osp.join(rwdir, "parent")) + sm_name = "mymodules/myname" sm = parent.create_submodule(sm_name, sm_name, url=self._small_repo_url()) parent.index.commit("Added submodule") assert sm.rename(sm_name) is sm and sm.name == sm_name - assert not sm.repo.is_dirty(index=True, working_tree=False, untracked_files=False) + assert not sm.repo.is_dirty( + index=True, working_tree=False, untracked_files=False + ) - new_path = 'renamed/myname' + new_path = "renamed/myname" assert sm.move(new_path).name == new_path new_sm_name = "shortname" @@ -861,8 +971,12 @@ class TestSubmodule(TestBase): assert sm.exists() sm_mod = sm.module() - if osp.isfile(osp.join(sm_mod.working_tree_dir, '.git')) == sm._need_gitfile_submodules(parent.git): - assert sm_mod.git_dir.endswith(join_path_native('.git', 'modules', new_sm_name)) + if osp.isfile( + osp.join(sm_mod.working_tree_dir, ".git") + ) == sm._need_gitfile_submodules(parent.git): + assert sm_mod.git_dir.endswith( + join_path_native(".git", "modules", new_sm_name) + ) # end @with_rw_directory @@ -870,33 +984,41 @@ class TestSubmodule(TestBase): # Setup initial sandbox: # parent repo has one submodule, which has all the latest changes source_url = self._small_repo_url() - sm_source_repo = git.Repo.clone_from(source_url, osp.join(rw_dir, 'sm-source'), b='master') - parent_repo = git.Repo.init(osp.join(rw_dir, 'parent')) - sm = parent_repo.create_submodule('mysubmodule', 'subdir/submodule', - sm_source_repo.working_tree_dir, branch='master') - parent_repo.index.commit('added submodule') + sm_source_repo = git.Repo.clone_from( + source_url, osp.join(rw_dir, "sm-source"), b="master" + ) + parent_repo = git.Repo.init(osp.join(rw_dir, "parent")) + sm = parent_repo.create_submodule( + "mysubmodule", + "subdir/submodule", + sm_source_repo.working_tree_dir, + branch="master", + ) + parent_repo.index.commit("added submodule") assert sm.exists() # Create feature branch with one new commit in submodule source - sm_fb = sm_source_repo.create_head('feature') + sm_fb = sm_source_repo.create_head("feature") sm_fb.checkout() - new_file = touch(osp.join(sm_source_repo.working_tree_dir, 'new-file')) + new_file = touch(osp.join(sm_source_repo.working_tree_dir, "new-file")) sm_source_repo.index.add([new_file]) sm.repo.index.commit("added new file") # change designated submodule checkout branch to the new upstream feature branch with sm.config_writer() as smcw: - smcw.set_value('branch', sm_fb.name) + smcw.set_value("branch", sm_fb.name) assert sm.repo.is_dirty(index=True, working_tree=False) sm.repo.index.commit("changed submodule branch to '%s'" % sm_fb) # verify submodule update with feature branch that leaves currently checked out branch in it's past sm_mod = sm.module() prev_commit = sm_mod.commit() - assert sm_mod.head.ref.name == 'master' + assert sm_mod.head.ref.name == "master" assert parent_repo.submodule_update() assert sm_mod.head.ref.name == sm_fb.name - assert sm_mod.commit() == prev_commit, "Without to_latest_revision, we don't change the commit" + assert ( + sm_mod.commit() == prev_commit + ), "Without to_latest_revision, we don't change the commit" assert parent_repo.submodule_update(to_latest_revision=True) assert sm_mod.head.ref.name == sm_fb.name @@ -904,25 +1026,29 @@ class TestSubmodule(TestBase): # Create new branch which is in our past, and thus seemingly unrelated to the currently checked out one # To make it even 'harder', we shall fork and create a new commit - sm_pfb = sm_source_repo.create_head('past-feature', commit='HEAD~20') + sm_pfb = sm_source_repo.create_head("past-feature", commit="HEAD~20") sm_pfb.checkout() - sm_source_repo.index.add([touch(osp.join(sm_source_repo.working_tree_dir, 'new-file'))]) + sm_source_repo.index.add( + [touch(osp.join(sm_source_repo.working_tree_dir, "new-file"))] + ) sm_source_repo.index.commit("new file added, to past of '%r'" % sm_fb) # Change designated submodule checkout branch to a new commit in its own past with sm.config_writer() as smcw: - smcw.set_value('branch', sm_pfb.path) + smcw.set_value("branch", sm_pfb.path) sm.repo.index.commit("changed submodule branch to '%s'" % sm_pfb) # Test submodule updates - must fail if submodule is dirty - touch(osp.join(sm_mod.working_tree_dir, 'unstaged file')) + touch(osp.join(sm_mod.working_tree_dir, "unstaged file")) # This doesn't fail as our own submodule binsha didn't change, and the reset is only triggered if # to latest revision is True. parent_repo.submodule_update(to_latest_revision=False) sm_mod.head.ref.name == sm_pfb.name, "should have been switched to past head" sm_mod.commit() == sm_fb.commit, "Head wasn't reset" - self.assertRaises(RepositoryDirtyError, parent_repo.submodule_update, to_latest_revision=True) + self.assertRaises( + RepositoryDirtyError, parent_repo.submodule_update, to_latest_revision=True + ) parent_repo.submodule_update(to_latest_revision=True, force_reset=True) assert sm_mod.commit() == sm_pfb.commit, "Now head should have been reset" assert sm_mod.head.ref.name == sm_pfb.name @@ -930,83 +1056,116 @@ class TestSubmodule(TestBase): @skipIf(not is_win, "Specifically for Windows.") def test_to_relative_path_with_super_at_root_drive(self): class Repo(object): - working_tree_dir = 'D:\\' + working_tree_dir = "D:\\" + super_repo = Repo() - submodule_path = 'D:\\submodule_path' + submodule_path = "D:\\submodule_path" relative_path = Submodule._to_relative_path(super_repo, submodule_path) - msg = '_to_relative_path should be "submodule_path" but was "%s"' % relative_path - assert relative_path == 'submodule_path', msg - - @skipIf(True, 'for some unknown reason the assertion fails, even though it in fact is working in more common setup') + msg = ( + '_to_relative_path should be "submodule_path" but was "%s"' % relative_path + ) + assert relative_path == "submodule_path", msg + + @skipIf( + True, + "for some unknown reason the assertion fails, even though it in fact is working in more common setup", + ) @with_rw_directory def test_depth(self, rwdir): - parent = git.Repo.init(osp.join(rwdir, 'test_depth')) - sm_name = 'mymodules/myname' + parent = git.Repo.init(osp.join(rwdir, "test_depth")) + sm_name = "mymodules/myname" sm_depth = 1 - sm = parent.create_submodule(sm_name, sm_name, url=self._small_repo_url(), depth=sm_depth) + sm = parent.create_submodule( + sm_name, sm_name, url=self._small_repo_url(), depth=sm_depth + ) self.assertEqual(len(list(sm.module().iter_commits())), sm_depth) @with_rw_directory def test_update_clone_multi_options_argument(self, rwdir): - #Arrange - parent = git.Repo.init(osp.join(rwdir, 'parent')) - sm_name = 'foo' + # Arrange + parent = git.Repo.init(osp.join(rwdir, "parent")) + sm_name = "foo" sm_url = self._small_repo_url() - sm_branch = 'refs/heads/master' + sm_branch = "refs/heads/master" sm_hexsha = git.Repo(self._small_repo_url()).head.commit.hexsha - sm = Submodule(parent, bytes.fromhex(sm_hexsha), name=sm_name, path=sm_name, url=sm_url, - branch_path=sm_branch) - - #Act - sm.update(init=True, clone_multi_options=['--config core.eol=true']) - - #Assert - sm_config = GitConfigParser(file_or_files=osp.join(parent.git_dir, 'modules', sm_name, 'config')) - self.assertTrue(sm_config.get_value('core', 'eol')) + sm = Submodule( + parent, + bytes.fromhex(sm_hexsha), + name=sm_name, + path=sm_name, + url=sm_url, + branch_path=sm_branch, + ) + + # Act + sm.update(init=True, clone_multi_options=["--config core.eol=true"]) + + # Assert + sm_config = GitConfigParser( + file_or_files=osp.join(parent.git_dir, "modules", sm_name, "config") + ) + self.assertTrue(sm_config.get_value("core", "eol")) @with_rw_directory def test_update_no_clone_multi_options_argument(self, rwdir): - #Arrange - parent = git.Repo.init(osp.join(rwdir, 'parent')) - sm_name = 'foo' + # Arrange + parent = git.Repo.init(osp.join(rwdir, "parent")) + sm_name = "foo" sm_url = self._small_repo_url() - sm_branch = 'refs/heads/master' + sm_branch = "refs/heads/master" sm_hexsha = git.Repo(self._small_repo_url()).head.commit.hexsha - sm = Submodule(parent, bytes.fromhex(sm_hexsha), name=sm_name, path=sm_name, url=sm_url, - branch_path=sm_branch) - - #Act + sm = Submodule( + parent, + bytes.fromhex(sm_hexsha), + name=sm_name, + path=sm_name, + url=sm_url, + branch_path=sm_branch, + ) + + # Act sm.update(init=True) - #Assert - sm_config = GitConfigParser(file_or_files=osp.join(parent.git_dir, 'modules', sm_name, 'config')) + # Assert + sm_config = GitConfigParser( + file_or_files=osp.join(parent.git_dir, "modules", sm_name, "config") + ) with self.assertRaises(cp.NoOptionError): - sm_config.get_value('core', 'eol') + sm_config.get_value("core", "eol") @with_rw_directory def test_add_clone_multi_options_argument(self, rwdir): - #Arrange - parent = git.Repo.init(osp.join(rwdir, 'parent')) - sm_name = 'foo' - - #Act - Submodule.add(parent, sm_name, sm_name, url=self._small_repo_url(), - clone_multi_options=['--config core.eol=true']) - - #Assert - sm_config = GitConfigParser(file_or_files=osp.join(parent.git_dir, 'modules', sm_name, 'config')) - self.assertTrue(sm_config.get_value('core', 'eol')) + # Arrange + parent = git.Repo.init(osp.join(rwdir, "parent")) + sm_name = "foo" + + # Act + Submodule.add( + parent, + sm_name, + sm_name, + url=self._small_repo_url(), + clone_multi_options=["--config core.eol=true"], + ) + + # Assert + sm_config = GitConfigParser( + file_or_files=osp.join(parent.git_dir, "modules", sm_name, "config") + ) + self.assertTrue(sm_config.get_value("core", "eol")) @with_rw_directory def test_add_no_clone_multi_options_argument(self, rwdir): - #Arrange - parent = git.Repo.init(osp.join(rwdir, 'parent')) - sm_name = 'foo' + # Arrange + parent = git.Repo.init(osp.join(rwdir, "parent")) + sm_name = "foo" - #Act + # Act Submodule.add(parent, sm_name, sm_name, url=self._small_repo_url()) - #Assert - sm_config = GitConfigParser(file_or_files=osp.join(parent.git_dir, 'modules', sm_name, 'config')) + # Assert + sm_config = GitConfigParser( + file_or_files=osp.join(parent.git_dir, "modules", sm_name, "config") + ) with self.assertRaises(cp.NoOptionError): - sm_config.get_value('core', 'eol') + sm_config.get_value("core", "eol") |