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