Add support for custom backends
Signed-off-by: Matthaus Woolard <matthaus.woolard@gmail.com>
This commit is contained in:
@@ -40,7 +40,7 @@ else:
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
# Import from pygit2
|
# Import from pygit2
|
||||||
from _pygit2 import Repository as _Repository
|
from _pygit2 import Repository as _Repository, init_file_backend
|
||||||
from _pygit2 import Oid, GIT_OID_HEXSZ, GIT_OID_MINPREFIXLEN
|
from _pygit2 import Oid, GIT_OID_HEXSZ, GIT_OID_MINPREFIXLEN
|
||||||
from _pygit2 import GIT_CHECKOUT_SAFE, GIT_CHECKOUT_RECREATE_MISSING, GIT_DIFF_NORMAL
|
from _pygit2 import GIT_CHECKOUT_SAFE, GIT_CHECKOUT_RECREATE_MISSING, GIT_DIFF_NORMAL
|
||||||
from _pygit2 import GIT_FILEMODE_LINK
|
from _pygit2 import GIT_FILEMODE_LINK
|
||||||
@@ -56,23 +56,12 @@ from .utils import to_bytes, is_string
|
|||||||
from .submodule import Submodule
|
from .submodule import Submodule
|
||||||
|
|
||||||
|
|
||||||
class Repository(_Repository):
|
class BaseRepository(_Repository):
|
||||||
|
|
||||||
def __init__(self, path, *args, **kwargs):
|
def __init__(self, backend, *args, **kwargs):
|
||||||
if not isinstance(path, six.string_types):
|
super(BaseRepository, self).__init__(backend, *args, **kwargs)
|
||||||
path = path.decode('utf-8')
|
|
||||||
super(Repository, self).__init__(path, *args, **kwargs)
|
|
||||||
self._common_init()
|
self._common_init()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _from_c(cls, ptr, owned):
|
|
||||||
cptr = ffi.new('git_repository **')
|
|
||||||
cptr[0] = ptr
|
|
||||||
repo = cls.__new__(cls)
|
|
||||||
super(cls, repo)._from_c(bytes(ffi.buffer(cptr)[:]), owned)
|
|
||||||
repo._common_init()
|
|
||||||
return repo
|
|
||||||
|
|
||||||
def _common_init(self):
|
def _common_init(self):
|
||||||
self.remotes = RemoteCollection(self)
|
self.remotes = RemoteCollection(self)
|
||||||
|
|
||||||
@@ -915,3 +904,21 @@ class Repository(_Repository):
|
|||||||
|
|
||||||
err = C.git_repository_set_ident(self._repo, to_bytes(name), to_bytes(email))
|
err = C.git_repository_set_ident(self._repo, to_bytes(name), to_bytes(email))
|
||||||
check_error(err)
|
check_error(err)
|
||||||
|
|
||||||
|
|
||||||
|
class Repository(BaseRepository):
|
||||||
|
def __init__(self, path, *args, **kwargs):
|
||||||
|
if not isinstance(path, six.string_types):
|
||||||
|
path = path.decode('utf-8')
|
||||||
|
|
||||||
|
path_backend = init_file_backend(path)
|
||||||
|
super(Repository, self).__init__(backend=path_backend, *args, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _from_c(cls, ptr, owned):
|
||||||
|
cptr = ffi.new('git_repository **')
|
||||||
|
cptr[0] = ptr
|
||||||
|
repo = cls.__new__(cls)
|
||||||
|
super(cls, repo)._from_c(bytes(ffi.buffer(cptr)[:]), owned)
|
||||||
|
repo._common_init()
|
||||||
|
return repo
|
||||||
|
|||||||
36
src/pygit2.c
36
src/pygit2.c
@@ -144,7 +144,43 @@ hash(PyObject *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(init_file_backend__doc__,
|
||||||
|
"init_file_backend(path) -> object\n"
|
||||||
|
"\n"
|
||||||
|
"open repo backend given path.");
|
||||||
|
PyObject *
|
||||||
|
init_file_backend(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
const char* path;
|
||||||
|
int err = GIT_OK;
|
||||||
|
git_repository *repository = NULL;
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &path)) {
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
err = git_repository_open(&repository, path);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
Error_set_str(err, path);
|
||||||
|
err = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyCapsule_New(repository, "backend", NULL);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (repository)
|
||||||
|
git_repository_free(repository);
|
||||||
|
|
||||||
|
PyErr_Format(PyExc_Exception,
|
||||||
|
"Git error %d during construction of git repo", err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PyMethodDef module_methods[] = {
|
PyMethodDef module_methods[] = {
|
||||||
|
{"init_file_backend", init_file_backend, METH_VARARGS,
|
||||||
|
init_file_backend__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__},
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ wrap_repository(git_repository *c_repo)
|
|||||||
int
|
int
|
||||||
Repository_init(Repository *self, PyObject *args, PyObject *kwds)
|
Repository_init(Repository *self, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
char *path;
|
PyObject *backend;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (kwds && PyDict_Size(kwds) > 0) {
|
if (kwds && PyDict_Size(kwds) > 0) {
|
||||||
@@ -97,15 +97,16 @@ Repository_init(Repository *self, PyObject *args, PyObject *kwds)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &path))
|
if (!PyArg_ParseTuple(args, "O", &backend)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
err = git_repository_open(&self->repo, path);
|
|
||||||
if (err < 0) {
|
|
||||||
Error_set_str(err, path);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->repo = PyCapsule_GetPointer(backend, "backend");
|
||||||
|
if (self->repo == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"Repository unable to unpack backend.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
self->owned = 1;
|
self->owned = 1;
|
||||||
self->config = NULL;
|
self->config = NULL;
|
||||||
self->index = NULL;
|
self->index = NULL;
|
||||||
@@ -1747,7 +1748,7 @@ PyGetSetDef Repository_getseters[] = {
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository__doc__,
|
PyDoc_STRVAR(Repository__doc__,
|
||||||
"Repository(path) -> Repository\n"
|
"Repository(backend) -> Repository\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Git repository.");
|
"Git repository.");
|
||||||
|
|
||||||
@@ -1793,3 +1794,4 @@ PyTypeObject RepositoryType = {
|
|||||||
0, /* tp_alloc */
|
0, /* tp_alloc */
|
||||||
0, /* tp_new */
|
0, /* tp_new */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user