Supporting clone in pygit2
This commit is contained in:
@@ -47,3 +47,22 @@ def init_repository(path, bare=False):
|
||||
"""
|
||||
_pygit2.init_repository(path, bare)
|
||||
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*.
|
||||
|
||||
Parameters:
|
||||
* If 'bare' is True, then a bare git repository will 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 fetch url.
|
||||
* 'fetch_spec' is the fetch specification to be used for fetching. 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
|
||||
"""
|
||||
|
||||
_pygit2.clone_repository(url, path, bare, remote_name, push_url, fetch_spec, push_spec, checkout_branch)
|
||||
return Repository(path)
|
||||
|
56
src/pygit2.c
56
src/pygit2.c
@@ -97,6 +97,61 @@ init_repository(PyObject *self, PyObject *args) {
|
||||
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, *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__,
|
||||
"discover_repository(path[, across_fs[, ceiling_dirs]]) -> str\n"
|
||||
@@ -172,6 +227,7 @@ hash(PyObject *self, PyObject *args)
|
||||
|
||||
PyMethodDef module_methods[] = {
|
||||
{"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__doc__},
|
||||
{"hashfile", hashfile, METH_VARARGS, hashfile__doc__},
|
||||
|
@@ -40,7 +40,7 @@ from os.path import join, realpath
|
||||
|
||||
# Import from pygit2
|
||||
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
|
||||
import pygit2
|
||||
from . import utils
|
||||
@@ -291,6 +291,46 @@ class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
||||
self.assertTrue(self.repo.head_is_orphaned)
|
||||
self.assertFalse(self.repo.head_is_detached)
|
||||
|
||||
class CloneRepositoryTest(utils.NoRepoTestCase):
|
||||
def test_clone_repository(self):
|
||||
repo = clone_repository("./test/data/testrepo.git/", self._temp_dir)
|
||||
self.assertFalse(repo.is_empty)
|
||||
self.assertFalse(repo.is_bare)
|
||||
|
||||
def test_clone_bare_repository(self):
|
||||
repo = clone_repository("./test/data/testrepo.git/", self._temp_dir, bare=True)
|
||||
self.assertFalse(repo.is_empty)
|
||||
self.assertTrue(repo.is_bare)
|
||||
|
||||
def test_clone_remote_name(self):
|
||||
repo = clone_repository("./test/data/testrepo.git/", 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 = clone_repository("./test/data/testrepo.git/", self._temp_dir, push_url="custom_push_url")
|
||||
self.assertFalse(repo.is_empty)
|
||||
# not sure how to test this... couldn't find pushurl
|
||||
# self.assertEqual(repo.remotes[0].pushurl, "custom_push_url")
|
||||
|
||||
def test_clone_fetch_spec(self):
|
||||
repo = clone_repository("./test/data/testrepo.git/", self._temp_dir, fetch_spec="refs/heads/test")
|
||||
self.assertFalse(repo.is_empty)
|
||||
# not sure how to test this either... fetchspec seems to be going through, but repo is not getting it.
|
||||
# self.assertEqual(repo.remotes[0].fetchspec, "refs/heads/test")
|
||||
|
||||
def test_clone_push_spec(self):
|
||||
repo = clone_repository("./test/data/testrepo.git/", self._temp_dir, push_spec="refs/heads/test")
|
||||
self.assertFalse(repo.is_empty)
|
||||
# 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 = clone_repository("./test/data/testrepo.git/", self._temp_dir, checkout_branch="test")
|
||||
self.assertFalse(repo.is_empty)
|
||||
# not sure how to test this either... couldn't find current branch
|
||||
# self.assertEqual(repo.remotes[0].current_branch, "test")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Reference in New Issue
Block a user