diff --git a/README.rst b/README.rst index 4154545..9e72c5e 100644 --- a/README.rst +++ b/README.rst @@ -165,6 +165,7 @@ This is the interface of a tree entry:: TreeEntry.oid -- the id of the git object TreeEntry.hex -- hexadecimal representation of the oid TreeEntry.attributes -- the Unix file attributes + TreeEntry.to_object() -- returns the git object (equivalent to repo[entry.oid]) Blobs ----------------- diff --git a/pygit2.c b/pygit2.c index cb4d826..fbc7226 100644 --- a/pygit2.c +++ b/pygit2.c @@ -108,6 +108,7 @@ OBJECT_STRUCT(Walker, git_revwalk, walk) typedef struct { PyObject_HEAD const git_tree_entry *entry; + Tree *tree; } TreeEntry; typedef struct { @@ -1328,6 +1329,7 @@ static PyTypeObject CommitType = { static void TreeEntry_dealloc(TreeEntry *self) { + Py_XDECREF(self->tree); PyObject_Del(self); } @@ -1358,6 +1360,15 @@ TreeEntry_get_hex(TreeEntry *self) return git_oid_to_py_str(git_tree_entry_id(self->entry)); } +static PyObject * +TreeEntry_to_object(TreeEntry *self) +{ + const git_oid *entry_oid; + + entry_oid = git_tree_entry_id(self->entry); + return lookup_object(self->tree->repo, entry_oid, GIT_OBJ_ANY); +} + static PyGetSetDef TreeEntry_getseters[] = { {"attributes", (getter)TreeEntry_get_attributes, NULL, "attributes", NULL}, {"name", (getter)TreeEntry_get_name, NULL, "name", NULL}, @@ -1366,6 +1377,12 @@ static PyGetSetDef TreeEntry_getseters[] = { {NULL} }; +static PyMethodDef TreeEntry_methods[] = { + {"to_object", (PyCFunction)TreeEntry_to_object, METH_NOARGS, + "Look up the corresponding object in the repo."}, + {NULL, NULL, 0, NULL} +}; + static PyTypeObject TreeEntryType = { PyVarObject_HEAD_INIT(NULL, 0) "pygit2.TreeEntry", /* tp_name */ @@ -1394,7 +1411,7 @@ static PyTypeObject TreeEntryType = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + TreeEntry_methods, /* tp_methods */ 0, /* tp_members */ TreeEntry_getseters, /* tp_getset */ 0, /* tp_base */ @@ -1432,8 +1449,11 @@ wrap_tree_entry(const git_tree_entry *entry, Tree *tree) TreeEntry *py_entry; py_entry = PyObject_New(TreeEntry, &TreeEntryType); - if (py_entry) + if (py_entry) { py_entry->entry = entry; + py_entry->tree = tree; + Py_INCREF(tree); + } return py_entry; } diff --git a/test/test_tree.py b/test/test_tree.py index 567b5f0..571f702 100644 --- a/test/test_tree.py +++ b/test/test_tree.py @@ -71,21 +71,20 @@ class TreeTest(utils.BareRepoTestCase): self.assertTreeEntryEqual(tree['b'], sha, 'b', 0o0100644) def test_read_subtree(self): - repo = self.repo - tree = repo[TREE_SHA] + tree = self.repo[TREE_SHA] subtree_entry = tree['c'] self.assertTreeEntryEqual(subtree_entry, SUBTREE_SHA, 'c', 0o0040000) - subtree = repo[subtree_entry.oid] + subtree = subtree_entry.to_object() self.assertEqual(1, len(subtree)) sha = '297efb891a47de80be0cfe9c639e4b8c9b450989' self.assertTreeEntryEqual(subtree[0], sha, 'd', 0o0100644) - # TODO This test worked with libgit2 v0.10.0, update to use the - # tree-builder + # XXX Creating new trees was removed from libgit2 by v0.11.0, we + # deactivate this test temporarily, since the feature may come back in + # a near feature (if it does not this test will be removed). def xtest_new_tree(self): - repo = self.repo - tree = pygit2.Tree(repo) + tree = pygit2.Tree(self.repo) self.assertEqual(0, len(tree)) tree.add_entry('1' * 40, 'x', 0o0100644) tree.add_entry('2' * 40, 'y', 0o0100755) @@ -104,7 +103,8 @@ class TreeTest(utils.BareRepoTestCase): self.assertEqual(None, tree.hex) tree.write() contents = '100644 x\0%s100755 y\0%s' % ('\x11' * 20, '\x22' * 20) - self.assertEqual((pygit2.GIT_OBJ_TREE, contents), repo.read(tree.hex)) + self.assertEqual((pygit2.GIT_OBJ_TREE, contents), + self.repo.read(tree.hex)) def test_modify_tree(self): tree = self.repo[TREE_SHA]