8000 Add support for custom backends by hishnash · Pull Request #690 · libgit2/pygit2 · GitHub
[go: up one dir, main page]

Skip to content

Add support for custom backends #690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions pygit2/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
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
Expand All @@ -56,23 +56,12 @@
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)

Expand Down Expand Up @@ -318,19 +307,19 @@ def diff(self, a=None, b=None, cached=False, flags=GIT_DIFF_NORMAL,
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.
Expand Down Expand Up @@ -915,3 +904,21 @@ def set_ident(self, name, email):

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 changes: 36 additions & 0 deletions src/pygit2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__},
Expand Down
20 changes: 11 additions & 9 deletions src/repository.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -1747,7 +1748,7 @@ PyGetSetDef Repository_getseters[] = {


PyDoc_STRVAR(Repository__doc__,
"Repository(path) -> Repository\n"
"Repository(backend) -> Repository\n"
"\n"
"Git repository.");

Expand Down Expand Up @@ -1793,3 +1794,4 @@ PyTypeObject RepositoryType = {
0, /* tp_alloc */
0, /* tp_new */
};

0