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 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 | ||||
|   | ||||
							
								
								
									
										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            */ | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Matthaus Woolard
					Matthaus Woolard