Branch: move from foreach to the iterator
This commit is contained in:
@@ -920,69 +920,64 @@ PyDoc_STRVAR(Repository_listall_branches__doc__,
|
|||||||
"\n"
|
"\n"
|
||||||
"Return a tuple with all the branches in the repository.");
|
"Return a tuple with all the branches in the repository.");
|
||||||
|
|
||||||
struct branch_foreach_s {
|
|
||||||
PyObject *tuple;
|
|
||||||
Py_ssize_t pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
branch_foreach_cb(const char *branch_name, git_branch_t branch_type, void *payload)
|
|
||||||
{
|
|
||||||
/* This is the callback that will be called in git_branch_foreach. It
|
|
||||||
* will be called for every branch.
|
|
||||||
* payload is a struct branch_foreach_s.
|
|
||||||
*/
|
|
||||||
int err;
|
|
||||||
struct branch_foreach_s *payload_s = (struct branch_foreach_s *)payload;
|
|
||||||
|
|
||||||
if (PyTuple_Size(payload_s->tuple) <= payload_s->pos)
|
|
||||||
{
|
|
||||||
err = _PyTuple_Resize(&(payload_s->tuple), payload_s->pos * 2);
|
|
||||||
if (err) {
|
|
||||||
Py_CLEAR(payload_s->tuple);
|
|
||||||
return GIT_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject *py_branch_name = to_path(branch_name);
|
|
||||||
if (py_branch_name == NULL) {
|
|
||||||
Py_CLEAR(payload_s->tuple);
|
|
||||||
return GIT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyTuple_SET_ITEM(payload_s->tuple, payload_s->pos++, py_branch_name);
|
|
||||||
|
|
||||||
return GIT_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Repository_listall_branches(Repository *self, PyObject *args)
|
Repository_listall_branches(Repository *self, PyObject *args)
|
||||||
{
|
{
|
||||||
unsigned int list_flags = GIT_BRANCH_LOCAL;
|
git_branch_t list_flags = GIT_BRANCH_LOCAL;
|
||||||
|
git_branch_iterator *iter;
|
||||||
|
git_reference *ref = NULL;
|
||||||
|
Py_ssize_t pos = 0;
|
||||||
int err;
|
int err;
|
||||||
|
git_branch_t type;
|
||||||
|
PyObject *tuple;
|
||||||
|
|
||||||
/* 1- Get list_flags */
|
/* 1- Get list_flags */
|
||||||
if (!PyArg_ParseTuple(args, "|I", &list_flags))
|
if (!PyArg_ParseTuple(args, "|I", &list_flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* 2- Get the C result */
|
tuple = PyTuple_New(4);
|
||||||
struct branch_foreach_s payload;
|
if (tuple == NULL)
|
||||||
payload.tuple = PyTuple_New(4);
|
|
||||||
if (payload.tuple == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
payload.pos = 0;
|
if ((err = git_branch_iterator_new(&iter, self->repo, list_flags)) < 0)
|
||||||
err = git_branch_foreach(self->repo, list_flags, branch_foreach_cb, &payload);
|
|
||||||
if (err != GIT_OK)
|
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
/* 3- Trim the tuple */
|
while ((err = git_branch_next(&ref, &type, iter)) == 0) {
|
||||||
err = _PyTuple_Resize(&payload.tuple, payload.pos);
|
if (PyTuple_Size(tuple) <= pos) {
|
||||||
if (err)
|
if (_PyTuple_Resize(&tuple, pos * 2) < 0)
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *py_branch_name = to_path(git_reference_shorthand(ref));
|
||||||
|
git_reference_free(ref);
|
||||||
|
ref = NULL;
|
||||||
|
|
||||||
|
if (py_branch_name == NULL)
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
PyTuple_SET_ITEM(tuple, pos++, py_branch_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
git_branch_iterator_free(iter);
|
||||||
|
if (err == GIT_ITEROVER)
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
Py_CLEAR(tuple);
|
||||||
|
return Error_set(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the elements we might have overallocated in the loop */
|
||||||
|
if (_PyTuple_Resize(&tuple, pos) < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
return payload.tuple;
|
return tuple;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
git_reference_free(ref);
|
||||||
|
git_branch_iterator_free(iter);
|
||||||
|
Py_CLEAR(tuple);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user