Merge remote-tracking branch 'heynemann/master'
This commit is contained in:
@@ -20,6 +20,17 @@ Functions
|
|||||||
>>> repo = init_repository('test') # Creates a non-bare repository
|
>>> repo = init_repository('test') # Creates a non-bare repository
|
||||||
>>> repo = init_repository('test', bare=True) # Creates a bare repository
|
>>> repo = init_repository('test', bare=True) # Creates a bare repository
|
||||||
|
|
||||||
|
.. autofunction:: pygit2.clone_repository
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
>>> from pygit2 import clone_repository
|
||||||
|
>>> repo_url = 'git://github.com/libgit2/pygit2.git'
|
||||||
|
>>> repo_path = '/path/to/create/repository'
|
||||||
|
>>> repo = clone_repository(repo_url, repo_path) # Clones a non-bare repository
|
||||||
|
>>> repo = clone_repository(repo_url, repo_path, bare=True) # Clones a bare repository
|
||||||
|
|
||||||
|
|
||||||
.. autofunction:: pygit2.discover_repository
|
.. autofunction:: pygit2.discover_repository
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,3 +47,43 @@ def init_repository(path, bare=False):
|
|||||||
"""
|
"""
|
||||||
_pygit2.init_repository(path, bare)
|
_pygit2.init_repository(path, bare)
|
||||||
return Repository(path)
|
return Repository(path)
|
||||||
|
|
||||||
|
|
||||||
|
def clone_repository(
|
||||||
|
url, path, bare=False, remote_name="origin",
|
||||||
|
push_url=None, fetch_spec=None,
|
||||||
|
push_spec=None, checkout_branch=None):
|
||||||
|
"""
|
||||||
|
Clones a new Git repository from *url* in the given *path*.
|
||||||
|
|
||||||
|
**bare** indicates whether a bare git repository should be created.
|
||||||
|
|
||||||
|
**remote_name** is the name given to the "origin" remote.
|
||||||
|
The default is "origin".
|
||||||
|
|
||||||
|
**push_url** is a URL to be used for pushing.
|
||||||
|
None means use the *url* parameter.
|
||||||
|
|
||||||
|
**fetch_spec** defines the the default fetch spec.
|
||||||
|
None results in the same behavior as *GIT_REMOTE_DEFAULT_FETCH*.
|
||||||
|
|
||||||
|
**push_spec** is the fetch specification to be used for pushing.
|
||||||
|
None means use the same spec as for *fetch_spec*.
|
||||||
|
|
||||||
|
**checkout_branch** gives the name of the branch to checkout.
|
||||||
|
None means use the remote's *HEAD*.
|
||||||
|
|
||||||
|
Returns a Repository class pointing to the newly cloned repository.
|
||||||
|
|
||||||
|
If you wish to use the repo, you need to do a checkout for one of
|
||||||
|
the available branches, like this:
|
||||||
|
|
||||||
|
>>> repo = repo.clone_repository("url", "path")
|
||||||
|
>>> repo.checkout(branch) # i.e.: refs/heads/master
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
_pygit2.clone_repository(
|
||||||
|
url, path, bare, remote_name, push_url,
|
||||||
|
fetch_spec, push_spec, checkout_branch)
|
||||||
|
return Repository(path)
|
||||||
|
|||||||
65
src/pygit2.c
65
src/pygit2.c
@@ -97,6 +97,69 @@ init_repository(PyObject *self, PyObject *args) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PyDoc_STRVAR(clone_repository__doc__,
|
||||||
|
"clone_repository(url, path, bare, remote_name, push_url,"
|
||||||
|
"fetch_spec, push_spec, checkout_branch)\n"
|
||||||
|
"\n"
|
||||||
|
"Clones a Git repository in the given url to the given path "
|
||||||
|
"with the specified options.\n"
|
||||||
|
"\n"
|
||||||
|
"Arguments:\n"
|
||||||
|
"\n"
|
||||||
|
"url\n"
|
||||||
|
" Git repository remote url.\n"
|
||||||
|
"path\n"
|
||||||
|
" Path where to create the repository.\n"
|
||||||
|
"bare\n"
|
||||||
|
" If 'bare' is not 0, then a bare git repository will be created.\n"
|
||||||
|
"remote_name\n"
|
||||||
|
" The name given to the 'origin' remote. The default is 'origin'.\n"
|
||||||
|
"push_url\n"
|
||||||
|
" URL to be used for pushing.\n"
|
||||||
|
"fetch_spec\n"
|
||||||
|
" The fetch specification to be used for fetching. None results in "
|
||||||
|
"the same behavior as GIT_REMOTE_DEFAULT_FETCH.\n"
|
||||||
|
"push_spec\n"
|
||||||
|
" The fetch specification to be used for pushing. None means use the "
|
||||||
|
"same spec as for 'fetch_spec'\n"
|
||||||
|
"checkout_branch\n"
|
||||||
|
" The name of the branch to checkout. None means use the remote's "
|
||||||
|
"HEAD.\n");
|
||||||
|
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
clone_repository(PyObject *self, PyObject *args) {
|
||||||
|
git_repository *repo;
|
||||||
|
const char *url;
|
||||||
|
const char *path;
|
||||||
|
unsigned int bare;
|
||||||
|
const char *remote_name, *push_url, *fetch_spec;
|
||||||
|
const char *push_spec, *checkout_branch;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "zzIzzzzz",
|
||||||
|
&url, &path, &bare, &remote_name, &push_url,
|
||||||
|
&fetch_spec, &push_spec, &checkout_branch))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
git_clone_options opts = {
|
||||||
|
.version=1,
|
||||||
|
.bare=bare,
|
||||||
|
.remote_name=remote_name,
|
||||||
|
.pushurl=push_url,
|
||||||
|
.fetch_spec=fetch_spec,
|
||||||
|
.push_spec=push_spec,
|
||||||
|
.checkout_branch=checkout_branch
|
||||||
|
};
|
||||||
|
|
||||||
|
err = git_clone(&repo, url, path, &opts);
|
||||||
|
if (err < 0)
|
||||||
|
return Error_set_str(err, path);
|
||||||
|
|
||||||
|
git_repository_free(repo);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(discover_repository__doc__,
|
PyDoc_STRVAR(discover_repository__doc__,
|
||||||
"discover_repository(path[, across_fs[, ceiling_dirs]]) -> str\n"
|
"discover_repository(path[, across_fs[, ceiling_dirs]]) -> str\n"
|
||||||
@@ -172,6 +235,8 @@ hash(PyObject *self, PyObject *args)
|
|||||||
|
|
||||||
PyMethodDef module_methods[] = {
|
PyMethodDef module_methods[] = {
|
||||||
{"init_repository", init_repository, METH_VARARGS, init_repository__doc__},
|
{"init_repository", init_repository, METH_VARARGS, init_repository__doc__},
|
||||||
|
{"clone_repository", clone_repository, METH_VARARGS,
|
||||||
|
clone_repository__doc__},
|
||||||
{"discover_repository", discover_repository, METH_VARARGS,
|
{"discover_repository", discover_repository, METH_VARARGS,
|
||||||
discover_repository__doc__},
|
discover_repository__doc__},
|
||||||
{"hashfile", hashfile, METH_VARARGS, hashfile__doc__},
|
{"hashfile", hashfile, METH_VARARGS, hashfile__doc__},
|
||||||
|
|||||||
@@ -40,7 +40,10 @@ from os.path import join, realpath
|
|||||||
|
|
||||||
# Import from pygit2
|
# Import from pygit2
|
||||||
from pygit2 import GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT
|
from pygit2 import GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT
|
||||||
from pygit2 import init_repository, discover_repository, Reference, hashfile
|
from pygit2 import (
|
||||||
|
init_repository, clone_repository, discover_repository,
|
||||||
|
Reference, hashfile
|
||||||
|
)
|
||||||
from pygit2 import Oid
|
from pygit2 import Oid
|
||||||
import pygit2
|
import pygit2
|
||||||
from . import utils
|
from . import utils
|
||||||
@@ -101,7 +104,7 @@ class RepositoryTest(utils.BareRepoTestCase):
|
|||||||
self.assertFalse('a' * 20 in self.repo)
|
self.assertFalse('a' * 20 in self.repo)
|
||||||
|
|
||||||
def test_iterable(self):
|
def test_iterable(self):
|
||||||
l = [ obj for obj in self.repo ]
|
l = [obj for obj in self.repo]
|
||||||
oid = Oid(hex=BLOB_HEX)
|
oid = Oid(hex=BLOB_HEX)
|
||||||
self.assertTrue(oid in l)
|
self.assertTrue(oid in l)
|
||||||
|
|
||||||
@@ -135,7 +138,8 @@ class RepositoryTest(utils.BareRepoTestCase):
|
|||||||
commit = self.repo[commit_sha_prefix]
|
commit = self.repo[commit_sha_prefix]
|
||||||
self.assertEqual(commit_sha, commit.hex)
|
self.assertEqual(commit_sha, commit.hex)
|
||||||
self.assertEqual(GIT_OBJ_COMMIT, commit.type)
|
self.assertEqual(GIT_OBJ_COMMIT, commit.type)
|
||||||
self.assertEqual(('Second test data commit.\n\n'
|
self.assertEqual(
|
||||||
|
('Second test data commit.\n\n'
|
||||||
'This commit has some additional text.\n'),
|
'This commit has some additional text.\n'),
|
||||||
commit.message)
|
commit.message)
|
||||||
self.assertRaises(ValueError, self.repo.__getitem__, too_short_prefix)
|
self.assertRaises(ValueError, self.repo.__getitem__, too_short_prefix)
|
||||||
@@ -272,6 +276,7 @@ class InitRepositoryTest(utils.NoRepoTestCase):
|
|||||||
repo = init_repository(self._temp_dir, bare=True)
|
repo = init_repository(self._temp_dir, bare=True)
|
||||||
self.assertTrue(repo.is_bare)
|
self.assertTrue(repo.is_bare)
|
||||||
|
|
||||||
|
|
||||||
class DiscoverRepositoryTest(utils.NoRepoTestCase):
|
class DiscoverRepositoryTest(utils.NoRepoTestCase):
|
||||||
def test_discover_repo(self):
|
def test_discover_repo(self):
|
||||||
repo = init_repository(self._temp_dir, False)
|
repo = init_repository(self._temp_dir, False)
|
||||||
@@ -279,6 +284,7 @@ class DiscoverRepositoryTest(utils.NoRepoTestCase):
|
|||||||
os.makedirs(subdir)
|
os.makedirs(subdir)
|
||||||
self.assertEqual(repo.path, discover_repository(subdir))
|
self.assertEqual(repo.path, discover_repository(subdir))
|
||||||
|
|
||||||
|
|
||||||
class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
||||||
|
|
||||||
def test_is_empty(self):
|
def test_is_empty(self):
|
||||||
@@ -292,5 +298,69 @@ class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
|||||||
self.assertFalse(self.repo.head_is_detached)
|
self.assertFalse(self.repo.head_is_detached)
|
||||||
|
|
||||||
|
|
||||||
|
class CloneRepositoryTest(utils.NoRepoTestCase):
|
||||||
|
def test_clone_repository(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(repo_path, self._temp_dir)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
self.assertFalse(repo.is_bare)
|
||||||
|
|
||||||
|
def test_clone_bare_repository(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(repo_path, self._temp_dir, bare=True)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
self.assertTrue(repo.is_bare)
|
||||||
|
|
||||||
|
def test_clone_remote_name(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, remote_name="custom_remote"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
self.assertEqual(repo.remotes[0].name, "custom_remote")
|
||||||
|
|
||||||
|
def test_clone_push_url(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, push_url="custom_push_url"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
# FIXME: When pygit2 supports retrieving the pushurl parameter,
|
||||||
|
# enable this test
|
||||||
|
# self.assertEqual(repo.remotes[0].pushurl, "custom_push_url")
|
||||||
|
|
||||||
|
def test_clone_fetch_spec(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, fetch_spec="refs/heads/test"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
# FIXME: When pygit2 retrieve the fetchspec we passed to git clone.
|
||||||
|
# fetchspec seems to be going through, but the Repository class is
|
||||||
|
# not getting it.
|
||||||
|
# self.assertEqual(repo.remotes[0].fetchspec, "refs/heads/test")
|
||||||
|
|
||||||
|
def test_clone_push_spec(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, push_spec="refs/heads/test"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
# FIXME: When pygit2 supports retrieving the pushspec parameter,
|
||||||
|
# enable this test
|
||||||
|
# not sure how to test this either... couldn't find pushspec
|
||||||
|
# self.assertEqual(repo.remotes[0].fetchspec, "refs/heads/test")
|
||||||
|
|
||||||
|
def test_clone_checkout_branch(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, checkout_branch="test"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
# FIXME: When pygit2 supports retrieving the current branch,
|
||||||
|
# enable this test
|
||||||
|
# self.assertEqual(repo.remotes[0].current_branch, "test")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user