Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/working-copy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
====================

Expand Down
43 changes: 32 additions & 11 deletions src/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,18 @@ extern PyTypeObject RepositoryType;
int
Index_init(Index *self, PyObject *args, PyObject *kwds)
{
char *path;
char *path = NULL;
int err;

if (kwds && PyDict_Size(kwds) > 0) {
PyErr_SetString(PyExc_TypeError, "Index takes no keyword arguments");
return -1;
}

if (!PyArg_ParseTuple(args, "s", &path))
if (!PyArg_ParseTuple(args, "|s", &path))
return -1;

self->repo = NULL;
err = git_index_open(&self->index, path);
if (err < 0) {
Error_set_str(err, path);
Expand Down Expand Up @@ -425,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);

Expand Down
16 changes: 15 additions & 1 deletion test/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import tempfile

import pygit2
from pygit2 import Repository
from pygit2 import Repository, Index
from . import utils


Expand Down Expand Up @@ -206,5 +206,19 @@ def test_create_entry(self):
tree_id = index.write_tree()
self.assertEqual('60e769e57ae1d6a2ab75d8d253139e6260e1f912', str(tree_id))

class StandaloneIndexTest(utils.RepoTestCase):

def test_create_empty(self):
index = Index()

def test_create_empty_read_tree_as_string(self):
index = Index()
# no repo associated, so we don't know where to read from
self.assertRaises(TypeError, index, 'read_tree', 'fd937514cb799514d4b81bb24c5fcfeb6472b245')

def test_create_empty_read_tree(self):
index = Index()
index.read_tree(self.repo['fd937514cb799514d4b81bb24c5fcfeb6472b245'])

if __name__ == '__main__':
unittest.main()