Complete support for revision walk
Signed-off-by: J. David Ibañez <jdavid@itaapy.com>
This commit is contained in:
parent
296f521496
commit
fc4f82cc68
139
pygit2.c
139
pygit2.c
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010 Google, Inc.
|
||||
* Copyright 2011 Itaapy
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License, version 2,
|
||||
@ -74,7 +75,7 @@ typedef struct {
|
||||
PyObject_HEAD
|
||||
Repository *repo;
|
||||
git_revwalk *walk;
|
||||
} RevWalker;
|
||||
} Walker;
|
||||
|
||||
static PyTypeObject RepositoryType;
|
||||
static PyTypeObject ObjectType;
|
||||
@ -85,7 +86,7 @@ static PyTypeObject BlobType;
|
||||
static PyTypeObject TagType;
|
||||
static PyTypeObject IndexType;
|
||||
static PyTypeObject IndexEntryType;
|
||||
static PyTypeObject RevWalkerType;
|
||||
static PyTypeObject WalkerType;
|
||||
|
||||
static PyObject *GitError;
|
||||
|
||||
@ -336,27 +337,43 @@ Repository_get_index(Repository *self, void *closure) {
|
||||
return self->index;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Repository_log(Repository *self, PyObject *py_hex)
|
||||
{
|
||||
static git_commit *
|
||||
py_str_to_git_commit(Repository *py_repo, PyObject *py_hex) {
|
||||
int err;
|
||||
char *hex;
|
||||
git_oid oid;
|
||||
git_commit *commit;
|
||||
git_revwalk *walk;
|
||||
RevWalker *py_walker;
|
||||
|
||||
hex = PyString_AsString(py_hex);
|
||||
if (!hex)
|
||||
return NULL;
|
||||
|
||||
err = git_oid_mkstr(&oid, hex);
|
||||
if (err < 0)
|
||||
return Error_set_str(err, hex);
|
||||
if (err < 0) {
|
||||
Error_set_str(err, hex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = git_commit_lookup(&commit, self->repo, &oid);
|
||||
if (err < 0)
|
||||
return Error_set_str(err, hex);
|
||||
err = git_commit_lookup(&commit, py_repo->repo, &oid);
|
||||
if (err < 0) {
|
||||
Error_set_str(err, hex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return commit;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Repository_walk(Repository *self, PyObject *py_hex)
|
||||
{
|
||||
int err;
|
||||
git_commit *commit;
|
||||
git_revwalk *walk;
|
||||
Walker *py_walker;
|
||||
|
||||
commit = py_str_to_git_commit(self, py_hex);
|
||||
if (commit == NULL)
|
||||
return NULL;
|
||||
|
||||
err = git_revwalk_new(&walk, self->repo);
|
||||
if (err < 0)
|
||||
@ -374,7 +391,7 @@ Repository_log(Repository *self, PyObject *py_hex)
|
||||
return Error_set(err);
|
||||
}
|
||||
|
||||
py_walker = PyObject_New(RevWalker, &RevWalkerType);
|
||||
py_walker = PyObject_New(Walker, &WalkerType);
|
||||
if (!py_walker) {
|
||||
git_revwalk_free(walk);
|
||||
return NULL;
|
||||
@ -387,7 +404,7 @@ Repository_log(Repository *self, PyObject *py_hex)
|
||||
}
|
||||
|
||||
static PyMethodDef Repository_methods[] = {
|
||||
{"log", (PyCFunction)Repository_log, METH_O,
|
||||
{"walk", (PyCFunction)Repository_walk, METH_O,
|
||||
"Generator that traverses the history starting from the given commit."},
|
||||
{"read", (PyCFunction)Repository_read, METH_O,
|
||||
"Read raw object data from the repository."},
|
||||
@ -1683,20 +1700,74 @@ static PyTypeObject IndexEntryType = {
|
||||
};
|
||||
|
||||
static void
|
||||
RevWalker_dealloc(RevWalker *self) {
|
||||
Walker_dealloc(Walker *self) {
|
||||
git_revwalk_free(self->walk);
|
||||
Py_DECREF(self->repo);
|
||||
self->ob_type->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
RevWalker_iter(RevWalker *self) {
|
||||
Walker_hide(Walker *self, PyObject *py_hex) {
|
||||
int err;
|
||||
git_commit *commit;
|
||||
|
||||
commit = py_str_to_git_commit(self->repo, py_hex);
|
||||
if (commit == NULL)
|
||||
return NULL;
|
||||
|
||||
err = git_revwalk_hide(self->walk, commit);
|
||||
if (err < 0)
|
||||
return Error_set(err);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Walker_push(Walker *self, PyObject *py_hex) {
|
||||
int err;
|
||||
git_commit *commit;
|
||||
|
||||
commit = py_str_to_git_commit(self->repo, py_hex);
|
||||
if (commit == NULL)
|
||||
return NULL;
|
||||
|
||||
err = git_revwalk_push(self->walk, commit);
|
||||
if (err < 0)
|
||||
return Error_set(err);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Walker_sort(Walker *self, PyObject *py_sort_mode) {
|
||||
int sort_mode;
|
||||
int err;
|
||||
|
||||
sort_mode = (int)PyInt_AsLong(py_sort_mode);
|
||||
if (sort_mode == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
err = git_revwalk_sorting(self->walk, sort_mode);
|
||||
if (err < 0)
|
||||
return Error_set_py_obj(err, py_sort_mode);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Walker_reset(Walker *self) {
|
||||
git_revwalk_reset(self->walk);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Walker_iter(Walker *self) {
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
RevWalker_iternext(RevWalker *self) {
|
||||
Walker_iternext(Walker *self) {
|
||||
int err;
|
||||
git_commit *commit;
|
||||
Commit *py_commit;
|
||||
@ -1716,13 +1787,25 @@ RevWalker_iternext(RevWalker *self) {
|
||||
return (PyObject*)py_commit;
|
||||
}
|
||||
|
||||
static PyTypeObject RevWalkerType = {
|
||||
static PyMethodDef Walker_methods[] = {
|
||||
{"hide", (PyCFunction)Walker_hide, METH_O,
|
||||
"Mark a commit (and its ancestors) uninteresting for the output."},
|
||||
{"push", (PyCFunction)Walker_push, METH_O,
|
||||
"Mark a commit to start traversal from."},
|
||||
{"reset", (PyCFunction)Walker_reset, METH_NOARGS,
|
||||
"Reset the walking machinery for reuse."},
|
||||
{"sort", (PyCFunction)Walker_sort, METH_O,
|
||||
"Change the sorting mode (this resets the walker)."},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static PyTypeObject WalkerType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /* ob_size */
|
||||
"pygit2.RevWalker", /* tp_name */
|
||||
sizeof(RevWalker), /* tp_basicsize */
|
||||
"pygit2.Walker", /* tp_name */
|
||||
sizeof(Walker), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
(destructor)RevWalker_dealloc, /* tp_dealloc */
|
||||
(destructor)Walker_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
@ -1743,9 +1826,9 @@ static PyTypeObject RevWalkerType = {
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
(getiterfunc)RevWalker_iter, /* tp_iter */
|
||||
(iternextfunc)RevWalker_iternext, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
(getiterfunc)Walker_iter, /* tp_iter */
|
||||
(iternextfunc)Walker_iternext, /* tp_iternext */
|
||||
Walker_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
@ -1801,8 +1884,8 @@ initpygit2(void)
|
||||
IndexEntryType.tp_new = PyType_GenericNew;
|
||||
if (PyType_Ready(&IndexEntryType) < 0)
|
||||
return;
|
||||
RevWalkerType.tp_new = PyType_GenericNew;
|
||||
if (PyType_Ready(&RevWalkerType) < 0)
|
||||
WalkerType.tp_new = PyType_GenericNew;
|
||||
if (PyType_Ready(&WalkerType) < 0)
|
||||
return;
|
||||
|
||||
m = Py_InitModule3("pygit2", module_methods,
|
||||
@ -1846,4 +1929,8 @@ initpygit2(void)
|
||||
PyModule_AddIntConstant(m, "GIT_OBJ_TREE", GIT_OBJ_TREE);
|
||||
PyModule_AddIntConstant(m, "GIT_OBJ_BLOB", GIT_OBJ_BLOB);
|
||||
PyModule_AddIntConstant(m, "GIT_OBJ_TAG", GIT_OBJ_TAG);
|
||||
PyModule_AddIntConstant(m, "GIT_SORT_NONE", GIT_SORT_NONE);
|
||||
PyModule_AddIntConstant(m, "GIT_SORT_TOPOLOGICAL", GIT_SORT_TOPOLOGICAL);
|
||||
PyModule_AddIntConstant(m, "GIT_SORT_TIME", GIT_SORT_TIME);
|
||||
PyModule_AddIntConstant(m, "GIT_SORT_REVERSE", GIT_SORT_REVERSE);
|
||||
}
|
||||
|
@ -36,6 +36,6 @@ import utils
|
||||
class WalkerTest(utils.BareRepoTestCase):
|
||||
|
||||
def test_walk(self):
|
||||
history = self.repo.log("5fe808e8953c12735680c257f56600cb0de44b10")
|
||||
history = self.repo.walk("5fe808e8953c12735680c257f56600cb0de44b10")
|
||||
history = list(history)
|
||||
self.assertEqual(len(history), 2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user