merged create_reference and create_reference_symbolic and added force-Option

To be more pythonic: merged methods create_reference and create_reference_symbolic
and added force-Option. To make a new symbolic reference you have provide symbolic=True
as an additional parameter. If force=True references will although be overridden.
Otherwise an exception is raised if the references exists.

Examples:

  # normal reference
    repo.create_reference('refs/heads/foo', repo.head.hex)

  # override reference with new value
    repo.create_reference('refs/heads/foo', repo.head.hex, force=True)

  # symbolic reference
    repo.create_reference('refs/tags/foo', 'refs/heads/master', symbolic = True)
This commit is contained in:
Nico von Geyso 2012-10-09 11:07:10 +02:00
parent 87572b2c8c
commit 682fb1fd13
3 changed files with 62 additions and 47 deletions
include/pygit2
src/pygit2
test

@ -55,8 +55,7 @@ PyObject* Repository_create_commit(Repository *self, PyObject *args);
PyObject* Repository_create_tag(Repository *self, PyObject *args);
PyObject* Repository_listall_references(Repository *self, PyObject *args);
PyObject* Repository_lookup_reference(Repository *self, PyObject *py_name);
PyObject* Repository_create_reference(Repository *self, PyObject *args);
PyObject* Repository_create_symbolic_reference(Repository *self, PyObject *args);
PyObject* Repository_create_reference(Repository *self, PyObject *args, PyObject* keywds);
PyObject* Repository_packall_references(Repository *self, PyObject *args);
PyObject* Repository_status(Repository *self, PyObject *args);
PyObject* Repository_status_file(Repository *self, PyObject *value);

@ -641,53 +641,60 @@ Repository_lookup_reference(Repository *self, PyObject *py_name)
return wrap_reference(c_reference);
}
PyObject *
Repository_create_reference(Repository *self, PyObject *args)
{
PyObject *py_oid;
git_reference *c_reference;
char *c_name;
git_oid oid;
int err;
/* 1- Get the C variables */
if (!PyArg_ParseTuple(args, "sO", &c_name, &py_oid))
return NULL;
err = py_str_to_git_oid_expand(self->repo, py_oid, &oid);
if (err < 0)
return Error_set(err);
/* 2- Create the reference */
err = git_reference_create_oid(&c_reference, self->repo, c_name, &oid, 0);
if (err < 0)
return Error_set(err);
/* 3- Make an instance of Reference and return it */
return wrap_reference(c_reference);
}
PyDoc_STRVAR(
Repository_create_reference_doc,
"Create a new reference \"name\" which points to a object or another reference\n\n"
"Arguments: (name, source, force=False, symbolic=False)\n\n"
"With force=True references will be overridden. Otherwise an exception is raised"
"You can create either a normal reference or a symbolic one:\n"
" * normal reference: source has to be a valid sha hash\n"
" * symbolic reference: source has to be a valid existing reference name\n\n"
"Examples:\n"
" repo.create_reference('refs/heads/foo', repo.head.hex)\n"
" repo.create_reference('refs/tags/foo', 'refs/heads/master', symbolic = True)\n"
);
PyObject *
Repository_create_symbolic_reference(Repository *self, PyObject *args)
Repository_create_reference(Repository *self, PyObject *args, PyObject* keywds)
{
PyObject *py_obj;
git_reference *c_reference;
char *c_name, *c_target;
int err;
git_oid oid;
int err, symbolic = 0, force = 0;
/* 1- Get the C variables */
if (!PyArg_ParseTuple(args, "ss", &c_name, &c_target))
static char *kwlist[] = {"name", "source", "force", "symbolic", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sO|ii", kwlist,
&c_name, &py_obj, &force, &symbolic))
return NULL;
/* 2- Create the reference */
err = git_reference_create_symbolic(&c_reference, self->repo, c_name,
c_target, 0);
if(symbolic) {
#if PY_MAJOR_VERSION == 2
c_target = PyString_AsString(py_obj);
#else
c_target = PyString_AsString(PyUnicode_AsASCIIString(py_obj));
#endif
if(c_target == NULL)
return NULL;
err = git_reference_create_symbolic(&c_reference, self->repo, c_name,
c_target, force);
} else {
err = py_str_to_git_oid_expand(self->repo, py_obj, &oid);
if (err < 0)
return Error_set(err);
err = git_reference_create_oid(&c_reference, self->repo, c_name, &oid, force);
}
if (err < 0)
return Error_set(err);
/* 3- Make an instance of Reference and return it */
return wrap_reference(c_reference);
}
PyObject *
Repository_packall_references(Repository *self, PyObject *args)
{
@ -827,13 +834,8 @@ PyMethodDef Repository_methods[] = {
METH_VARARGS,
"Create a new blob from file"},
{"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\n"
"\"target\"."},
METH_VARARGS|METH_KEYWORDS,
Repository_create_reference_doc},
{"packall_references", (PyCFunction)Repository_packall_references,
METH_NOARGS, "Pack all the loose references in the repository."},
{"status", (PyCFunction)Repository_status, METH_NOARGS, "Reads the "

@ -49,8 +49,7 @@ class ReferencesTest(utils.RepoTestCase):
['refs/heads/i18n', 'refs/heads/master'])
# We add a symbolic reference
repo.create_symbolic_reference('refs/tags/version1',
'refs/heads/master')
repo.create_reference('refs/tags/version1','refs/heads/master', symbolic=True)
self.assertEqual(sorted(repo.listall_references()),
['refs/heads/i18n', 'refs/heads/master',
'refs/tags/version1'])
@ -145,7 +144,7 @@ class ReferencesTest(utils.RepoTestCase):
def test_reload(self):
name = 'refs/tags/version1'
ref = self.repo.create_symbolic_reference(name, "refs/heads/master")
ref = self.repo.create_reference(name, "refs/heads/master", symbolic=True)
ref2 = self.repo.lookup_reference(name)
ref.delete()
self.assertEqual(ref2.name, name)
@ -176,12 +175,27 @@ class ReferencesTest(utils.RepoTestCase):
reference = self.repo.lookup_reference('refs/tags/version1')
self.assertEqual(reference.hex, LAST_COMMIT)
self.assertRaises(GitError, self.repo.create_reference,
'refs/tags/version1', LAST_COMMIT)
reference = self.repo.create_reference('refs/tags/version1',
LAST_COMMIT, force=True)
self.assertEqual(reference.hex, 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')
reference = self.repo.create_reference('refs/tags/beta',
'refs/heads/master', symbolic=True)
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
self.assertEqual(reference.target, 'refs/heads/master')
self.assertRaises(GitError, self.repo.create_reference,
'refs/tags/beta','refs/heads/master', symbolic=True)
reference = self.repo.create_reference('refs/tags/beta',
'refs/heads/master', force=True, symbolic=True)
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
self.assertEqual(reference.target, 'refs/heads/master')