Updating to libgit2 v0.11.0 (work in progress)

This commit is contained in:
J. David Ibáñez 2011-03-31 19:06:10 +02:00
parent 6c7df765c1
commit aa2982b687

446
pygit2.c

@ -276,28 +276,29 @@ Repository_getitem(Repository *self, PyObject *value) {
}
static int
Repository_read_raw(git_rawobj *raw, git_repository *repo, const git_oid *oid) {
return git_odb_read(raw, git_repository_database(repo), oid);
Repository_read_raw(git_odb_object **obj, git_repository *repo, const git_oid *oid) {
return git_odb_read(obj, git_repository_database(repo), oid);
}
static PyObject *
Repository_read(Repository *self, PyObject *py_hex) {
git_oid oid;
int err;
git_rawobj raw;
PyObject *result;
git_odb_object *obj;
err = py_str_to_git_oid(py_hex, &oid);
if (err < 0)
return NULL;
err = Repository_read_raw(&raw, self->repo, &oid);
err = Repository_read_raw(&obj, self->repo, &oid);
if (err < 0)
return Error_set_py_obj(err, py_hex);
result = Py_BuildValue("(ns#)", raw.type, raw.data, raw.len);
free(raw.data);
return result;
return Py_BuildValue(
"(ns#)",
git_odb_object_type(obj),
git_odb_object_data(obj),
git_odb_object_size(obj));
}
static PyObject *
@ -353,11 +354,7 @@ Repository_walk(Repository *self, PyObject *args)
return Error_set(err);
/* Sort */
err = git_revwalk_sorting(walk, sort);
if (err < 0) {
git_revwalk_free(walk);
return Error_set(err);
}
git_revwalk_sorting(walk, sort);
/* Push */
if (value != Py_None) {
@ -390,7 +387,7 @@ static PyMethodDef Repository_methods[] = {
"Generator that traverses the history starting from the given commit."},
{"read", (PyCFunction)Repository_read, METH_O,
"Read raw object data from the repository."},
{NULL, NULL, 0, NULL}
{NULL}
};
static PyGetSetDef Repository_getseters[] = {
@ -486,7 +483,7 @@ Object_get_sha(Object *self) {
static PyObject *
Object_read_raw(Object *self) {
const git_oid *id;
git_rawobj raw;
git_odb_object *obj;
int err;
PyObject *result = NULL, *py_sha = NULL;
@ -494,35 +491,22 @@ Object_read_raw(Object *self) {
if (!id)
Py_RETURN_NONE; /* in-memory object */
err = Repository_read_raw(&raw, self->repo->repo, id);
err = Repository_read_raw(&obj, self->repo->repo, id);
if (err < 0) {
py_sha = Object_get_sha(self);
Error_set_py_obj(err, py_sha);
goto cleanup;
}
result = PyString_FromStringAndSize(raw.data, raw.len);
result = PyString_FromStringAndSize(
git_odb_object_data(obj),
git_odb_object_size(obj));
cleanup:
Py_XDECREF(py_sha);
free(raw.data);
return result;
}
static PyObject *
Object_write(Object *self) {
int err;
PyObject *py_sha;
err = git_object_write(self->obj);
if (err < 0) {
py_sha = Object_get_sha(self);
Error_set_py_obj(err, py_sha);
Py_DECREF(py_sha);
return NULL;
}
Py_RETURN_NONE;
}
static PyGetSetDef Object_getseters[] = {
{"type", (getter)Object_get_type, NULL, "type number", NULL},
{"sha", (getter)Object_get_sha, NULL, "hex SHA", NULL},
@ -532,8 +516,6 @@ static PyGetSetDef Object_getseters[] = {
static PyMethodDef Object_methods[] = {
{"read_raw", (PyCFunction)Object_read_raw, METH_NOARGS,
"Read the raw contents of the object from the repo."},
{"write", (PyCFunction)Object_write, METH_NOARGS,
"Write the object to the repo, if changed."},
{NULL}
};
@ -579,40 +561,6 @@ static PyTypeObject ObjectType = {
0, /* tp_new */
};
static int
Object_init_with_type(Object *py_obj, const git_otype type, PyObject *args,
PyObject *kwds) {
Repository *repo = NULL;
git_object *obj;
int err;
if (kwds) {
PyErr_Format(PyExc_TypeError, "%s takes no keyword arugments",
py_obj->ob_type->tp_name);
return -1;
}
if (!PyArg_ParseTuple(args, "O", &repo))
return -1;
if (!PyObject_TypeCheck(repo, &RepositoryType)) {
PyErr_Format(PyExc_TypeError,
"repo argument must be %.200s, not %.200s",
RepositoryType.tp_name, repo->ob_type->tp_name);
return -1;
}
err = git_object_new(&obj, repo->repo, type);
if (err < 0) {
Error_set(err);
return -1;
}
Py_INCREF(repo);
py_obj->repo = repo;
py_obj->obj = obj;
return 0;
}
static PyObject *
build_person(const char *name, const char *email, long long time) {
return Py_BuildValue("(ssL)", name, email, time);
@ -625,8 +573,34 @@ parse_person(PyObject *value, char **name, char **email, long long *time) {
static int
Commit_init(Commit *py_commit, PyObject *args, PyObject *kwds) {
return Object_init_with_type((Object*)py_commit, GIT_OBJ_COMMIT, args,
kwds);
Repository *repo = NULL;
git_oid oid;
git_commit *commit;
int err;
if (kwds) {
PyErr_Format(PyExc_TypeError, "%s takes no keyword arugments",
py_commit->ob_type->tp_name);
return -1;
}
/* TODO Finish this */
if (!PyArg_ParseTuple(args, "O!", &RepositoryType, &repo))
return -1;
err = git_commit_create(&oid, repo->repo, NULL,
author, committer, message, tree_oid, parent_count, parent_oids);
if (err < 0)
return -1;
err = git_commit_lookup(&commit, repo->repo, &oid);
if (err < 0)
return -1;
Py_INCREF(repo);
py_commit->repo = repo;
py_commit->commit = commit;
return 0;
}
static PyObject *
@ -639,17 +613,6 @@ Commit_get_message(Commit *commit) {
return PyString_FromString(git_commit_message(commit->commit));
}
static int
Commit_set_message(Commit *commit, PyObject *message) {
if (!PyString_Check(message)) {
PyErr_Format(PyExc_TypeError, "message must be str, not %.200s",
message->ob_type->tp_name);
return -1;
}
git_commit_set_message(commit->commit, PyString_AS_STRING(message));
return 0;
}
static PyObject *
Commit_get_commit_time(Commit *commit) {
return PyLong_FromLong(git_commit_time(commit->commit));
@ -664,21 +627,6 @@ Commit_get_committer(Commit *commit) {
committer->when.time);
}
static int
Commit_set_committer(Commit *commit, PyObject *value) {
char *name = NULL, *email = NULL;
long long time;
if (!parse_person(value, &name, &email, &time))
return -1;
git_signature *signature = git_signature_new(name, email, time, 0);
if ( signature == NULL)
return -1;
git_commit_set_committer(commit->commit, signature);
return 0;
}
static PyObject *
Commit_get_author(Commit *commit) {
const git_signature *author = git_commit_author(commit->commit);
@ -688,20 +636,6 @@ Commit_get_author(Commit *commit) {
author->when.time);
}
static int
Commit_set_author(Commit *commit, PyObject *value) {
char *name = NULL, *email = NULL;
long long time;
if (!parse_person(value, &name, &email, &time))
return -1;
git_signature *signature = git_signature_new(name, email, time, 0);
if ( signature == NULL)
return -1;
git_commit_set_author(commit->commit, signature);
return 0;
}
static PyObject *
Commit_get_tree(Commit *commit) {
git_tree *tree;
@ -756,62 +690,20 @@ Commit_get_parents(Commit *commit)
return list;
}
static PyObject *
Commit_add_parent(Commit *self, PyObject *parent)
{
int err;
git_commit *parent_commit;
if (PyString_Check(parent)) {
git_oid oid;
err = py_str_to_git_oid(parent, &oid);
if (err < 0)
return NULL;
err = git_commit_lookup(&parent_commit, self->repo->repo, &oid);
if (err < 0)
return Error_set_py_obj(err, parent);
} else {
if (!PyObject_TypeCheck(parent, &CommitType)) {
PyErr_Format(PyExc_TypeError, "target must be %.200s, not %.200s",
CommitType.tp_name, parent->ob_type->tp_name);
return NULL;
}
parent_commit = ((Commit *) parent)->commit;
}
err = git_commit_add_parent(self->commit, parent_commit);
if (err < 0)
return Error_set(err);
Py_RETURN_NONE;
}
static PyGetSetDef Commit_getseters[] = {
{"message_short", (getter)Commit_get_message_short, NULL, "short message",
NULL},
{"message", (getter)Commit_get_message, (setter)Commit_set_message,
"message", NULL},
{"message", (getter)Commit_get_message, NULL, "message", NULL},
{"commit_time", (getter)Commit_get_commit_time, NULL, "commit time",
NULL},
{"committer", (getter)Commit_get_committer,
(setter)Commit_set_committer, "committer", NULL},
{"author", (getter)Commit_get_author,
(setter)Commit_set_author, "author", NULL},
{"committer", (getter)Commit_get_committer, NULL, "committer", NULL},
{"author", (getter)Commit_get_author, NULL, "author", NULL},
{"tree", (getter)Commit_get_tree, NULL, "tree object", NULL},
{"parents", (getter)Commit_get_parents, NULL, "parents of this commit",
NULL},
{NULL}
};
static PyMethodDef Commit_methods[] = {
{"add_parent", (PyCFunction)Commit_add_parent, METH_O,
"Add a new parent commit to an existing commit."},
{NULL}
};
static PyTypeObject CommitType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
@ -841,7 +733,7 @@ static PyTypeObject CommitType = {
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Commit_methods, /* tp_methods */
0, /* tp_methods */
0, /* tp_members */
Commit_getseters, /* tp_getset */
0, /* tp_base */
@ -865,31 +757,11 @@ TreeEntry_get_attributes(TreeEntry *self) {
return PyInt_FromLong(git_tree_entry_attributes(self->entry));
}
static int
TreeEntry_set_attributes(TreeEntry *self, PyObject *value) {
unsigned int attributes;
attributes = PyInt_AsLong(value);
if (PyErr_Occurred())
return -1;
git_tree_entry_set_attributes(self->entry, attributes);
return 0;
}
static PyObject *
TreeEntry_get_name(TreeEntry *self) {
return PyString_FromString(git_tree_entry_name(self->entry));
}
static int
TreeEntry_set_name(TreeEntry *self, PyObject *value) {
char *name;
name = PyString_AsString(value);
if (!name)
return -1;
git_tree_entry_set_name(self->entry, name);
return 0;
}
static PyObject *
TreeEntry_get_sha(TreeEntry *self) {
char hex[GIT_OID_HEXSZ];
@ -897,26 +769,13 @@ TreeEntry_get_sha(TreeEntry *self) {
return PyString_FromStringAndSize(hex, GIT_OID_HEXSZ);
}
static int
TreeEntry_set_sha(TreeEntry *self, PyObject *value) {
git_oid oid;
int err;
err = py_str_to_git_oid(value, &oid);
if (err < 0)
return -1;
git_tree_entry_set_id(self->entry, &oid);
return 0;
}
static PyObject *
TreeEntry_to_object(TreeEntry *self) {
git_object *obj;
int err;
char hex[GIT_OID_HEXSZ + 1];
err = git_tree_entry_2object(&obj, self->entry);
err = git_tree_entry_2object(&obj, self->tree->repo->repo, self->entry);
if (err < 0) {
git_oid_fmt(hex, git_tree_entry_id(self->entry));
hex[GIT_OID_HEXSZ] = '\0';
@ -926,11 +785,9 @@ TreeEntry_to_object(TreeEntry *self) {
}
static PyGetSetDef TreeEntry_getseters[] = {
{"attributes", (getter)TreeEntry_get_attributes,
(setter)TreeEntry_set_attributes, "attributes", NULL},
{"name", (getter)TreeEntry_get_name, (setter)TreeEntry_set_name, "name",
NULL},
{"sha", (getter)TreeEntry_get_sha, (setter)TreeEntry_set_sha, "sha", NULL},
{"attributes", (getter)TreeEntry_get_attributes, NULL, "attributes", NULL},
{"name", (getter)TreeEntry_get_name, NULL, "name", NULL},
{"sha", (getter)TreeEntry_get_sha, NULL, "sha", NULL},
{NULL}
};
@ -982,11 +839,6 @@ static PyTypeObject TreeEntryType = {
0, /* tp_new */
};
static int
Tree_init(Tree *py_tree, PyObject *args, PyObject *kwds) {
return Object_init_with_type((Object*)py_tree, GIT_OBJ_TREE, args, kwds);
}
static Py_ssize_t
Tree_len(Tree *self) {
return (Py_ssize_t)git_tree_entrycount(self->tree);
@ -1083,80 +935,6 @@ Tree_getitem(Tree *self, PyObject *value) {
}
}
static int
Tree_delitem_by_name(Tree *self, PyObject *name) {
int err;
err = git_tree_remove_entry_byname(self->tree, PyString_AS_STRING(name));
if (err < 0) {
PyErr_SetObject(PyExc_KeyError, name);
return -1;
}
return 0;
}
static int
Tree_delitem_by_index(Tree *self, PyObject *py_index) {
int index, err;
index = Tree_fix_index(self, py_index);
if (PyErr_Occurred())
return -1;
err = git_tree_remove_entry_byindex(self->tree, index);
if (err < 0) {
PyErr_SetObject(PyExc_IndexError, py_index);
return -1;
}
return 0;
}
static int
Tree_delitem(Tree *self, PyObject *name, PyObject *value) {
/* TODO: This function is only used for deleting items. We may be able to
* come up with some reasonable assignment semantics, but it's tricky
* because git_tree_entry objects are owned by their containing tree. */
if (value) {
PyErr_SetString(PyExc_ValueError,
"Cannot set TreeEntry directly; use add_entry.");
return -1;
}
if (PyString_Check(name)) {
return Tree_delitem_by_name(self, name);
} else if (PyInt_Check(name)) {
return Tree_delitem_by_index(self, name);
} else {
PyErr_Format(PyExc_TypeError,
"Tree entry index must be int or str, not %.200s",
value->ob_type->tp_name);
return -1;
}
}
static TreeEntry *
Tree_add_entry(Tree *self, PyObject *args) {
PyObject *py_sha;
char *name;
int attributes, err;
git_oid oid;
git_tree_entry *entry = NULL;
if (!PyArg_ParseTuple(args, "Osi", &py_sha, &name, &attributes))
return NULL;
err = py_str_to_git_oid(py_sha, &oid);
if (err < 0)
return NULL;
if (git_tree_add_entry(&entry, self->tree, &oid, name, attributes) < 0)
return (TreeEntry*)PyErr_NoMemory();
return wrap_tree_entry(entry, self);
}
static PyMethodDef Tree_methods[] = {
{"add_entry", (PyCFunction)Tree_add_entry, METH_VARARGS,
"Add an entry to a Tree."},
{NULL}
};
static PySequenceMethods Tree_as_sequence = {
0, /* sq_length */
0, /* sq_concat */
@ -1171,7 +949,7 @@ static PySequenceMethods Tree_as_sequence = {
static PyMappingMethods Tree_as_mapping = {
(lenfunc)Tree_len, /* mp_length */
(binaryfunc)Tree_getitem, /* mp_subscript */
(objobjargproc)Tree_delitem, /* mp_ass_subscript */
0, /* mp_ass_subscript */
};
static PyTypeObject TreeType = {
@ -1203,7 +981,7 @@ static PyTypeObject TreeType = {
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Tree_methods, /* tp_methods */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
@ -1211,17 +989,11 @@ static PyTypeObject TreeType = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Tree_init, /* tp_init */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
static int
Blob_init(Blob *py_blob, PyObject *args, PyObject *kwds) {
return Object_init_with_type((Object*)py_blob, GIT_OBJ_BLOB, args, kwds);
}
/* TODO: libgit2 needs some way to set blob data. */
static PyGetSetDef Blob_getseters[] = {
{"data", (getter)Object_read_raw, NULL, "raw data", NULL},
{NULL}
@ -1264,14 +1036,41 @@ static PyTypeObject BlobType = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Blob_init, /* tp_init */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
static int
Tag_init(Tag *py_tag, PyObject *args, PyObject *kwds) {
return Object_init_with_type((Object*)py_tag, GIT_OBJ_TAG, args, kwds);
Repository *repo = NULL;
git_oid oid;
git_tag *tag;
int err;
if (kwds) {
PyErr_Format(PyExc_TypeError, "%s takes no keyword arugments",
py_tag->ob_type->tp_name);
return -1;
}
/* TODO Finish this */
if (!PyArg_ParseTuple(args, "O!", &RepositoryType, &repo))
return -1;
err = git_tag_create(&oid, repo->repo,
tag_name, target, target_type, tagger, message);
if (err < 0)
return -1;
err = git_tag_lookup(&tag, repo->repo, &oid);
if (err < 0)
return -1;
Py_INCREF(repo);
py_tag->repo = repo;
py_tag->tag = tag;
return 0;
}
static void
@ -1302,28 +1101,6 @@ Tag_get_target(Tag *self) {
return self->target;
}
static int
Tag_set_target(Tag *self, Object *target) {
int err;
if (!PyObject_TypeCheck(target, &ObjectType)) {
PyErr_Format(PyExc_TypeError, "target must be %.200s, not %.200s",
ObjectType.tp_name, target->ob_type->tp_name);
return -1;
}
Py_XDECREF(self->target);
self->target = (PyObject*)target;
Py_INCREF(target);
err = git_tag_set_target(self->tag, target->obj);
if (err < 0) {
Error_set(err);
return -1;
}
return 0;
}
static PyObject *
Tag_get_name(Tag *self) {
const char *name;
@ -1333,21 +1110,6 @@ Tag_get_name(Tag *self) {
return PyString_FromString(name);
}
static int
Tag_set_name(Tag *self, PyObject *py_name) {
char *name;
if (!PyString_Check(py_name)) {
PyErr_Format(PyExc_TypeError, "name must be str, not %.200s",
py_name->ob_type->tp_name);
return -1;
}
name = PyString_AsString(py_name);
if (!name)
return -1;
git_tag_set_name(self->tag, name);
return 0;
}
static PyObject *
Tag_get_tagger(Tag *tag) {
const git_signature *tagger = git_tag_tagger(tag->tag);
@ -1358,21 +1120,6 @@ Tag_get_tagger(Tag *tag) {
tagger->when.time);
}
static int
Tag_set_tagger(Tag *tag, PyObject *value) {
char *name = NULL, *email = NULL;
long long time;
if (!parse_person(value, &name, &email, &time))
return -1;
git_signature *signature = git_signature_new(name, email, time, 0);
if ( signature == NULL)
return -1;
git_tag_set_tagger(tag->tag, signature);
return 0;
}
static PyObject *
Tag_get_message(Tag *self) {
const char *message;
@ -1382,23 +1129,11 @@ Tag_get_message(Tag *self) {
return PyString_FromString(message);
}
static int
Tag_set_message(Tag *self, PyObject *message) {
if (!PyString_Check(message)) {
PyErr_Format(PyExc_TypeError, "message must be str, not %.200s",
message->ob_type->tp_name);
return -1;
}
git_tag_set_message(self->tag, PyString_AS_STRING(message));
return 0;
}
static PyGetSetDef Tag_getseters[] = {
{"target", (getter)Tag_get_target, (setter)Tag_set_target, "tagged object",
NULL},
{"name", (getter)Tag_get_name, (setter)Tag_set_name, "tag name", NULL},
{"tagger", (getter)Tag_get_tagger, (setter)Tag_set_tagger, "tagger", NULL},
{"message", (getter)Tag_get_message, (setter)Tag_set_message, "tag message",
{"target", (getter)Tag_get_target, NULL, "tagged object", NULL},
{"name", (getter)Tag_get_name, NULL, "tag name", NULL},
{"tagger", (getter)Tag_get_tagger, NULL, "tagger", NULL},
{"message", (getter)Tag_get_message, NULL, "tag message",
NULL},
{NULL}
};
@ -1829,15 +1564,12 @@ Walker_push(Walker *self, PyObject *py_hex) {
static PyObject *
Walker_sort(Walker *self, PyObject *py_sort_mode) {
int sort_mode;
int err;
sort_mode = (int)PyInt_AsLong(py_sort_mode);
if (sort_mode == -1 && PyErr_Occurred())
return NULL;
err = git_revwalk_sorting(self->walk, sort_mode);
if (err < 0)
return Error_set_py_obj(err, py_sort_mode);
git_revwalk_sorting(self->walk, sort_mode);
Py_RETURN_NONE;
}