From 9e91a390cc39625ebc72d609e1be6d04c71fab25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 27 May 2014 18:24:53 +0200 Subject: [PATCH] Index: accept a tree for read_tree() An index may not have an associated repository, so giving it an id in that case is useless. Raise an error in that case and accept a Tree object to make the function useful then. --- docs/working-copy.rst | 8 ++++++++ src/index.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/docs/working-copy.rst b/docs/working-copy.rst index 76bcada87..88762b706 100644 --- a/docs/working-copy.rst +++ b/docs/working-copy.rst @@ -26,6 +26,14 @@ Custom entries:: >>> entry = pygit2.IndexEntry('README.md', blob_id, blob_filemode) >>> repo.index.add(entry) +The index fulfills a dual role as the in-memory representation of the +index file and data structure which represents a flat list of a +tree. You can use it independently of the index file, e.g. + + >>> index = pygit2.Index() + >>> entry = pygit2.IndexEntry('README.md', blob_id, blob_filemode) + >>> index.add(entry) + The Index type ==================== diff --git a/src/index.c b/src/index.c index 0cb8207b7..6a855f41a 100644 --- a/src/index.c +++ b/src/index.c @@ -426,26 +426,46 @@ Index_remove(Index *self, PyObject *args) PyDoc_STRVAR(Index_read_tree__doc__, "read_tree(tree)\n" "\n" - "Update the index file from the tree identified by the given oid."); + "Update the index file from the specified tree. The tree can be a Tree object or an Oid.\n" + "Using an Oid is only possible if this index is associated with a repository"); PyObject * Index_read_tree(Index *self, PyObject *value) { git_oid oid; - git_tree *tree; - int err; + git_tree *tree = NULL; + int err, need_free = 0; size_t len; len = py_oid_to_git_oid(value, &oid); - if (len == 0) - return NULL; + if (len == 0) { + Tree *py_tree; + if (!PyObject_TypeCheck(value, &TreeType)) { + return NULL; + } - err = git_tree_lookup_prefix(&tree, self->repo->repo, &oid, len); - if (err < 0) - return Error_set(err); + PyErr_Clear(); + py_tree = (Tree *) value; + tree = py_tree->tree; + } + + /* + * if the user passed in an id but we're not associated with a + * repo, we can't do anything + */ + if (tree == NULL && self->repo == NULL) { + PyErr_SetString(PyExc_TypeError, "id given but no associated repository"); + return NULL; + } else if (tree == NULL) { + need_free = 1; + err = git_tree_lookup_prefix(&tree, self->repo->repo, &oid, len); + if (err < 0) + return Error_set(err); + } err = git_index_read_tree(self->index, tree); - git_tree_free(tree); + if (need_free) + git_tree_free(tree); if (err < 0) return Error_set(err);