Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Usage guide:
merge
config
remotes
submodule
blame
settings
features
Expand Down
17 changes: 17 additions & 0 deletions docs/submodule.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
**********************************************************************
The submodule
**********************************************************************

A submodule is a foreign repository that is embedded within a
dedicated subdirectory of the repositories tree.

.. automethod:: pygit2.Repository.lookup_submodule
.. automethod:: pygit2.Repository.listall_submodules

The Submodule type
====================

.. autoattribute:: pygit2.Submodule.name
.. autoattribute:: pygit2.Submodule.path
.. autoattribute:: pygit2.Submodule.url
.. automethod:: pygit2.Submodule.open
7 changes: 7 additions & 0 deletions src/pygit2.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ extern PyTypeObject RepositoryType;
extern PyTypeObject OidType;
extern PyTypeObject ObjectType;
extern PyTypeObject CommitType;
extern PyTypeObject SubmoduleType;
extern PyTypeObject DiffType;
extern PyTypeObject DiffIterType;
extern PyTypeObject DiffDeltaType;
Expand Down Expand Up @@ -219,6 +220,12 @@ moduleinit(PyObject* m)
ADD_CONSTANT_INT(m, GIT_FILEMODE_LINK)
ADD_CONSTANT_INT(m, GIT_FILEMODE_COMMIT)

/*
* Submodules
*/
INIT_TYPE(SubmoduleType, NULL, NULL);
ADD_TYPE(m, Submodule);

/*
* Log
*/
Expand Down
77 changes: 77 additions & 0 deletions src/repository.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "repository.h"
#include "branch.h"
#include "signature.h"
#include "submodule.h"
#include <git2/odb_backend.h>

extern PyObject *GitError;
Expand Down Expand Up @@ -70,6 +71,21 @@ int_to_loose_object_type(int type_id)
}
}

PyObject *
wrap_repository(git_repository *c_repo)
{
Repository *py_repo = PyObject_GC_New(Repository, &RepositoryType);

if (py_repo) {
py_repo->repo = c_repo;
py_repo->config = NULL;
py_repo->index = NULL;
py_repo->owned = 1;
}

return (PyObject *)py_repo;
}

int
Repository_init(Repository *self, PyObject *args, PyObject *kwds)
{
Expand Down Expand Up @@ -1084,6 +1100,65 @@ Repository_listall_branches(Repository *self, PyObject *args)
return NULL;
}

PyDoc_STRVAR(Repository_lookup_submodule__doc__,
"lookup_submodule(path) -> Submodule\n"
"\n"
"Lookup a submodule by its path in a repository.");

PyObject *
Repository_lookup_submodule(Repository *self, PyObject *py_path)
{
git_submodule *c_submodule;
char *c_name;
int err;

c_name = py_path_to_c_str(py_path);
if (c_name == NULL)
return NULL;

err = git_submodule_lookup(&c_submodule, self->repo, c_name);
if (err < 0) {
PyObject *err_obj = Error_set_str(err, c_name);
free(c_name);
return err_obj;
}
free(c_name);

return wrap_submodule(self, c_submodule);
}

PyDoc_STRVAR(Repository_listall_submodules__doc__,
"listall_submodules() -> [str, ...]\n"
"\n"
"Return a list with all submodule paths in the repository.\n");

static int foreach_path_cb(git_submodule *submodule, const char *name, void *payload)
{
PyObject *list = (PyObject *)payload;
PyObject *path = to_unicode(git_submodule_path(submodule), NULL, NULL);

return PyList_Append(list, path);
}

PyObject *
Repository_listall_submodules(Repository *self, PyObject *args)
{
int err;
PyObject *list;

list = PyList_New(0);
if (list == NULL)
return NULL;

err = git_submodule_foreach(self->repo, foreach_path_cb, list);
if (err != 0) {
Py_DECREF(list);
return Py_None;
}

return list;
}


PyDoc_STRVAR(Repository_lookup_reference__doc__,
"lookup_reference(name) -> Reference\n"
Expand Down Expand Up @@ -1508,6 +1583,8 @@ PyMethodDef Repository_methods[] = {
METHOD(Repository, create_reference_direct, METH_VARARGS),
METHOD(Repository, create_reference_symbolic, METH_VARARGS),
METHOD(Repository, listall_references, METH_NOARGS),
METHOD(Repository, lookup_submodule, METH_O),
METHOD(Repository, listall_submodules, METH_NOARGS),
METHOD(Repository, lookup_reference, METH_O),
METHOD(Repository, revparse_single, METH_O),
METHOD(Repository, status, METH_NOARGS),
Expand Down
2 changes: 2 additions & 0 deletions src/repository.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include <git2.h>
#include "types.h"

PyObject *wrap_repository(git_repository *c_repo);

int Repository_init(Repository *self, PyObject *args, PyObject *kwds);
int Repository_traverse(Repository *self, visitproc visit, void *arg);
int Repository_clear(Repository *self);
Expand Down
189 changes: 189 additions & 0 deletions src/submodule.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/*
* Copyright 2010-2015 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.
*/

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include "error.h"
#include "utils.h"
#include "types.h"
#include "submodule.h"
#include "repository.h"

PyTypeObject SubmoduleType;

PyDoc_STRVAR(Submodule_open__doc__,
"open() -> Repository\n"
"\n"
"Open the submodule as repository.");

PyObject *
Submodule_open(Submodule *self, PyObject *args)
{
int err;
git_repository *repo;

err = git_submodule_open(&repo, self->submodule);
if (err < 0)
return Error_set_str(err, giterr_last()->message);

return wrap_repository(repo);
}

PyDoc_STRVAR(Submodule_name__doc__,
"Gets name of the submodule\n");

PyObject *
Submodule_name__get__(Submodule *self)
{
return to_unicode(git_submodule_name(self->submodule), NULL, NULL);
}

PyDoc_STRVAR(Submodule_path__doc__,
"Gets path of the submodule\n");

PyObject *
Submodule_path__get__(Submodule *self)
{
const char *path = git_submodule_path(self->submodule);
assert(path);
return to_unicode(path, NULL, NULL);
}

PyDoc_STRVAR(Submodule_url__doc__,
"Gets URL of the submodule\n");

PyObject *
Submodule_url__get__(Submodule *self)
{
const char *url = git_submodule_url(self->submodule);
if (url == NULL)
Py_RETURN_NONE;
return to_unicode(url, NULL, NULL);
}

PyDoc_STRVAR(Submodule_branch__doc__,
"Gets branch of the submodule\n");

PyObject *
Submodule_branch__get__(Submodule *self)
{
const char *branch = git_submodule_branch(self->submodule);
if (branch == NULL)
Py_RETURN_NONE;
return to_unicode(branch, NULL, NULL);
}

PyObject *
Submodule_repr(PyObject *self)
{
Submodule *subm = (Submodule *)self;

return PyString_FromFormat("pygit2.Submodule(\"%s\")",
git_submodule_name(subm->submodule));
}

static void
Submodule_dealloc(Submodule *self)
{
Py_CLEAR(self->repo);
git_submodule_free(self->submodule);
PyObject_Del(self);
}

PyMethodDef Submodule_methods[] = {
METHOD(Submodule, open, METH_NOARGS),
{NULL}
};

PyGetSetDef Submodule_getseters[] = {
GETTER(Submodule, name),
GETTER(Submodule, path),
GETTER(Submodule, url),
GETTER(Submodule, branch),
{NULL}
};

PyDoc_STRVAR(Submodule__doc__, "Submodule object.");

PyTypeObject SubmoduleType = {
PyVarObject_HEAD_INIT(NULL, 0)
"_pygit2.Submodule", /* tp_name */
sizeof(Submodule), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)Submodule_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
Submodule_repr, /* 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 */
Submodule__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Submodule_methods, /* tp_methods */
0, /* tp_members */
Submodule_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_submodule(Repository *repo, git_submodule *c_submodule)
{
Submodule *py_submodule = NULL;

py_submodule = PyObject_New(Submodule, &SubmoduleType);
if (py_submodule) {
py_submodule->submodule = c_submodule;
py_submodule->repo = repo;
if (repo) {
Py_INCREF(repo);
}
}

return (PyObject *)py_submodule;
}
38 changes: 38 additions & 0 deletions src/submodule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2015 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.
*/

#ifndef INCLUDE_pygit2_submodule_h
#define INCLUDE_pygit2_submodule_h

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <git2.h>

PyObject *wrap_submodule(Repository* repo, git_submodule *submodule);

#endif

Loading