Permalink
Browse files

Implement the References (part II)

  • Loading branch information...
David Versmisse
David Versmisse committed Apr 27, 2011
1 parent aac4cf1 commit 858adab759a8852ef4db819c3f5e6fd3b170edb2
Showing with 208 additions and 28 deletions.
  1. +141 −22 pygit2.c
  2. +67 −6 test/test_refs.py
View
163 pygit2.c
@@ -500,26 +500,29 @@ Repository_create_tag(Repository *self, PyObject *args) {
}
static PyObject *
-Repository_listall_references(Repository *self, PyObject *args)
-{
+Repository_listall_references(Repository *self, PyObject *args) {
+ unsigned list_flags=GIT_REF_LISTALL;
git_strarray c_result;
PyObject *py_result, *py_string;
unsigned index;
int err;
- /* 1- Get the C result */
- /* TODO We can choose an other option (instead of GIT_REF_LISTALL) */
- err = git_reference_listall (&c_result, self->repo, GIT_REF_LISTALL);
+ /* 1- Get list_flags */
+ if (!PyArg_ParseTuple(args, "|I", &list_flags))
+ return NULL;
+
+ /* 2- Get the C result */
+ err = git_reference_listall(&c_result, self->repo, list_flags);
if (err < 0)
return Error_set(err);
- /* 2- Create a new PyTuple */
+ /* 3- Create a new PyTuple */
if ( (py_result = PyTuple_New(c_result.count)) == NULL) {
git_strarray_free(&c_result);
return NULL;
}
- /* 3- Fill it */
+ /* 4- Fill it */
for (index=0; index < c_result.count; index++) {
if ((py_string = PyString_FromString( (c_result.strings)[index] ))
== NULL) {
@@ -530,16 +533,15 @@ Repository_listall_references(Repository *self, PyObject *args)
PyTuple_SET_ITEM(py_result, index, py_string);
}
- /* 4- Destroy the c_result */
+ /* 5- Destroy the c_result */
git_strarray_free(&c_result);
- /* 5- And return the py_result */
+ /* 6- And return the py_result */
return py_result;
}
static PyObject *
-Repository_lookup_reference(Repository *self, PyObject *py_name)
-{
+Repository_lookup_reference(Repository *self, PyObject *py_name) {
git_reference *c_reference;
char *c_name;
int err;
@@ -559,8 +561,7 @@ Repository_lookup_reference(Repository *self, PyObject *py_name)
}
static PyObject *
-Repository_create_reference(Repository *self, PyObject *args)
-{
+Repository_create_reference(Repository *self, PyObject *args) {
git_reference *c_reference;
char *c_name;
git_oid oid;
@@ -580,6 +581,39 @@ Repository_create_reference(Repository *self, PyObject *args)
return wrap_reference(c_reference);
}
+static PyObject *
+Repository_create_symbolic_reference(Repository *self, PyObject *args) {
+ git_reference *c_reference;
+ char *c_name, *c_target;
+ int err;
+
+ /* 1- Get the C variables */
+ if (!PyArg_ParseTuple(args, "ss", &c_name, &c_target))
+ return NULL;
+
+ /* 2- Create the reference */
+ err = git_reference_create_symbolic(&c_reference, self->repo, c_name,
+ c_target);
+ if (err < 0)
+ return Error_set(err);
+
+ /* 3- Make an instance of Reference and return it */
+ return wrap_reference(c_reference);
+}
+
+static PyObject *
+Repository_packall_references(Repository *self, PyObject *args) {
+ int err;
+
+ /* 1- Pack */
+ err = git_reference_packall(self->repo);
+ if (err < 0)
+ return Error_set(err);
+
+ /* 2- Return None */
+ Py_RETURN_NONE;
+}
+
static PyMethodDef Repository_methods[] = {
{"create_commit", (PyCFunction)Repository_create_commit, METH_VARARGS,
"Create a new commit object, return its SHA."},
@@ -590,14 +624,20 @@ static PyMethodDef Repository_methods[] = {
{"read", (PyCFunction)Repository_read, METH_O,
"Read raw object data from the repository."},
{"listall_references", (PyCFunction)Repository_listall_references,
- METH_NOARGS,
+ METH_VARARGS,
"Return a list with all the references that can be found in a "
"repository."},
{"lookup_reference", (PyCFunction)Repository_lookup_reference, METH_O,
"Lookup a reference by its name in a repository."},
{"create_reference", (PyCFunction)Repository_create_reference, METH_VARARGS,
"Create a new reference \"name\" that points to the object given by its "
"\"sha\"."},
+ {"create_symbolic_reference",
+ (PyCFunction)Repository_create_symbolic_reference, METH_VARARGS,
+ "Create a new symbolic reference \"name\" that points to the reference "
+ "\"target\"."},
+ {"packall_references", (PyCFunction)Repository_packall_references,
+ METH_NOARGS, "Pack all the loose references in the repository."},
{NULL}
};
@@ -1817,8 +1857,42 @@ static PyTypeObject WalkerType = {
};
static PyObject *
-Reference_resolve(Reference *self, PyObject *args)
-{
+Reference_delete(Reference *self, PyObject *args) {
+ int err;
+
+ /* 1- Delete the reference */
+ err = git_reference_delete(self->reference);
+ if (err < 0)
+ return Error_set(err);
+
+ /* 2- Invalidate the pointer */
+ self->reference = NULL;
+
+ /* 3- Return None */
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+Reference_rename(Reference *self, PyObject *py_name) {
+ char *c_name;
+ int err;
+
+ /* 1- Get the C name */
+ c_name = PyString_AsString(py_name);
+ if (c_name == NULL)
+ return NULL;
+
+ /* 2- Rename */
+ err = git_reference_rename(self->reference, c_name);
+ if (err < 0)
+ return Error_set(err);
+
+ /* 3- Return None */
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+Reference_resolve(Reference *self, PyObject *args) {
git_reference *c_reference;
int err;
@@ -1832,8 +1906,7 @@ Reference_resolve(Reference *self, PyObject *args)
}
static PyObject *
-Reference_get_target(Reference *self, PyObject *args)
-{
+Reference_get_target(Reference *self) {
const char * c_name;
/* 1- Get the target */
@@ -1847,6 +1920,27 @@ Reference_get_target(Reference *self, PyObject *args)
return PyString_FromString(c_name);
}
+static int
+Reference_set_target(Reference *self, PyObject *py_name) {
+ char *c_name;
+ int err;
+
+ /* 1- Get the C name */
+ c_name = PyString_AsString(py_name);
+ if (c_name == NULL)
+ return -1;
+
+ /* 2- Set the new target */
+ err = git_reference_set_target(self->reference, c_name);
+ if (err < 0) {
+ Error_set(err);
+ return -1;
+ }
+
+ /* 3- All OK */
+ return 0;
+}
+
static PyObject *
Reference_get_name(Reference *self) {
const char *c_name;
@@ -1874,6 +1968,26 @@ Reference_get_sha(Reference *self) {
return PyString_FromStringAndSize(hex, GIT_OID_HEXSZ);
}
+static int
+Reference_set_sha(Reference *self, PyObject *py_sha) {
+ git_oid oid;
+ int err;
+
+ /* 1- Get the oid from the py_sha */
+ if (!py_str_to_git_oid(py_sha, &oid))
+ return -1;
+
+ /* 2- Set the oid */
+ err = git_reference_set_oid (self->reference, &oid);
+ if (err < 0) {
+ Error_set(err);
+ return -1;
+ }
+
+ /* 3- All OK */
+ return 0;
+}
+
static PyObject *
Reference_get_type(Reference *self) {
git_rtype c_type;
@@ -1883,17 +1997,22 @@ Reference_get_type(Reference *self) {
}
static 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."},
{"resolve", (PyCFunction)Reference_resolve, METH_NOARGS,
- "Resolve a symbolic reference and return a direct reference"},
- {"get_target", (PyCFunction)Reference_get_target, METH_NOARGS,
- "Get full name to the reference pointed by this symbolic reference."},
+ "Resolve a symbolic reference and return a direct reference."},
{NULL}
};
static PyGetSetDef Reference_getseters[] = {
{"name", (getter)Reference_get_name, NULL,
"The full name of a reference.", NULL},
- {"sha", (getter)Reference_get_sha, NULL, "hex SHA", NULL},
+ {"sha", (getter)Reference_get_sha, (setter)Reference_set_sha, "hex SHA",
+ 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}
View
@@ -33,7 +33,7 @@
import unittest
import utils
-from pygit2 import GIT_REF_OID
+from pygit2 import GIT_REF_OID, GIT_REF_SYMBOLIC
@@ -44,9 +44,23 @@
class ReferencesTest(utils.RepoTestCase):
def test_list_all_references(self):
- self.assertEqual(self.repo.listall_references(),
+ repo = self.repo
+
+ # Without argument
+ self.assertEqual(repo.listall_references(),
('refs/heads/i18n', 'refs/heads/master'))
+ # We add a symbolic reference
+ reference = repo.create_symbolic_reference('refs/tags/version1',
+ 'refs/heads/master')
+ self.assertEqual(repo.listall_references(),
+ ('refs/heads/i18n', 'refs/heads/master',
+ 'refs/tags/version1'))
+
+ # Now we list only the symbolic references
+ self.assertEqual(repo.listall_references(GIT_REF_SYMBOLIC),
+ ('refs/tags/version1', ))
+
def test_lookup_reference(self):
repo = self.repo
@@ -64,19 +78,54 @@ def test_reference_get_sha(self):
self.assertEqual(reference.sha, LAST_COMMIT)
+ def test_reference_set_sha(self):
+ NEW_COMMIT = '5ebeeebb320790caf276b9fc8b24546d63316533'
+ reference = self.repo.lookup_reference('refs/heads/master')
+ reference.sha = NEW_COMMIT
+ self.assertEqual(reference.sha, NEW_COMMIT)
+
+
def test_reference_get_type(self):
reference = self.repo.lookup_reference('refs/heads/master')
self.assertEqual(reference.type, GIT_REF_OID)
def test_get_target(self):
- # XXX We must have a symbolic reference to make this test
- pass
+ reference = self.repo.lookup_reference('HEAD')
+ self.assertEqual(reference.target, 'refs/heads/master')
+
+
+ def test_set_target(self):
+ reference = self.repo.lookup_reference('HEAD')
+ self.assertEqual(reference.target, 'refs/heads/master')
+ reference.target = 'refs/heads/i18n'
+ self.assertEqual(reference.target, 'refs/heads/i18n')
+
+
+ def test_delete(self):
+ repo = self.repo
+
+ # We add a tag as a new reference that points to "origin/master"
+ reference = repo.create_reference('refs/tags/version1', LAST_COMMIT)
+ self.assertTrue('refs/tags/version1' in repo.listall_references())
+
+ # And we delete it
+ reference.delete()
+ self.assertFalse('refs/tags/version1' in repo.listall_references())
+
+
+ def test_rename(self):
+ # We add a tag as a new reference that points to "origin/master"
+ reference = self.repo.create_reference('refs/tags/version1',
+ LAST_COMMIT)
+ self.assertEqual(reference.name, 'refs/tags/version1')
+ reference.rename('refs/tags/version2')
+ self.assertEqual(reference.name, 'refs/tags/version2')
def test_reference_resolve(self):
- # XXX We must have a symbolic reference to make a better test
- reference = self.repo.lookup_reference('refs/heads/master')
+ reference = self.repo.lookup_reference('HEAD')
+ self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
reference = reference.resolve()
self.assertEqual(reference.type, GIT_REF_OID)
self.assertEqual(reference.sha, LAST_COMMIT)
@@ -92,6 +141,18 @@ def test_create_reference(self):
self.assertEqual(reference.sha, LAST_COMMIT)
+ def test_create_symbolic_reference(self):
+ # We add a tag as a new symbolic reference that always points to
+ # "refs/heads/master"
+ reference = self.repo.create_symbolic_reference('refs/tags/beta',
+ 'refs/heads/master')
+ self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
+ self.assertEqual(reference.target, 'refs/heads/master')
+
+
+ def test_packall_references(self):
+ self.repo.packall_references()
+
if __name__ == '__main__':
unittest.main()

0 comments on commit 858adab

Please sign in to comment.