Files
deb-python-pygit2/src/pygit2/reference.c
Nico von Geyso 6b1a281edc refactoring pygit2.c into several small files
The whole extension was organised in one big 3727 lines monster.
This refactoring is splitting these 3727 lines into several smaller files.
2012-05-25 14:07:44 +02:00

301 lines
8.3 KiB
C

#include <Python.h>
#include <pygit2/error.h>
#include <pygit2/types.h>
#include <pygit2/utils.h>
#include <pygit2/oid.h>
#include <pygit2/reference.h>
extern PyObject *GitError;
void
Reference_dealloc(Reference *self)
{
git_reference_free(self->reference);
PyObject_Del(self);
}
PyObject *
Reference_delete(Reference *self, PyObject *args)
{
int err;
CHECK_REFERENCE(self);
/* Delete the reference */
err = git_reference_delete(self->reference);
if (err < 0)
return Error_set(err);
self->reference = NULL; /* Invalidate the pointer */
Py_RETURN_NONE; /* Return None */
}
PyObject *
Reference_rename(Reference *self, PyObject *py_name)
{
char *c_name;
int err;
CHECK_REFERENCE(self);
/* Get the C name */
c_name = py_path_to_c_str(py_name);
if (c_name == NULL)
return NULL;
/* Rename */
err = git_reference_rename(self->reference, c_name, 0);
free(c_name);
if (err < 0)
return Error_set(err);
Py_RETURN_NONE; /* Return None */
}
PyObject *
Reference_reload(Reference *self)
{
int err;
CHECK_REFERENCE(self);
err = git_reference_reload(self->reference);
if (err < 0) {
self->reference = NULL;
return Error_set(err);
}
Py_RETURN_NONE;
}
PyObject *
Reference_resolve(Reference *self, PyObject *args)
{
git_reference *c_reference;
int err;
CHECK_REFERENCE(self);
/* Direct: reload */
if (git_reference_type(self->reference) == GIT_REF_OID) {
err = git_reference_reload(self->reference);
if (err < 0) {
self->reference = NULL;
return Error_set(err);
}
Py_INCREF(self);
return (PyObject *)self;
}
/* Symbolic: resolve */
err = git_reference_resolve(&c_reference, self->reference);
if (err < 0)
return Error_set(err);
return wrap_reference(c_reference);
}
PyObject *
Reference_get_target(Reference *self)
{
const char * c_name;
CHECK_REFERENCE(self);
/* Get the target */
c_name = git_reference_target(self->reference);
if (c_name == NULL) {
PyErr_SetString(PyExc_ValueError, "no target available");
return NULL;
}
/* Make a PyString and return it */
return to_path(c_name);
}
int
Reference_set_target(Reference *self, PyObject *py_name)
{
char *c_name;
int err;
CHECK_REFERENCE_INT(self);
/* Get the C name */
c_name = py_path_to_c_str(py_name);
if (c_name == NULL)
return -1;
/* Set the new target */
err = git_reference_set_target(self->reference, c_name);
free(c_name);
if (err < 0) {
Error_set(err);
return -1;
}
return 0;
}
PyObject *
Reference_get_name(Reference *self)
{
CHECK_REFERENCE(self);
return to_path(git_reference_name(self->reference));
}
PyObject *
Reference_get_oid(Reference *self)
{
const git_oid *oid;
CHECK_REFERENCE(self);
/* Get the oid (only for "direct" references) */
oid = git_reference_oid(self->reference);
if (oid == NULL) {
PyErr_SetString(PyExc_ValueError,
"oid is only available if the reference is direct "
"(i.e. not symbolic)");
return NULL;
}
/* Convert and return it */
return git_oid_to_python(oid->id);
}
int
Reference_set_oid(Reference *self, PyObject *py_hex)
{
git_oid oid;
int err;
CHECK_REFERENCE_INT(self);
/* Get the oid */
err = py_str_to_git_oid_expand(git_reference_owner(self->reference), py_hex, &oid);
if (err < 0) {
Error_set(err);
return -1;
}
/* Set the oid */
err = git_reference_set_oid(self->reference, &oid);
if (err < 0) {
Error_set(err);
return -1;
}
return 0;
}
PyObject *
Reference_get_hex(Reference *self)
{
const git_oid *oid;
CHECK_REFERENCE(self);
/* Get the oid (only for "direct" references) */
oid = git_reference_oid(self->reference);
if (oid == NULL) {
PyErr_SetString(PyExc_ValueError,
"oid is only available if the reference is direct "
"(i.e. not symbolic)");
return NULL;
}
/* Convert and return it */
return git_oid_to_py_str(oid);
}
PyObject *
Reference_get_type(Reference *self)
{
git_ref_t c_type;
CHECK_REFERENCE(self);
c_type = git_reference_type(self->reference);
return PyInt_FromLong(c_type);
}
PyMethodDef Reference_methods[] = {
{"delete", (PyCFunction)Reference_delete, METH_NOARGS,
"Delete this reference. It will no longer be valid!"},
{"rename", (PyCFunction)Reference_rename, METH_O,
"Rename the reference."},
{"reload", (PyCFunction)Reference_reload, METH_NOARGS,
"Reload the reference from the file-system."},
{"resolve", (PyCFunction)Reference_resolve, METH_NOARGS,
"Resolve a symbolic reference and return a direct reference."},
{NULL}
};
PyGetSetDef Reference_getseters[] = {
{"name", (getter)Reference_get_name, NULL,
"The full name of a reference.", NULL},
{"oid", (getter)Reference_get_oid, (setter)Reference_set_oid, "object id",
NULL},
{"hex", (getter)Reference_get_hex, NULL, "hex oid", NULL},
{"target", (getter)Reference_get_target, (setter)Reference_set_target,
"target", NULL},
{"type", (getter)Reference_get_type, NULL,
"type (GIT_REF_OID, GIT_REF_SYMBOLIC or GIT_REF_PACKED).", NULL},
{NULL}
};
PyTypeObject ReferenceType = {
PyVarObject_HEAD_INIT(NULL, 0)
"pygit2.Reference", /* tp_name */
sizeof(Reference), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)Reference_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"Reference", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Reference_methods, /* tp_methods */
0, /* tp_members */
Reference_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
PyObject *
wrap_reference(git_reference * c_reference)
{
Reference *py_reference=NULL;
py_reference = PyObject_New(Reference, &ReferenceType);
if (py_reference)
py_reference->reference = c_reference;
return (PyObject *)py_reference;
}