Files
deb-python-pygit2/src/pygit2/reference.c
Nico von Geyso ad4edf1b85 added pygit2.utils module
refactored package integration to be able to have pygit2.utils module
2012-05-25 14:23:25 +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;
}