Merge remote-tracking branch 'carlos/index-add-entry'
This commit is contained in:
@@ -22,6 +22,9 @@ Index write::
|
|||||||
>>> del index['path/to/file'] # git rm
|
>>> del index['path/to/file'] # git rm
|
||||||
>>> index.write() # don't forget to save the changes
|
>>> index.write() # don't forget to save the changes
|
||||||
|
|
||||||
|
Custom entries::
|
||||||
|
>>> entry = pygit2.IndexEntry('README.md', blob_id, blob_filemode)
|
||||||
|
>>> repo.index.add(entry)
|
||||||
|
|
||||||
The Index type
|
The Index type
|
||||||
====================
|
====================
|
||||||
|
126
src/index.c
126
src/index.c
@@ -39,6 +39,8 @@ extern PyTypeObject TreeType;
|
|||||||
extern PyTypeObject DiffType;
|
extern PyTypeObject DiffType;
|
||||||
extern PyTypeObject IndexIterType;
|
extern PyTypeObject IndexIterType;
|
||||||
extern PyTypeObject IndexEntryType;
|
extern PyTypeObject IndexEntryType;
|
||||||
|
extern PyTypeObject OidType;
|
||||||
|
extern PyTypeObject RepositoryType;
|
||||||
|
|
||||||
int
|
int
|
||||||
Index_init(Index *self, PyObject *args, PyObject *kwds)
|
Index_init(Index *self, PyObject *args, PyObject *kwds)
|
||||||
@@ -81,7 +83,7 @@ Index_traverse(Index *self, visitproc visit, void *arg)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Index_add__doc__,
|
PyDoc_STRVAR(Index_add__doc__,
|
||||||
"add(path)\n"
|
"add([path|entry])\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Add or update an index entry from a file in disk.");
|
"Add or update an index entry from a file in disk.");
|
||||||
|
|
||||||
@@ -90,6 +92,16 @@ Index_add(Index *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
const char *path;
|
const char *path;
|
||||||
|
IndexEntry *py_entry;
|
||||||
|
|
||||||
|
if (PyArg_ParseTuple(args, "O!", &IndexEntryType, &py_entry)) {
|
||||||
|
err = git_index_add(self->index, &py_entry->entry);
|
||||||
|
if (err < 0)
|
||||||
|
return Error_set(err);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &path))
|
if (!PyArg_ParseTuple(args, "s", &path))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -314,8 +326,15 @@ wrap_index_entry(const git_index_entry *entry, Index *index)
|
|||||||
IndexEntry *py_entry;
|
IndexEntry *py_entry;
|
||||||
|
|
||||||
py_entry = PyObject_New(IndexEntry, &IndexEntryType);
|
py_entry = PyObject_New(IndexEntry, &IndexEntryType);
|
||||||
if (py_entry)
|
if (!py_entry)
|
||||||
py_entry->entry = entry;
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(&py_entry->entry, entry, sizeof(struct git_index_entry));
|
||||||
|
py_entry->entry.path = strdup(entry->path);
|
||||||
|
if (!py_entry->entry.path) {
|
||||||
|
Py_CLEAR(py_entry);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return (PyObject*)py_entry;
|
return (PyObject*)py_entry;
|
||||||
}
|
}
|
||||||
@@ -410,17 +429,26 @@ Index_read_tree(Index *self, PyObject *value)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Index_write_tree__doc__,
|
PyDoc_STRVAR(Index_write_tree__doc__,
|
||||||
"write_tree() -> Oid\n"
|
"write_tree([repo]) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create a tree object from the index file, return its oid.");
|
"Create a tree object from the index file, return its oid.\n"
|
||||||
|
"If 'repo' is passed, write to that repository's odb.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Index_write_tree(Index *self)
|
Index_write_tree(Index *self, PyObject *args)
|
||||||
{
|
{
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
|
Repository *repo = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = git_index_write_tree(&oid, self->index);
|
if (!PyArg_ParseTuple(args, "|O!", &RepositoryType, &repo))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (repo)
|
||||||
|
err = git_index_write_tree_to(&oid, self->index, repo->repo);
|
||||||
|
else
|
||||||
|
err = git_index_write_tree(&oid, self->index);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
@@ -437,7 +465,7 @@ PyMethodDef Index_methods[] = {
|
|||||||
METHOD(Index, read, METH_VARARGS),
|
METHOD(Index, read, METH_VARARGS),
|
||||||
METHOD(Index, write, METH_NOARGS),
|
METHOD(Index, write, METH_NOARGS),
|
||||||
METHOD(Index, read_tree, METH_O),
|
METHOD(Index, read_tree, METH_O),
|
||||||
METHOD(Index, write_tree, METH_NOARGS),
|
METHOD(Index, write_tree, METH_VARARGS),
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -557,6 +585,31 @@ PyTypeObject IndexIterType = {
|
|||||||
(iternextfunc)IndexIter_iternext, /* tp_iternext */
|
(iternextfunc)IndexIter_iternext, /* tp_iternext */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
IndexEntry_init(IndexEntry *self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
char *c_path = NULL;
|
||||||
|
Oid *id = NULL;
|
||||||
|
unsigned int mode;
|
||||||
|
char *keywords[] = {"path", "oid", "mode", NULL};
|
||||||
|
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO!I", keywords,
|
||||||
|
&c_path, &OidType, &id, &mode))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(&self->entry, 0, sizeof(struct git_index_entry));
|
||||||
|
if (c_path)
|
||||||
|
self->entry.path = c_path;
|
||||||
|
|
||||||
|
if (id)
|
||||||
|
git_oid_cpy(&self->entry.oid, &id->oid);
|
||||||
|
|
||||||
|
if (mode)
|
||||||
|
self->entry.mode = mode;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IndexEntry_dealloc(IndexEntry *self)
|
IndexEntry_dealloc(IndexEntry *self)
|
||||||
{
|
{
|
||||||
@@ -569,40 +622,81 @@ PyDoc_STRVAR(IndexEntry_mode__doc__, "Mode.");
|
|||||||
PyObject *
|
PyObject *
|
||||||
IndexEntry_mode__get__(IndexEntry *self)
|
IndexEntry_mode__get__(IndexEntry *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromLong(self->entry->mode);
|
return PyLong_FromLong(self->entry.mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
IndexEntry_mode__set__(IndexEntry *self, PyObject *py_mode)
|
||||||
|
{
|
||||||
|
long c_val;
|
||||||
|
|
||||||
|
c_val = PyLong_AsLong(py_mode);
|
||||||
|
if (c_val == -1 && PyErr_Occurred())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
self->entry.mode = (unsigned int) c_val;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(IndexEntry_path__doc__, "Path.");
|
PyDoc_STRVAR(IndexEntry_path__doc__, "Path.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
IndexEntry_path__get__(IndexEntry *self)
|
IndexEntry_path__get__(IndexEntry *self)
|
||||||
{
|
{
|
||||||
return to_path(self->entry->path);
|
return to_path(self->entry.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
IndexEntry_path__set__(IndexEntry *self, PyObject *py_path)
|
||||||
|
{
|
||||||
|
char *c_inner, *c_path;
|
||||||
|
|
||||||
|
c_inner = py_str_to_c_str(py_path, NULL);
|
||||||
|
if (!c_inner)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
c_path = strdup(c_inner);
|
||||||
|
if (!c_path) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(self->entry.path);
|
||||||
|
self->entry.path = c_path;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(IndexEntry_oid__doc__, "Object id.");
|
PyDoc_STRVAR(IndexEntry_oid__doc__, "Object id.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
IndexEntry_oid__get__(IndexEntry *self)
|
IndexEntry_oid__get__(IndexEntry *self)
|
||||||
{
|
{
|
||||||
return git_oid_to_python(&self->entry->oid);
|
return git_oid_to_python(&self->entry.oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
IndexEntry_oid__set__(IndexEntry *self, PyObject *py_id)
|
||||||
|
{
|
||||||
|
if (!py_oid_to_git_oid(py_id, &self->entry.oid))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(IndexEntry_hex__doc__, "Hex id.");
|
PyDoc_STRVAR(IndexEntry_hex__doc__, "Hex id.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
IndexEntry_hex__get__(IndexEntry *self)
|
IndexEntry_hex__get__(IndexEntry *self)
|
||||||
{
|
{
|
||||||
return git_oid_to_py_str(&self->entry->oid);
|
return git_oid_to_py_str(&self->entry.oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyGetSetDef IndexEntry_getseters[] = {
|
PyGetSetDef IndexEntry_getseters[] = {
|
||||||
GETTER(IndexEntry, mode),
|
GETSET(IndexEntry, mode),
|
||||||
GETTER(IndexEntry, path),
|
GETSET(IndexEntry, path),
|
||||||
GETTER(IndexEntry, oid),
|
GETSET(IndexEntry, oid),
|
||||||
GETTER(IndexEntry, hex),
|
GETTER(IndexEntry, hex),
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
@@ -645,7 +739,7 @@ PyTypeObject IndexEntryType = {
|
|||||||
0, /* tp_descr_get */
|
0, /* tp_descr_get */
|
||||||
0, /* tp_descr_set */
|
0, /* tp_descr_set */
|
||||||
0, /* tp_dictoffset */
|
0, /* tp_dictoffset */
|
||||||
0, /* tp_init */
|
(initproc)IndexEntry_init, /* tp_init */
|
||||||
0, /* tp_alloc */
|
0, /* tp_alloc */
|
||||||
0, /* tp_new */
|
0, /* tp_new */
|
||||||
};
|
};
|
||||||
|
@@ -40,7 +40,7 @@ PyObject* Index_write(Index *self);
|
|||||||
PyObject* Index_iter(Index *self);
|
PyObject* Index_iter(Index *self);
|
||||||
PyObject* Index_getitem(Index *self, PyObject *value);
|
PyObject* Index_getitem(Index *self, PyObject *value);
|
||||||
PyObject* Index_read_tree(Index *self, PyObject *value);
|
PyObject* Index_read_tree(Index *self, PyObject *value);
|
||||||
PyObject* Index_write_tree(Index *self);
|
PyObject* Index_write_tree(Index *self, PyObject *args);
|
||||||
Py_ssize_t Index_len(Index *self);
|
Py_ssize_t Index_len(Index *self);
|
||||||
int Index_setitem(Index *self, PyObject *key, PyObject *value);
|
int Index_setitem(Index *self, PyObject *key, PyObject *value);
|
||||||
|
|
||||||
|
@@ -354,7 +354,7 @@ moduleinit(PyObject* m)
|
|||||||
* Index & Working copy
|
* Index & Working copy
|
||||||
*/
|
*/
|
||||||
INIT_TYPE(IndexType, NULL, PyType_GenericNew)
|
INIT_TYPE(IndexType, NULL, PyType_GenericNew)
|
||||||
INIT_TYPE(IndexEntryType, NULL, NULL)
|
INIT_TYPE(IndexEntryType, NULL, PyType_GenericNew)
|
||||||
INIT_TYPE(IndexIterType, NULL, NULL)
|
INIT_TYPE(IndexIterType, NULL, NULL)
|
||||||
ADD_TYPE(m, Index)
|
ADD_TYPE(m, Index)
|
||||||
ADD_TYPE(m, IndexEntry)
|
ADD_TYPE(m, IndexEntry)
|
||||||
|
@@ -153,7 +153,7 @@ SIMPLE_TYPE(Index, git_index, index)
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
const git_index_entry *entry;
|
git_index_entry entry;
|
||||||
} IndexEntry;
|
} IndexEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -31,6 +31,7 @@ from __future__ import absolute_import
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
|
import tempfile
|
||||||
|
|
||||||
import pygit2
|
import pygit2
|
||||||
from . import utils
|
from . import utils
|
||||||
@@ -139,6 +140,36 @@ class IndexTest(utils.RepoTestCase):
|
|||||||
index.remove('hello.txt')
|
index.remove('hello.txt')
|
||||||
self.assertFalse('hello.txt' in index)
|
self.assertFalse('hello.txt' in index)
|
||||||
|
|
||||||
|
def test_change_attributes(self):
|
||||||
|
index = self.repo.index
|
||||||
|
entry = index['hello.txt']
|
||||||
|
ign_entry = index['.gitignore']
|
||||||
|
self.assertNotEqual(ign_entry.oid, entry.oid)
|
||||||
|
self.assertNotEqual(entry.mode, pygit2.GIT_FILEMODE_BLOB_EXECUTABLE)
|
||||||
|
entry.path = 'foo.txt'
|
||||||
|
entry.oid = ign_entry.oid
|
||||||
|
entry.mode = pygit2.GIT_FILEMODE_BLOB_EXECUTABLE
|
||||||
|
self.assertEqual('foo.txt', entry.path)
|
||||||
|
self.assertEqual(ign_entry.oid, entry.oid)
|
||||||
|
self.assertEqual(pygit2.GIT_FILEMODE_BLOB_EXECUTABLE, entry.mode)
|
||||||
|
|
||||||
|
def test_write_tree_to(self):
|
||||||
|
path = tempfile.mkdtemp()
|
||||||
|
pygit2.init_repository(path)
|
||||||
|
nrepo = pygit2.Repository(path)
|
||||||
|
|
||||||
|
id = self.repo.index.write_tree(nrepo)
|
||||||
|
self.assertNotEqual(None, nrepo[id])
|
||||||
|
|
||||||
|
class IndexEntryTest(utils.RepoTestCase):
|
||||||
|
|
||||||
|
def test_create_entry(self):
|
||||||
|
index = self.repo.index
|
||||||
|
hello_entry = index['hello.txt']
|
||||||
|
entry = pygit2.IndexEntry('README.md', hello_entry.oid, hello_entry.mode)
|
||||||
|
index.add(entry)
|
||||||
|
tree_id = index.write_tree()
|
||||||
|
self.assertEqual('60e769e57ae1d6a2ab75d8d253139e6260e1f912', str(tree_id))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Reference in New Issue
Block a user