diff --git a/AUTHORS b/AUTHORS index d2483dd42..4dd1f8a75 100644 --- a/AUTHORS +++ b/AUTHORS @@ -29,5 +29,6 @@ Contributors are: -Tim Swast -William Luc Ritchie -David Host +-Steven Whitman Portions derived from other open source works and are clearly marked. diff --git a/git/repo/base.py b/git/repo/base.py index 58f11e51e..66cc199ba 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -931,7 +931,7 @@ def init(cls, path=None, mkdir=True, odbt=GitCmdObjectDB, expand_vars=True, **kw return cls(path, odbt=odbt) @classmethod - def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): + def _clone(cls, git, url, path, odb_default_type, progress, multi_options=None, **kwargs): if progress is not None: progress = to_progress_instance(progress) @@ -953,7 +953,10 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): sep_dir = kwargs.get('separate_git_dir') if sep_dir: kwargs['separate_git_dir'] = Git.polish_url(sep_dir) - proc = git.clone(Git.polish_url(url), clone_path, with_extended_output=True, as_process=True, + multi = None + if multi_options: + multi = ' '.join(multi_options).split(' ') + proc = git.clone(multi, Git.polish_url(url), clone_path, with_extended_output=True, as_process=True, v=True, universal_newlines=True, **add_progress(kwargs, git, progress)) if progress: handle_process_output(proc, None, progress.new_message_handler(), finalize_process, decode_streams=False) @@ -983,33 +986,38 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): # END handle remote repo return repo - def clone(self, path, progress=None, **kwargs): + def clone(self, path, progress=None, multi_options=None, **kwargs): """Create a clone from this repository. :param path: is the full path of the new repo (traditionally ends with ./.git). :param progress: See 'git.remote.Remote.push'. + :param multi_options: A list of Clone options that can be provided multiple times. One + option per list item which is passed exactly as specified to clone. + For example ['--config core.filemode=false', '--config core.ignorecase', + '--recurse-submodule=repo1_path', '--recurse-submodule=repo2_path'] :param kwargs: * odbt = ObjectDatabase Type, allowing to determine the object database implementation used by the returned Repo instance * All remaining keyword arguments are given to the git-clone command :return: ``git.Repo`` (the newly cloned repo)""" - return self._clone(self.git, self.common_dir, path, type(self.odb), progress, **kwargs) + return self._clone(self.git, self.common_dir, path, type(self.odb), progress, multi_options, **kwargs) @classmethod - def clone_from(cls, url, to_path, progress=None, env=None, **kwargs): + def clone_from(cls, url, to_path, progress=None, env=None, multi_options=None, **kwargs): """Create a clone from the given URL :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS :param to_path: Path to which the repository should be cloned to :param progress: See 'git.remote.Remote.push'. :param env: Optional dictionary containing the desired environment variables. + :param mutli_options: See ``clone`` method :param kwargs: see the ``clone`` method :return: Repo instance pointing to the cloned directory""" git = Git(os.getcwd()) if env is not None: git.update_environment(**env) - return cls._clone(git, url, to_path, GitCmdObjectDB, progress, **kwargs) + return cls._clone(git, url, to_path, GitCmdObjectDB, progress, multi_options, **kwargs) def archive(self, ostream, treeish=None, prefix=None, **kwargs): """Archive the tree at the given revision. diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 7fc49f3b1..0577bd589 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -229,6 +229,22 @@ def test_clone_from_pathlib(self, rw_dir): Repo.clone_from(original_repo.git_dir, pathlib.Path(rw_dir) / "clone_pathlib") + @with_rw_directory + def test_clone_from_pathlib_withConfig(self, rw_dir): + if pathlib is None: # pythons bellow 3.4 don't have pathlib + raise SkipTest("pathlib was introduced in 3.4") + + original_repo = Repo.init(osp.join(rw_dir, "repo")) + + cloned = Repo.clone_from(original_repo.git_dir, pathlib.Path(rw_dir) / "clone_pathlib_withConfig", + multi_options=["--recurse-submodules=repo", + "--config core.filemode=false", + "--config submodule.repo.update=checkout"]) + + assert_equal(cloned.config_reader().get_value('submodule', 'active'), 'repo') + assert_equal(cloned.config_reader().get_value('core', 'filemode'), False) + assert_equal(cloned.config_reader().get_value('submodule "repo"', 'update'), 'checkout') + @with_rw_repo('HEAD') def test_max_chunk_size(self, repo): class TestOutputStream(object):