From eb522b0caa7317e4b952ff6754d093701c342a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= <carlos@cmartin.tk> Date: Fri, 17 Feb 2012 17:14:13 +0100 Subject: [PATCH] Make TreeBuilder grow out of the repository A TreeBuilder is a lot more useful (and easy to use) when it belongs to a repository. --- pygit2.c | 81 +++++++++++++++++++++++----------------- test/test_treebuilder.py | 10 ++--- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/pygit2.c b/pygit2.c index cb4d826..f63a119 100644 --- a/pygit2.c +++ b/pygit2.c @@ -937,6 +937,45 @@ Repository_status_file(Repository *self, PyObject *value) return PyInt_FromLong(status); } +static PyObject * +Repository_TreeBuilder(Repository *self, PyObject *args) +{ + TreeBuilder *builder; + git_treebuilder *bld; + PyObject *py_oid = NULL; + size_t oid_len; + git_oid oid; + git_tree *tree = NULL; + int err; + + if (!PyArg_ParseTuple(args, "|O", &py_oid)) + return NULL; + + if (py_oid) { + oid_len = py_str_to_git_oid(py_oid, &oid); + TODO_SUPPORT_SHORT_HEXS(oid_len) + if (oid_len == 0) + return NULL; + + err = git_tree_lookup(&tree, self->repo, &oid); + if (err < 0) + return Error_set(err); + } + + err = git_treebuilder_create(&bld, tree); + if (err < 0) + return Error_set(err); + + builder = PyObject_New(TreeBuilder, &TreeBuilderType); + if (builder) { + builder->repo = self; + builder->bld = bld; + Py_INCREF(self); + } + + return (PyObject*)builder; +} + static PyMethodDef Repository_methods[] = { {"create_commit", (PyCFunction)Repository_create_commit, METH_VARARGS, "Create a new commit object, return its SHA."}, @@ -970,6 +1009,8 @@ static PyMethodDef Repository_methods[] = { "as keys and status flags as values.\nSee pygit2.GIT_STATUS_*."}, {"status_file", (PyCFunction)Repository_status_file, METH_O, "Returns the status of the given file path."}, + {"TreeBuilder", (PyCFunction)Repository_TreeBuilder, METH_VARARGS, + "Create a TreeBuilder object for this repository."}, {NULL} }; @@ -1578,36 +1619,10 @@ static PyTypeObject TreeType = { 0, /* tp_new */ }; -static int -TreeBuilder_init(TreeBuilder *self, PyObject *args, PyObject *kwds) -{ - Tree *py_tree = NULL; - git_tree *tree; - int err; - - if (kwds) { - PyErr_SetString(PyExc_TypeError, - "TreeBuilder takes no keyword arguments"); - return -1; - } - - if (!PyArg_ParseTuple(args, "|O", &py_tree)) - return -1; - - tree = py_tree == NULL ? NULL : py_tree->tree; - - err = git_treebuilder_create(&self->bld, tree); - if (err < 0) { - Error_set(err); - return -1; - } - - return 0; -} - static void TreeBuilder_dealloc(TreeBuilder* self) { + Py_XDECREF(self->repo); git_treebuilder_free(self->bld); PyObject_Del(self); } @@ -1633,13 +1648,12 @@ TreeBuilder_insert(TreeBuilder *self, TreeEntry *py_tentry) } static PyObject * -TreeBuilder_write(TreeBuilder *self, Repository *py_repo) +TreeBuilder_write(TreeBuilder *self) { int err; git_oid oid; - git_repository *repo = py_repo->repo; - err = git_treebuilder_write(&oid, repo, self->bld); + err = git_treebuilder_write(&oid, self->repo->repo, self->bld); if (err < 0) return Error_set(err); @@ -1649,7 +1663,7 @@ TreeBuilder_write(TreeBuilder *self, Repository *py_repo) static PyMethodDef TreeBuilder_methods[] = { {"insert", (PyCFunction)TreeBuilder_insert, METH_O, "Insert or replace an entry in the treebuilder"}, - {"write", (PyCFunction)TreeBuilder_write, METH_O, + {"write", (PyCFunction)TreeBuilder_write, METH_NOARGS, "Write the tree to the given repository"}, {NULL, NULL, 0, NULL} }; @@ -1690,7 +1704,7 @@ static PyTypeObject TreeBuilderType = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)TreeBuilder_init, /* tp_init */ + 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; @@ -3073,9 +3087,6 @@ moduleinit(PyObject* m) Py_INCREF(&TreeType); PyModule_AddObject(m, "Tree", (PyObject *)&TreeType); - Py_INCREF(&TreeBuilderType); - PyModule_AddObject(m, "TreeBuilder", (PyObject *)&TreeBuilderType); - Py_INCREF(&BlobType); PyModule_AddObject(m, "Blob", (PyObject *)&BlobType); diff --git a/test/test_treebuilder.py b/test/test_treebuilder.py index 7fbbc40..d1b003b 100644 --- a/test/test_treebuilder.py +++ b/test/test_treebuilder.py @@ -42,21 +42,21 @@ TREE_SHA = '967fce8df97cc71722d3c2a5930ef3e6f1d27b12' class TreeBuilderTest(utils.BareRepoTestCase): def test_new_empty_treebuilder(self): - bld = pygit2.TreeBuilder() + bld = self.repo.TreeBuilder() def test_noop_treebuilder(self): tree = self.repo[TREE_SHA] - bld = pygit2.TreeBuilder(tree) - result = bld.write(self.repo) + bld = self.repo.TreeBuilder(TREE_SHA) + result = bld.write() self.assertEqual(tree.oid, result) def test_rebuild_treebuilder(self): tree = self.repo[TREE_SHA] - bld = pygit2.TreeBuilder(tree) + bld = self.repo.TreeBuilder(TREE_SHA) for e in tree: bld.insert(e) - result = bld.write(self.repo) + result = bld.write() self.assertEqual(tree.oid, result) if __name__ == '__main__':