Add support for custom backends

Signed-off-by: Matthaus Woolard <matthaus.woolard@gmail.com>
This commit is contained in:
Matthaus Woolard 2017-01-20 16:11:51 +00:00
parent 5c061cbb0a
commit 4fbc1f1c05
3 changed files with 72 additions and 27 deletions

View File

@ -40,7 +40,7 @@ else:
import six
# 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 GIT_CHECKOUT_SAFE, GIT_CHECKOUT_RECREATE_MISSING, GIT_DIFF_NORMAL
from _pygit2 import GIT_FILEMODE_LINK
@ -56,23 +56,12 @@ from .utils import to_bytes, is_string
from .submodule import Submodule
class Repository(_Repository):
class BaseRepository(_Repository):
def __init__(self, path, *args, **kwargs):
if not isinstance(path, six.string_types):
path = path.decode('utf-8')
super(Repository, self).__init__(path, *args, **kwargs)
def __init__(self, backend, *args, **kwargs):
super(BaseRepository, self).__init__(backend, *args, **kwargs)
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):
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))
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

View File

@ -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[] = {
{"init_file_backend", init_file_backend, METH_VARARGS,
init_file_backend__doc__},
{"discover_repository", discover_repository, METH_VARARGS,
discover_repository__doc__},
{"hashfile", hashfile, METH_VARARGS, hashfile__doc__},

View File

@ -88,7 +88,7 @@ wrap_repository(git_repository *c_repo)
int
Repository_init(Repository *self, PyObject *args, PyObject *kwds)
{
char *path;
PyObject *backend;
int err;
if (kwds && PyDict_Size(kwds) > 0) {
@ -97,15 +97,16 @@ Repository_init(Repository *self, PyObject *args, PyObject *kwds)
return -1;
}
if (!PyArg_ParseTuple(args, "s", &path))
return -1;
err = git_repository_open(&self->repo, path);
if (err < 0) {
Error_set_str(err, path);
return -1;
if (!PyArg_ParseTuple(args, "O", &backend)) {
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->config = NULL;
self->index = NULL;
@ -1747,7 +1748,7 @@ PyGetSetDef Repository_getseters[] = {
PyDoc_STRVAR(Repository__doc__,
"Repository(path) -> Repository\n"
"Repository(backend) -> Repository\n"
"\n"
"Git repository.");
@ -1793,3 +1794,4 @@ PyTypeObject RepositoryType = {
0, /* tp_alloc */
0, /* tp_new */
};