diff --git a/pygit2/repository.py b/pygit2/repository.py index 0386914..3643e44 100644 --- a/pygit2/repository.py +++ b/pygit2/repository.py @@ -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 diff --git a/src/pygit2.c b/src/pygit2.c index 6eaafaf..74ed953 100644 --- a/src/pygit2.c +++ b/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__}, diff --git a/src/repository.c b/src/repository.c index 355070e..a5d67f7 100644 --- a/src/repository.c +++ b/src/repository.c @@ -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 */ }; +