diff --git a/pygit2/__init__.py b/pygit2/__init__.py index b1549ce..09aa858 100644 --- a/pygit2/__init__.py +++ b/pygit2/__init__.py @@ -26,5 +26,19 @@ # Boston, MA 02110-1301, USA. from .version import __version__ + +# Low level API +import _pygit2 from _pygit2 import * + +# High level API +from repository import Repository import pygit2.utils + + +def init_repository(path, bare=False): + """ + Creates a new Git repository in the given path. + """ + _pygit2.init_repository(path, bare) + return Repository(path) diff --git a/pygit2/repository.py b/pygit2/repository.py new file mode 100644 index 0000000..4de0214 --- /dev/null +++ b/pygit2/repository.py @@ -0,0 +1,60 @@ +# -*- 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. + +# Import from pygit2 +from _pygit2 import Repository as _Repository + + +class Repository(_Repository): + + def create_reference(self, name, target, force=False, symbolic=False): + """ + Create a new reference "name" which points to a object or another + reference. + + Keyword arguments: + + force + If True references will be overridden, otherwise (the default) an + exception is raised. + + symbolic + If True a symbolic reference will be created, then source has to + be a valid existing reference name; if False (the default) a + normal reference will be created, then source must has to be a + valid SHA hash. + + Examples:: + + repo.create_reference('refs/heads/foo', repo.head.hex) + repo.create_reference('refs/tags/foo', 'refs/heads/master', + symbolic=True) + """ + if symbolic: + return self.create_symbolic_reference(name, target, force) + + return self.create_direct_reference(name, target, force) diff --git a/src/pygit2.c b/src/pygit2.c index af09d7b..5bfd89b 100644 --- a/src/pygit2.c +++ b/src/pygit2.c @@ -62,36 +62,26 @@ extern PyTypeObject RemoteType; PyDoc_STRVAR(init_repository__doc__, - "init_repository(path, bare=False) -> Repository\n" + "init_repository(path, bare)\n" "\n" "Creates a new Git repository in the given path."); PyObject * init_repository(PyObject *self, PyObject *args, PyObject *kw) { git_repository *repo; - Repository *py_repo; const char *path; - unsigned int bare = 0; + unsigned int bare; int err; - static char * kwlist[] = {"path", "bare", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|I", kwlist, &path, &bare)) + if (!PyArg_ParseTuple(args, "sI", &path, &bare)) return NULL; err = git_repository_init(&repo, path, bare); if (err < 0) return Error_set_str(err, path); - py_repo = PyObject_GC_New(Repository, &RepositoryType); - if (py_repo) { - py_repo->repo = repo; - py_repo->index = NULL; - PyObject_GC_Track(py_repo); - return (PyObject*)py_repo; - } - git_repository_free(repo); - return NULL; + Py_RETURN_NONE; }; diff --git a/src/repository.c b/src/repository.c index a7079de..1016948 100644 --- a/src/repository.c +++ b/src/repository.c @@ -818,64 +818,83 @@ Repository_lookup_reference(Repository *self, PyObject *py_name) return wrap_reference(c_reference); } -PyDoc_STRVAR(Repository_create_reference__doc__, - "create_reference(name, source, force=False, symbolic=False) -> Reference\n" +PyDoc_STRVAR(Repository_create_direct_reference__doc__, + "create_reference(name, target, force) -> Reference\n" "\n" - "Create a new reference \"name\" which points to a object or another\n" - "reference.\n" + "Create a new reference \"name\" which points to an object.\n" "\n" - "Keyword arguments:\n" + "Arguments:\n" "\n" "force\n" " If True references will be overridden, otherwise (the default) an\n" " exception is raised.\n" "\n" - "symbolic\n" - " If True a symbolic reference will be created, then source has to be a\n" - " valid existing reference name; if False (the default) a normal\n" - " reference will be created, then source must has to be a valid SHA\n" - " hash.\n" - "\n" "Examples::\n" "\n" - " repo.create_reference('refs/heads/foo', repo.head.hex)\n" - " repo.create_reference('refs/tags/foo', 'refs/heads/master', symbolic=True)"); + " repo.create_direct_reference('refs/heads/foo', repo.head.hex, False)"); PyObject * -Repository_create_reference(Repository *self, PyObject *args, PyObject *kw) +Repository_create_direct_reference(Repository *self, PyObject *args, + PyObject *kw) { PyObject *py_obj; git_reference *c_reference; char *c_name, *c_target; git_oid oid; - int err = 0, symbolic = 0, force = 0; + int err, force; - static char *kwlist[] = {"name", "source", "force", "symbolic", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ii", kwlist, - &c_name, &py_obj, &force, &symbolic)) + if (!PyArg_ParseTuple(args, "sOi", &c_name, &py_obj, &force)) return NULL; - if (!symbolic) { - err = py_str_to_git_oid_expand(self->repo, py_obj, &oid); - if (err < 0) - return Error_set(err); + err = py_str_to_git_oid_expand(self->repo, py_obj, &oid); + if (err < 0) + return Error_set(err); - err = git_reference_create(&c_reference, self->repo, c_name, &oid, - force); - } else { - #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(&c_reference, self->repo, c_name, &oid, force); + if (err < 0) + return Error_set(err); - err = git_reference_symbolic_create(&c_reference, self->repo, c_name, - c_target, force); - } + return wrap_reference(c_reference); +} +PyDoc_STRVAR(Repository_create_symbolic_reference__doc__, + "create_symbolic_reference(name, source, force) -> Reference\n" + "\n" + "Create a new reference \"name\" which points to another reference.\n" + "\n" + "Arguments:\n" + "\n" + "force\n" + " If True references will be overridden, otherwise (the default) an\n" + " exception is raised.\n" + "\n" + "Examples::\n" + "\n" + " repo.create_reference('refs/tags/foo', 'refs/heads/master', False)"); + +PyObject * +Repository_create_symbolic_reference(Repository *self, PyObject *args, + PyObject *kw) +{ + PyObject *py_obj; + git_reference *c_reference; + char *c_name, *c_target; + git_oid oid; + int err, force; + + if (!PyArg_ParseTuple(args, "sOi", &c_name, &py_obj, &force)) + return NULL; + + #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_symbolic_create(&c_reference, self->repo, c_name, + c_target, force); if (err < 0) return Error_set(err); @@ -1122,7 +1141,8 @@ PyMethodDef Repository_methods[] = { METHOD(Repository, walk, METH_VARARGS), METHOD(Repository, read, METH_O), METHOD(Repository, write, METH_VARARGS), - METHOD(Repository, create_reference, METH_VARARGS|METH_KEYWORDS), + METHOD(Repository, create_direct_reference, METH_VARARGS), + METHOD(Repository, create_symbolic_reference, METH_VARARGS), METHOD(Repository, listall_references, METH_VARARGS), METHOD(Repository, lookup_reference, METH_O), METHOD(Repository, packall_references, METH_NOARGS),