Skip to content

Commit 19be4b6

Browse files
committed
clone: wrap clone_into()
This allows the user to prepare the repository and remote with whichever custom settings they want before performing the "clone" proper.
1 parent 06b7438 commit 19be4b6

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

pygit2/__init__.py

+23
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,27 @@ def clone_repository(
129129

130130
return Repository(path)
131131

132+
def clone_into(repo, remote, branch=None):
133+
"""Clone into an empty repository from the specified remote
134+
135+
:param Repository repo: The empty repository into which to clone
136+
137+
:param Remote remote: The remote from which to clone
138+
139+
:param str branch: Branch to checkout after the clone. Pass None
140+
to use the remotes's default branch.
141+
142+
This allows you specify arbitrary repository and remote configurations
143+
before performing the clone step itself. E.g. you can replicate git-clone's
144+
'--mirror' option by setting a refspec of '+refs/*:refs/*', 'core.mirror' to true
145+
and calling this function.
146+
"""
147+
148+
err = C.git_clone_into(repo._repo, remote._remote, ffi.NULL, to_str(branch))
149+
150+
if remote._stored_exception:
151+
raise remote._stored_exception
152+
153+
check_error(err)
154+
132155
settings = Settings()

pygit2/decl.h

+1
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ int git_clone(git_repository **out,
216216
const char *local_path,
217217
const git_clone_options *options);
218218

219+
int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch);
219220

220221
typedef enum {
221222
GIT_CONFIG_LEVEL_SYSTEM = 1,

test/test_repository.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
# Import from pygit2
4242
from pygit2 import GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT
43-
from pygit2 import init_repository, clone_repository, discover_repository
43+
from pygit2 import init_repository, clone_repository, clone_into, discover_repository
4444
from pygit2 import Oid, Reference, hashfile
4545
import pygit2
4646
from . import utils
@@ -461,6 +461,13 @@ def test_clone_remote_name(self):
461461
self.assertFalse(repo.is_empty)
462462
self.assertEqual(repo.remotes[0].name, "custom_remote")
463463

464+
def test_clone_into(self):
465+
repo_path = "./test/data/testrepo.git/"
466+
repo = init_repository(os.path.join(self._temp_dir, "clone-into"))
467+
remote = repo.create_remote("origin", 'file://' + os.path.realpath(repo_path))
468+
clone_into(repo, remote)
469+
self.assertTrue('refs/remotes/origin/master' in repo.listall_references())
470+
464471
def test_clone_with_credentials(self):
465472
credentials = pygit2.UserPass("libgit2", "libgit2")
466473
repo = clone_repository(

0 commit comments

Comments
 (0)