Skip to content

Commit b425301

Browse files
committed
Adjusted clone method to allow static classmethod clone ( using clone_from ) as well as the previous instance method clone to keep it compatible
Fixed small bug in test code
1 parent ca288d4 commit b425301

File tree

2 files changed

+44
-19
lines changed

2 files changed

+44
-19
lines changed

lib/git/repo/base.py

+29-18
Original file line numberDiff line numberDiff line change
@@ -606,26 +606,15 @@ def init(cls, path=None, mkdir=True, **kwargs):
606606
output = git.init(**kwargs)
607607
return Repo(path)
608608

609-
def clone(self, path, **kwargs):
610-
"""Create a clone from this repository.
611-
:param path:
612-
is the full path of the new repo (traditionally ends with ./<name>.git).
613-
614-
:param kwargs:
615-
odbt = ObjectDatabase Type, allowing to determine the object database
616-
implementation used by the returned Repo instance
617-
618-
All remaining keyword arguments are given to the git-clone command
619-
620-
:return:
621-
``git.Repo`` (the newly cloned repo)"""
609+
@classmethod
610+
def _clone(cls, git, url, path, odb_default_type, **kwargs):
622611
# special handling for windows for path at which the clone should be
623612
# created.
624613
# tilde '~' will be expanded to the HOME no matter where the ~ occours. Hence
625614
# we at least give a proper error instead of letting git fail
626615
prev_cwd = None
627616
prev_path = None
628-
odbt = kwargs.pop('odbt', type(self.odb))
617+
odbt = kwargs.pop('odbt', odb_default_type)
629618
if os.name == 'nt':
630619
if '~' in path:
631620
raise OSError("Git cannot handle the ~ character in path %r correctly" % path)
@@ -645,7 +634,7 @@ def clone(self, path, **kwargs):
645634
# END windows handling
646635

647636
try:
648-
self.git.clone(self.git_dir, path, **kwargs)
637+
git.clone(url, path, **kwargs)
649638
finally:
650639
if prev_cwd is not None:
651640
os.chdir(prev_cwd)
@@ -655,10 +644,32 @@ def clone(self, path, **kwargs):
655644

656645
# our git command could have a different working dir than our actual
657646
# environment, hence we prepend its working dir if required
658-
if not os.path.isabs(path) and self.git.working_dir:
659-
path = join(self.git._working_dir, path)
660-
return Repo(os.path.abspath(path), odbt = odbt)
647+
if not os.path.isabs(path) and git.working_dir:
648+
path = join(git._working_dir, path)
649+
return cls(os.path.abspath(path), odbt = odbt)
661650

651+
def clone(self, path, **kwargs):
652+
"""Create a clone from this repository.
653+
:param path:
654+
is the full path of the new repo (traditionally ends with ./<name>.git).
655+
656+
:param kwargs:
657+
odbt = ObjectDatabase Type, allowing to determine the object database
658+
implementation used by the returned Repo instance
659+
660+
All remaining keyword arguments are given to the git-clone command
661+
662+
:return: ``git.Repo`` (the newly cloned repo)"""
663+
return self._clone(self.git, self.git_dir, path, type(self.odb), **kwargs)
664+
665+
@classmethod
666+
def clone_from(cls, url, to_path, **kwargs):
667+
"""Create a clone from the given URL
668+
:param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS
669+
:param to_path: Path to which the repository should be cloned to
670+
:param **kwargs: see the ``clone`` method
671+
:return: Repo instance pointing to the cloned directory"""
672+
return cls._clone(Git(os.getcwd()), url, to_path, GitCmdObjectDB, **kwargs)
662673

663674
def archive(self, ostream, treeish=None, prefix=None, **kwargs):
664675
"""Archive the tree at the given revision.

test/git/test_repo.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,19 @@ def test_init(self):
145145
rc = r.clone(clone_path)
146146
self._assert_empty_repo(rc)
147147

148+
149+
try:
150+
shutil.rmtree(clone_path)
151+
except OSError:
152+
# when relative paths are used, the clone may actually be inside
153+
# of the parent directory
154+
pass
155+
# END exception handling
156+
157+
# try again, this time with the absolute version
158+
rc = Repo.clone_from(r.git_dir, clone_path)
159+
self._assert_empty_repo(rc)
160+
148161
shutil.rmtree(git_dir_abs)
149162
try:
150163
shutil.rmtree(clone_path)
@@ -153,6 +166,7 @@ def test_init(self):
153166
# of the parent directory
154167
pass
155168
# END exception handling
169+
156170
# END for each path
157171

158172
os.makedirs(git_dir_rela)
@@ -441,7 +455,7 @@ def _assert_rev_parse(self, name):
441455
for pn, parent in enumerate(obj.parents):
442456
rev = name + "^%i" % (pn+1)
443457
assert rev_parse(rev) == parent
444-
self._assert_rev_parse_types(rev, obj2)
458+
self._assert_rev_parse_types(rev, parent)
445459
# END for each parent
446460

447461
return orig_obj

0 commit comments

Comments
 (0)