Add support for custom backends
Signed-off-by: Matthaus Woolard <matthaus.woolard@gmail.com>
This commit is contained in:
parent
5c061cbb0a
commit
4fbc1f1c05
@ -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)
|
||||
|
||||
@ -318,19 +307,19 @@ class Repository(_Repository):
|
||||
Keyword arguments:
|
||||
|
||||
a
|
||||
None, a str (that refers to an Object, see revparse_single()) or a
|
||||
None, a str (that refers to an Object, see revparse_single()) or a
|
||||
Reference object.
|
||||
If None, b must be None, too. In this case the working directory is
|
||||
compared with the index. Otherwise the referred object is compared to
|
||||
'b'.
|
||||
|
||||
|
||||
b
|
||||
None, a str (that refers to an Object, see revparse_single()) or a
|
||||
Reference object.
|
||||
If None, the working directory is compared to 'a'. (except
|
||||
'cached' is True, in which case the index is compared to 'a').
|
||||
Otherwise the referred object is compared to 'a'
|
||||
|
||||
|
||||
cached
|
||||
if 'b' is None, by default the working directory is compared to 'a'.
|
||||
If 'cached' is set to True, the index/staging area is used for comparing.
|
||||
@ -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
|
||||
|
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[] = {
|
||||
{"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__},
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user