Add TreeBuilder.get and remove TreeEntry.to_object
Also, check errors from git_tree_entry_dup
This commit is contained in:
parent
f5082b320b
commit
42aed417d4
@ -187,7 +187,6 @@ interfaces::
|
||||
.. autoattribute:: pygit2.TreeEntry.oid
|
||||
.. autoattribute:: pygit2.TreeEntry.hex
|
||||
.. autoattribute:: pygit2.TreeEntry.filemode
|
||||
.. automethod:: pygit2.TreeEntry.to_object
|
||||
|
||||
|
||||
Creating trees
|
||||
|
58
src/tree.c
58
src/tree.c
@ -42,7 +42,6 @@ extern PyTypeObject IndexType;
|
||||
void
|
||||
TreeEntry_dealloc(TreeEntry *self)
|
||||
{
|
||||
Py_CLEAR(self->owner);
|
||||
git_tree_entry_free((git_tree_entry*)self->entry);
|
||||
PyObject_Del(self);
|
||||
}
|
||||
@ -87,22 +86,6 @@ TreeEntry_hex__get__(TreeEntry *self)
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(TreeEntry_to_object__doc__,
|
||||
"to_object() -> Object\n"
|
||||
"\n"
|
||||
"Look up the corresponding object in the repo.");
|
||||
|
||||
PyObject *
|
||||
TreeEntry_to_object(TreeEntry *self)
|
||||
{
|
||||
const git_oid *entry_oid;
|
||||
Repository *repo;
|
||||
|
||||
repo = ((Object*)(self->owner))->repo;
|
||||
entry_oid = git_tree_entry_id(self->entry);
|
||||
return lookup_object(repo, entry_oid, GIT_OBJ_ANY);
|
||||
}
|
||||
|
||||
PyGetSetDef TreeEntry_getseters[] = {
|
||||
GETTER(TreeEntry, filemode),
|
||||
GETTER(TreeEntry, name),
|
||||
@ -111,11 +94,6 @@ PyGetSetDef TreeEntry_getseters[] = {
|
||||
{NULL}
|
||||
};
|
||||
|
||||
PyMethodDef TreeEntry_methods[] = {
|
||||
METHOD(TreeEntry, to_object, METH_NOARGS),
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
||||
PyDoc_STRVAR(TreeEntry__doc__, "TreeEntry objects.");
|
||||
|
||||
@ -147,7 +125,7 @@ PyTypeObject TreeEntryType = {
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
TreeEntry_methods, /* tp_methods */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
TreeEntry_getseters, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
@ -181,16 +159,14 @@ Tree_contains(Tree *self, PyObject *py_name)
|
||||
}
|
||||
|
||||
TreeEntry *
|
||||
wrap_tree_entry(const git_tree_entry *entry, Tree *tree)
|
||||
wrap_tree_entry(const git_tree_entry *entry)
|
||||
{
|
||||
TreeEntry *py_entry;
|
||||
|
||||
py_entry = PyObject_New(TreeEntry, &TreeEntryType);
|
||||
if (py_entry) {
|
||||
if (py_entry)
|
||||
py_entry->entry = entry;
|
||||
py_entry->owner = (PyObject*)tree;
|
||||
Py_INCREF(tree);
|
||||
}
|
||||
|
||||
return py_entry;
|
||||
}
|
||||
|
||||
@ -252,7 +228,14 @@ Tree_getitem_by_index(Tree *self, PyObject *py_index)
|
||||
PyErr_SetObject(PyExc_IndexError, py_index);
|
||||
return NULL;
|
||||
}
|
||||
return wrap_tree_entry(git_tree_entry_dup(entry), self);
|
||||
|
||||
entry = git_tree_entry_dup(entry);
|
||||
if (entry == NULL) {
|
||||
PyErr_SetNone(PyExc_MemoryError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wrap_tree_entry(entry);
|
||||
}
|
||||
|
||||
TreeEntry *
|
||||
@ -283,7 +266,7 @@ Tree_getitem(Tree *self, PyObject *value)
|
||||
return (TreeEntry*)Error_set(err);
|
||||
|
||||
/* git_tree_entry_dup is already done in git_tree_entry_bypath */
|
||||
return wrap_tree_entry(entry, self);
|
||||
return wrap_tree_entry(entry);
|
||||
}
|
||||
|
||||
|
||||
@ -431,15 +414,20 @@ TreeIter_dealloc(TreeIter *self)
|
||||
TreeEntry *
|
||||
TreeIter_iternext(TreeIter *self)
|
||||
{
|
||||
const git_tree_entry *tree_entry;
|
||||
const git_tree_entry *entry;
|
||||
|
||||
tree_entry = git_tree_entry_byindex(self->owner->tree, self->i);
|
||||
if (!tree_entry)
|
||||
entry = git_tree_entry_byindex(self->owner->tree, self->i);
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
self->i += 1;
|
||||
return (TreeEntry*)wrap_tree_entry(git_tree_entry_dup(tree_entry),
|
||||
self->owner);
|
||||
|
||||
entry = git_tree_entry_dup(entry);
|
||||
if (entry == NULL) {
|
||||
PyErr_SetNone(PyExc_MemoryError);
|
||||
return NULL;
|
||||
}
|
||||
return wrap_tree_entry(entry);
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,11 +33,11 @@
|
||||
#include <git2.h>
|
||||
#include "types.h"
|
||||
|
||||
TreeEntry * wrap_tree_entry(const git_tree_entry *entry);
|
||||
PyObject* TreeEntry_get_filemode(TreeEntry *self);
|
||||
PyObject* TreeEntry_get_name(TreeEntry *self);
|
||||
PyObject* TreeEntry_get_oid(TreeEntry *self);
|
||||
PyObject* TreeEntry_get_hex(TreeEntry *self);
|
||||
PyObject* TreeEntry_to_object(TreeEntry *self);
|
||||
|
||||
TreeEntry* Tree_getitem_by_index(Tree *self, PyObject *py_index);
|
||||
TreeEntry* Tree_getitem(Tree *self, PyObject *value);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "utils.h"
|
||||
#include "oid.h"
|
||||
#include "treebuilder.h"
|
||||
#include "tree.h"
|
||||
|
||||
|
||||
void
|
||||
@ -44,9 +45,9 @@ TreeBuilder_dealloc(TreeBuilder *self)
|
||||
|
||||
|
||||
PyDoc_STRVAR(TreeBuilder_insert__doc__,
|
||||
"insert(name, oid, attr)\n"
|
||||
"\n"
|
||||
"Insert or replace an entry in the treebuilder.");
|
||||
"insert(name, oid, attr)\n"
|
||||
"\n"
|
||||
"Insert or replace an entry in the treebuilder.");
|
||||
|
||||
PyObject *
|
||||
TreeBuilder_insert(TreeBuilder *self, PyObject *args)
|
||||
@ -72,9 +73,9 @@ TreeBuilder_insert(TreeBuilder *self, PyObject *args)
|
||||
|
||||
|
||||
PyDoc_STRVAR(TreeBuilder_write__doc__,
|
||||
"write() -> bytes\n"
|
||||
"\n"
|
||||
"Write the tree to the given repository.");
|
||||
"write() -> bytes\n"
|
||||
"\n"
|
||||
"Write the tree to the given repository.");
|
||||
|
||||
PyObject *
|
||||
TreeBuilder_write(TreeBuilder *self)
|
||||
@ -90,10 +91,38 @@ TreeBuilder_write(TreeBuilder *self)
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(TreeBuilder_get__doc__,
|
||||
"get(name) -> TreeEntry\n"
|
||||
"\n"
|
||||
"Return the TreeEntry for the given name, or None if there is not.");
|
||||
|
||||
PyObject *
|
||||
TreeBuilder_get(TreeBuilder *self, PyObject *py_filename)
|
||||
{
|
||||
char *filename;
|
||||
const git_tree_entry *entry;
|
||||
|
||||
filename = py_path_to_c_str(py_filename);
|
||||
if (filename == NULL)
|
||||
return NULL;
|
||||
|
||||
entry = git_treebuilder_get(self->bld, filename);
|
||||
if (entry == NULL)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
entry = git_tree_entry_dup(entry);
|
||||
if (entry == NULL) {
|
||||
PyErr_SetNone(PyExc_MemoryError);
|
||||
return NULL;
|
||||
}
|
||||
return (PyObject*)wrap_tree_entry(entry);
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(TreeBuilder_remove__doc__,
|
||||
"remove(name)\n"
|
||||
"\n"
|
||||
"Remove an entry from the builder.");
|
||||
"remove(name)\n"
|
||||
"\n"
|
||||
"Remove an entry from the builder.");
|
||||
|
||||
PyObject *
|
||||
TreeBuilder_remove(TreeBuilder *self, PyObject *py_filename)
|
||||
@ -114,9 +143,9 @@ TreeBuilder_remove(TreeBuilder *self, PyObject *py_filename)
|
||||
|
||||
|
||||
PyDoc_STRVAR(TreeBuilder_clear__doc__,
|
||||
"clear()\n"
|
||||
"\n"
|
||||
"Clear all the entries in the builder.");
|
||||
"clear()\n"
|
||||
"\n"
|
||||
"Clear all the entries in the builder.");
|
||||
|
||||
PyObject *
|
||||
TreeBuilder_clear(TreeBuilder *self)
|
||||
@ -126,10 +155,11 @@ TreeBuilder_clear(TreeBuilder *self)
|
||||
}
|
||||
|
||||
PyMethodDef TreeBuilder_methods[] = {
|
||||
METHOD(TreeBuilder, insert, METH_VARARGS),
|
||||
METHOD(TreeBuilder, write, METH_NOARGS),
|
||||
METHOD(TreeBuilder, remove, METH_O),
|
||||
METHOD(TreeBuilder, clear, METH_NOARGS),
|
||||
METHOD(TreeBuilder, get, METH_O),
|
||||
METHOD(TreeBuilder, insert, METH_VARARGS),
|
||||
METHOD(TreeBuilder, remove, METH_O),
|
||||
METHOD(TreeBuilder, write, METH_NOARGS),
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -130,7 +130,6 @@ SIMPLE_TYPE(TreeBuilder, git_treebuilder, bld)
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *owner; /* Tree or TreeBuilder */
|
||||
const git_tree_entry *entry;
|
||||
} TreeEntry;
|
||||
|
||||
|
@ -71,23 +71,26 @@ class TreeTest(utils.BareRepoTestCase):
|
||||
self.assertTreeEntryEqual(tree['c/d'], sha, 'd', 0o0100644)
|
||||
self.assertRaisesWithArg(KeyError, 'ab/cd', lambda: tree['ab/cd'])
|
||||
|
||||
|
||||
def test_read_subtree(self):
|
||||
tree = self.repo[TREE_SHA]
|
||||
subtree_entry = tree['c']
|
||||
self.assertTreeEntryEqual(subtree_entry, SUBTREE_SHA, 'c', 0o0040000)
|
||||
|
||||
subtree = subtree_entry.to_object()
|
||||
subtree = self.repo[subtree_entry.oid]
|
||||
self.assertEqual(1, len(subtree))
|
||||
sha = '297efb891a47de80be0cfe9c639e4b8c9b450989'
|
||||
self.assertTreeEntryEqual(subtree[0], sha, 'd', 0o0100644)
|
||||
|
||||
|
||||
def test_new_tree(self):
|
||||
b0 = self.repo.create_blob('1')
|
||||
b1 = self.repo.create_blob('2')
|
||||
t = self.repo.TreeBuilder()
|
||||
repo = self.repo
|
||||
b0 = repo.create_blob('1')
|
||||
b1 = repo.create_blob('2')
|
||||
t = repo.TreeBuilder()
|
||||
t.insert('x', b0, 0o0100644)
|
||||
t.insert('y', b1, 0o0100755)
|
||||
tree = self.repo[t.write()]
|
||||
tree = repo[t.write()]
|
||||
|
||||
self.assertTrue('x' in tree)
|
||||
self.assertTrue('y' in tree)
|
||||
@ -97,9 +100,8 @@ class TreeTest(utils.BareRepoTestCase):
|
||||
self.assertEqual(x.filemode, 0o0100644)
|
||||
self.assertEqual(y.filemode, 0o0100755)
|
||||
|
||||
self.assertEqual(x.to_object().oid, b0)
|
||||
self.assertEqual(y.to_object().oid, b1)
|
||||
|
||||
self.assertEqual(repo[x.oid].oid, b0)
|
||||
self.assertEqual(repo[y.oid].oid, b1)
|
||||
|
||||
|
||||
def test_modify_tree(self):
|
||||
@ -107,6 +109,7 @@ class TreeTest(utils.BareRepoTestCase):
|
||||
self.assertRaises(TypeError, operator.setitem, 'c', tree['a'])
|
||||
self.assertRaises(TypeError, operator.delitem, 'c')
|
||||
|
||||
|
||||
def test_iterate_tree(self):
|
||||
"""
|
||||
Testing that we're able to iterate of a Tree object and that the
|
||||
|
@ -63,8 +63,11 @@ class TreeBuilderTest(utils.BareRepoTestCase):
|
||||
def test_rebuild_treebuilder(self):
|
||||
tree = self.repo[TREE_SHA]
|
||||
bld = self.repo.TreeBuilder()
|
||||
for e in tree:
|
||||
bld.insert(e.name, e.hex, e.filemode)
|
||||
for entry in tree:
|
||||
name = entry.name
|
||||
self.assertIsNone(bld.get(name))
|
||||
bld.insert(name, entry.hex, entry.filemode)
|
||||
self.assertEqual(bld.get(name).oid, entry.oid)
|
||||
result = bld.write()
|
||||
|
||||
self.assertEqual(len(bld), len(tree))
|
||||
|
Loading…
Reference in New Issue
Block a user