diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index cbf6cd0db..f0b8babca 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -316,7 +316,8 @@ def _write_git_file_and_module_config(cls, working_tree_dir, module_abspath): #{ Edit Interface @classmethod - def add(cls, repo, name, path, url=None, branch=None, no_checkout=False, depth=None, env=None): + def add(cls, repo, name, path, url=None, branch=None, no_checkout=False, depth=None, env=None, + clone_multi_options=None): """Add a new submodule to the given repository. This will alter the index as well as the .gitmodules file, but will not create a new commit. If the submodule already exists, no matter if the configuration differs @@ -349,6 +350,8 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False, depth=N and is defined in `os.environ`, value from `os.environ` will be used. If you want to unset some variable, consider providing empty string as its value. + :param clone_multi_options: A list of Clone options. Please see ``git.repo.base.Repo.clone`` + for details. :return: The newly created submodule instance :note: works atomically, such that no change will be done if the repository update fails for instance""" @@ -415,6 +418,8 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False, depth=N kwargs['depth'] = depth else: raise ValueError("depth should be an integer") + if clone_multi_options: + kwargs['multi_options'] = clone_multi_options # _clone_repo(cls, repo, url, path, name, **kwargs): mrepo = cls._clone_repo(repo, url, path, name, env=env, **kwargs) @@ -449,7 +454,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False, depth=N return sm def update(self, recursive=False, init=True, to_latest_revision=False, progress=None, dry_run=False, - force=False, keep_going=False, env=None): + force=False, keep_going=False, env=None, clone_multi_options=None): """Update the repository of this submodule to point to the checkout we point at with the binsha of this instance. @@ -480,6 +485,8 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= and is defined in `os.environ`, value from `os.environ` will be used. If you want to unset some variable, consider providing empty string as its value. + :param clone_multi_options: list of Clone options. Please see ``git.repo.base.Repo.clone`` + for details. Only take effect with `init` option. :note: does nothing in bare repositories :note: method is definitely not atomic if recurisve is True :return: self""" @@ -546,7 +553,8 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= progress.update(BEGIN | CLONE, 0, 1, prefix + "Cloning url '%s' to '%s' in submodule %r" % (self.url, checkout_module_abspath, self.name)) if not dry_run: - mrepo = self._clone_repo(self.repo, self.url, self.path, self.name, n=True, env=env) + mrepo = self._clone_repo(self.repo, self.url, self.path, self.name, n=True, env=env, + multi_options=clone_multi_options) # END handle dry-run progress.update(END | CLONE, 0, 1, prefix + "Done cloning to %s" % checkout_module_abspath) diff --git a/test/test_submodule.py b/test/test_submodule.py index eb821b54e..85191a896 100644 --- a/test/test_submodule.py +++ b/test/test_submodule.py @@ -9,6 +9,7 @@ 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 @@ -945,3 +946,68 @@ def test_depth(self, rwdir): sm_depth = 1 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' + sm_url = self._small_repo_url() + 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')) + + @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' + sm_url = self._small_repo_url() + 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) + + #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') + + @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')) + + @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' + + #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')) + with self.assertRaises(cp.NoOptionError): + sm_config.get_value('core', 'eol')