Merge remote branch 'byron/repo_write_improved' into repo_write
This commit is contained in:
59
pygit2.c
59
pygit2.c
@@ -169,7 +169,7 @@ Error_set_py_obj(int err, PyObject *py_obj) {
|
|||||||
assert(err < 0);
|
assert(err < 0);
|
||||||
|
|
||||||
if (err == GIT_ENOTOID && !PyString_Check(py_obj)) {
|
if (err == GIT_ENOTOID && !PyString_Check(py_obj)) {
|
||||||
PyErr_Format(PyExc_TypeError, "Git object id must be str, not %.200s",
|
PyErr_Format(PyExc_TypeError, "Git object id must be 40 byte hexadecimal str, or 20 byte binary str: %.200s",
|
||||||
py_obj->ob_type->tp_name);
|
py_obj->ob_type->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (err == GIT_ENOTFOUND) {
|
} else if (err == GIT_ENOTFOUND) {
|
||||||
@@ -223,6 +223,18 @@ lookup_object(Repository *repo, const git_oid *oid, git_otype type) {
|
|||||||
return (PyObject*)py_obj;
|
return (PyObject*)py_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static git_otype
|
||||||
|
int_to_loose_object_type(int type_id)
|
||||||
|
{
|
||||||
|
switch((git_otype)type_id) {
|
||||||
|
case GIT_OBJ_COMMIT: return GIT_OBJ_COMMIT;
|
||||||
|
case GIT_OBJ_TREE: return GIT_OBJ_TREE;
|
||||||
|
case GIT_OBJ_BLOB: return GIT_OBJ_BLOB;
|
||||||
|
case GIT_OBJ_TAG: return GIT_OBJ_TAG;
|
||||||
|
default: return GIT_OBJ_BAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
wrap_reference(git_reference * c_reference)
|
wrap_reference(git_reference * c_reference)
|
||||||
{
|
{
|
||||||
@@ -261,6 +273,16 @@ py_str_to_git_oid(PyObject *py_str, git_oid *oid) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
git_oid_to_py_string(git_oid* oid)
|
||||||
|
{
|
||||||
|
char buf[GIT_OID_HEXSZ+1];
|
||||||
|
if (strlen(git_oid_to_string(buf, sizeof(buf), oid)) != GIT_OID_HEXSZ)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return PyString_FromStringAndSize(buf, GIT_OID_HEXSZ);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Repository_init(Repository *self, PyObject *args, PyObject *kwds) {
|
Repository_init(Repository *self, PyObject *args, PyObject *kwds) {
|
||||||
char *path;
|
char *path;
|
||||||
@@ -341,6 +363,37 @@ Repository_read(Repository *self, PyObject *py_hex) {
|
|||||||
return tuple;
|
return tuple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Repository_write(Repository *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
git_oid oid;
|
||||||
|
git_odb_stream* stream;
|
||||||
|
|
||||||
|
int type_id;
|
||||||
|
const char* buffer;
|
||||||
|
Py_ssize_t buflen;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "Is#", &type_id, &buffer, &buflen))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
git_otype type = int_to_loose_object_type(type_id);
|
||||||
|
if (type == GIT_OBJ_BAD)
|
||||||
|
return Error_set_str(-100, "Invalid object type");
|
||||||
|
|
||||||
|
git_odb* odb = git_repository_database(self->repo);
|
||||||
|
|
||||||
|
if ((err = git_odb_open_wstream(&stream, odb, buflen, type)) == GIT_SUCCESS) {
|
||||||
|
stream->write(stream, buffer, buflen);
|
||||||
|
err = stream->finalize_write(&oid, stream);
|
||||||
|
stream->free(stream);
|
||||||
|
}
|
||||||
|
if (err < 0)
|
||||||
|
return Error_set_str(err, "failed to write data");
|
||||||
|
|
||||||
|
return git_oid_to_py_string(&oid);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Repository_get_index(Repository *self, void *closure) {
|
Repository_get_index(Repository *self, void *closure) {
|
||||||
int err;
|
int err;
|
||||||
@@ -689,6 +742,10 @@ static PyMethodDef Repository_methods[] = {
|
|||||||
"Generator that traverses the history starting from the given commit."},
|
"Generator that traverses the history starting from the given commit."},
|
||||||
{"read", (PyCFunction)Repository_read, METH_O,
|
{"read", (PyCFunction)Repository_read, METH_O,
|
||||||
"Read raw object data from the repository."},
|
"Read raw object data from the repository."},
|
||||||
|
{"write", (PyCFunction)Repository_write, METH_VARARGS,
|
||||||
|
"Write raw object data into the repository. First arg is the object type number, \n\
|
||||||
|
the second one a buffer with data.\n\
|
||||||
|
Return the hexadecimal sha of the created object"},
|
||||||
{"listall_references", (PyCFunction)Repository_listall_references,
|
{"listall_references", (PyCFunction)Repository_listall_references,
|
||||||
METH_VARARGS,
|
METH_VARARGS,
|
||||||
"Return a list with all the references that can be found in a "
|
"Return a list with all the references that can be found in a "
|
||||||
|
@@ -53,6 +53,17 @@ class RepositoryTest(utils.BareRepoTestCase):
|
|||||||
|
|
||||||
a2 = self.repo.read('7f129fd57e31e935c6d60a0c794efe4e6927664b')
|
a2 = self.repo.read('7f129fd57e31e935c6d60a0c794efe4e6927664b')
|
||||||
self.assertEqual((pygit2.GIT_OBJ_BLOB, 'a contents 2\n'), a2)
|
self.assertEqual((pygit2.GIT_OBJ_BLOB, 'a contents 2\n'), a2)
|
||||||
|
|
||||||
|
def test_write(self):
|
||||||
|
data = "hello world"
|
||||||
|
# invalid object type
|
||||||
|
self.assertRaises(pygit2.GitError, self.repo.write, pygit2.GIT_OBJ_ANY, data)
|
||||||
|
|
||||||
|
hex_sha = self.repo.write(pygit2.GIT_OBJ_BLOB, data)
|
||||||
|
self.assertEqual(len(hex_sha), 40)
|
||||||
|
|
||||||
|
# works as buffer as well
|
||||||
|
self.assertEqual(hex_sha, self.repo.write(pygit2.GIT_OBJ_BLOB, buffer(data)))
|
||||||
|
|
||||||
def test_contains(self):
|
def test_contains(self):
|
||||||
self.assertRaises(TypeError, lambda: 123 in self.repo)
|
self.assertRaises(TypeError, lambda: 123 in self.repo)
|
||||||
|
Reference in New Issue
Block a user