diff --git a/docs/remotes.rst b/docs/remotes.rst index 4b9692f..12a1755 100644 --- a/docs/remotes.rst +++ b/docs/remotes.rst @@ -13,6 +13,10 @@ The Remote type .. autoattribute:: pygit2.Remote.name .. autoattribute:: pygit2.Remote.url .. autoattribute:: pygit2.Remote.refspec_count +.. automethod:: pygit2.Remote.get_push_refspec +.. automethod:: pygit2.Remote.get_pull_refspec +.. automethod:: pygit2.Remote.set_push_refspec +.. automethod:: pygit2.Remote.set_pull_refspec .. automethod:: pygit2.Remote.get_refspec .. automethod:: pygit2.Remote.fetch .. automethod:: pygit2.Remote.push diff --git a/src/remote.c b/src/remote.c index 66530ce..a357fa4 100644 --- a/src/remote.c +++ b/src/remote.c @@ -33,6 +33,7 @@ #include "types.h" #include "remote.h" + extern PyObject *GitError; extern PyTypeObject RepositoryType; @@ -95,8 +96,164 @@ Remote_name__set__(Remote *self, PyObject* py_name) } +PyObject * get_pylist_from_git_strarray(git_strarray *strarray) +{ + int index; + PyObject *new_list; + + new_list = PyList_New(strarray->count); + + if (new_list == NULL) + return Error_set(GITERR_NOMEMORY); + + for (index = 0; index < strarray->count; (index)++ ) { + PyList_SET_ITEM( + new_list, + index, + to_unicode(strarray->strings[index], NULL, NULL)); + } + return new_list; +} + + +PyDoc_STRVAR(Remote_get_fetch_refspecs__doc__, "Fetch refspecs"); + + +PyObject * +Remote_get_fetch_refspecs(Remote *self) +{ + int err; + git_strarray refspecs; + PyObject *new_list; + + err = git_remote_get_fetch_refspecs(&refspecs, self->remote); + + if (err != GIT_OK) + return Error_set(err); + + new_list = get_pylist_from_git_strarray(&refspecs); + + git_strarray_free(&refspecs); + return new_list; +} + + +PyDoc_STRVAR(Remote_get_push_refspecs__doc__, "Push refspecs"); + + +PyObject * +Remote_get_push_refspecs(Remote *self) +{ + int err; + git_strarray refspecs; + PyObject *new_list; + + err = git_remote_get_push_refspecs(&refspecs, self->remote); + + if (err != GIT_OK) + return Error_set(err); + + new_list = get_pylist_from_git_strarray(&refspecs); + + git_strarray_free(&refspecs); + return new_list; +} + + +int +get_strarraygit_from_pylist(git_strarray *array, PyObject *pylist) +{ + long index, n; + PyObject *item; + + n = PyObject_Length(pylist); + if (n < 0) + goto error; + + /* allocate new git_strarray */ + void *ptr = calloc(n, sizeof(char *)); + + if (!ptr) + goto error; + + array->strings = ptr; + array->count = n; + + for (index = 0; index < n; index++) { + item = PyList_GetItem(pylist, index); + array->strings[index] = py_str_to_c_str(item, NULL); + } + + return GIT_OK; + +error: + Error_set(GITERR_NOMEMORY); + return -1; +} + + +PyDoc_STRVAR(Remote_set_fetch_refspecs__doc__, + "set_fetch_refspecs([str])\n" + "\n"); + + +PyObject * +Remote_set_fetch_refspecs(Remote *self, PyObject *args) +{ + int err; + PyObject *pyrefspecs; + git_strarray fetch_refspecs; + + if (! PyArg_Parse(args, "O", &pyrefspecs)) + return Error_set(GITERR_INVALID); + + if (get_strarraygit_from_pylist(&fetch_refspecs , pyrefspecs) != GIT_OK) + return NULL; + + err = git_remote_set_fetch_refspecs(self->remote, &fetch_refspecs); + + git_strarray_free(&fetch_refspecs); + + if (err != GIT_OK) { + return Error_set(err); + } + + Py_RETURN_NONE; +} + + +PyDoc_STRVAR(Remote_set_push_refspecs__doc__, + "set_push_refspecs([str])\n" + "\n"); + + +PyObject * +Remote_set_push_refspecs(Remote *self, PyObject *args) +{ + int err; + PyObject *pyrefspecs; + git_strarray push_refspecs; + + if (! PyArg_Parse(args, "O", &pyrefspecs)) + return Error_set(GITERR_INVALID); + + if (get_strarraygit_from_pylist(&push_refspecs, pyrefspecs) != 0) + return NULL; + + err = git_remote_set_push_refspecs(self->remote, &push_refspecs); + + git_strarray_free(&push_refspecs); + + if (err != GIT_OK) + return Error_set(err); + + Py_RETURN_NONE; +} + + PyDoc_STRVAR(Remote_url__doc__, "Url of the remote"); + PyObject * Remote_url__get__(Remote *self) { @@ -288,6 +445,10 @@ PyMethodDef Remote_methods[] = { METHOD(Remote, save, METH_NOARGS), METHOD(Remote, get_refspec, METH_O), METHOD(Remote, push, METH_VARARGS), + METHOD(Remote, get_fetch_refspecs, METH_NOARGS), + METHOD(Remote, set_fetch_refspecs, METH_O), + METHOD(Remote, get_push_refspecs, METH_NOARGS), + METHOD(Remote, set_push_refspecs, METH_O), {NULL} }; diff --git a/test/test_remote.py b/test/test_remote.py index b6a9edc..741cd50 100644 --- a/test/test_remote.py +++ b/test/test_remote.py @@ -83,11 +83,36 @@ class RepositoryTest(utils.RepoTestCase): self.assertEqual(refspec[0], REMOTE_FETCHSPEC_SRC) self.assertEqual(refspec[1], REMOTE_FETCHSPEC_DST) -# new_fetchspec = ('refs/foo/*', 'refs/remotes/foo/*') -# remote.fetchspec = new_fetchspec -# refspec = remote.get_refspec(0) -# self.assertEqual(new_fetchspec[0], refspec[0]) -# self.assertEqual(new_fetchspec[1], refspec[1]) + self.assertEqual(list, type(remote.get_fetch_refspecs())) + self.assertEqual(1, len(remote.get_fetch_refspecs())) + self.assertEqual('+refs/heads/*:refs/remotes/origin/*', + remote.get_fetch_refspecs()[0]) + + self.assertEqual(list, type(remote.get_push_refspecs())) + self.assertEqual(0, len(remote.get_push_refspecs())) + + remote.set_fetch_refspecs(['+refs/*:refs/remotes/*']) + self.assertEqual('+refs/*:refs/remotes/*', + remote.get_fetch_refspecs()[0]) + + remote.set_fetch_refspecs([ + '+refs/*:refs/remotes/*', + '+refs/test/*:refs/test/remotes/*' + ]) + self.assertEqual('+refs/*:refs/remotes/*', + remote.get_fetch_refspecs()[0]) + self.assertEqual('+refs/test/*:refs/test/remotes/*', + remote.get_fetch_refspecs()[1]) + + remote.set_push_refspecs([ + '+refs/*:refs/remotes/*', + '+refs/test/*:refs/test/remotes/*' + ]) + + self.assertEqual('+refs/*:refs/remotes/*', + remote.get_push_refspecs()[0]) + self.assertEqual('+refs/test/*:refs/test/remotes/*', + remote.get_push_refspecs()[1]) def test_remote_list(self):