diff --git a/src/oid.c b/src/oid.c index d1db630..40a5d79 100644 --- a/src/oid.c +++ b/src/oid.c @@ -46,7 +46,7 @@ git_oid_to_python(const git_oid *oid) } size_t -py_hex_to_git_oid (PyObject *py_oid, git_oid *oid) +py_hex_to_git_oid(PyObject *py_oid, git_oid *oid) { PyObject *py_hex; int err; diff --git a/src/reference.c b/src/reference.c index 4d11cb5..e9abc6c 100644 --- a/src/reference.c +++ b/src/reference.c @@ -40,6 +40,7 @@ extern PyObject *GitError; extern PyTypeObject RefLogEntryType; +extern PyTypeObject SignatureType; void RefLogIter_dealloc(RefLogIter *self) @@ -312,6 +313,72 @@ Reference_log(Reference *self) return (PyObject*)iter; } +PyDoc_STRVAR(Reference_log_append__doc__, + "log_append(committer, message, oid)\n" + "\n" + "Append reflog to the current reference."); + +PyObject * +Reference_log_append(Reference *self, PyObject *args, PyObject *kwds) +{ + git_signature *committer; + const char *message = NULL; + git_reflog *reflog; + git_oid oid; + git_oid *ref_oid; + int err; + Signature *py_committer; + PyObject *py_message = NULL; + PyObject *py_hex = NULL; + char *keywords[] = {"committer", "message", "oid", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|OO", keywords, + &SignatureType, &py_committer, + &py_message, + &py_hex)) + return NULL; + + /* FIXME: encoding */ + if (py_message != NULL) { + message = py_str_to_c_str(py_message, NULL); + if (message == NULL) + return NULL; + } + + if (py_hex != NULL) { + err = py_oid_to_git_oid_expand(self->repo->repo, py_hex, &oid); + if (err < 0) + return NULL; + } + + CHECK_REFERENCE(self); + + err = git_reflog_read(&reflog, self->reference); + if (err < 0) { + free((void *)message); + return NULL; + } + + if (py_hex != NULL) + ref_oid = &oid; + else + ref_oid = git_reference_target(self->reference); + + committer = (git_signature *)py_committer->signature; + if (!(err = git_reflog_append(reflog, + ref_oid, + committer, + message))) + err = git_reflog_write(reflog); + + git_reflog_free(reflog); + free((void *)message); + + if (err < 0) + return NULL; + + Py_RETURN_NONE; +} PyDoc_STRVAR(Reference_get_object__doc__, "get_object() -> object\n" @@ -426,6 +493,7 @@ PyMethodDef Reference_methods[] = { METHOD(Reference, rename, METH_O), METHOD(Reference, resolve, METH_NOARGS), METHOD(Reference, log, METH_NOARGS), + METHOD(Reference, log_append, METH_VARARGS|METH_KEYWORDS), METHOD(Reference, get_object, METH_NOARGS), {NULL} }; diff --git a/test/test_reflog.py b/test/test_reflog.py new file mode 100644 index 0000000..af68f5b --- /dev/null +++ b/test/test_reflog.py @@ -0,0 +1,44 @@ +# -*- coding: UTF-8 -*- +# +# Copyright 2010-2013 The pygit2 contributors +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, +# as published by the Free Software Foundation. +# +# In addition to the permissions in the GNU General Public License, +# the authors give you unlimited permission to link the compiled +# version of this file into combinations with other programs, +# and to distribute those combinations without any restriction +# coming from the use of this file. (The General Public License +# restrictions do apply in other respects; for example, they cover +# modification of the file, and distribution when not linked into +# a combined executable.) +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +"""Tests for reference log.""" + +from __future__ import absolute_import +from __future__ import unicode_literals + +from pygit2 import Signature +from . import utils + + +class ReflogTest(utils.RepoTestCase): + + def test_log_append(self): + repo = self.repo + master = repo.lookup_reference("refs/heads/master") + signature = Signature('xtao', 'xutao@douban.com') + master.log_append(signature, 'reflog') + self.assertTrue('reflog' in [entry.message for entry in master.log()])