Merge branch 'master' of https://github.com/libgit2/pygit2 into refactoring
Conflicts: pygit2.c
This commit is contained in:
commit
e7b5560590
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_commit_h
|
#ifndef INCLUDE_pygit2_commit_h
|
||||||
#define INCLUDE_pygit2_commit_h
|
#define INCLUDE_pygit2_commit_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
|
12
include/pygit2/diff.h
Normal file
12
include/pygit2/diff.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef INCLUDE_pygit2_diff_h
|
||||||
|
#define INCLUDE_pygit2_diff_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
|
#include <Python.h>
|
||||||
|
#include <git2.h>
|
||||||
|
#include <pygit2/types.h>
|
||||||
|
|
||||||
|
PyObject* Diff_changes(Diff *self);
|
||||||
|
PyObject* Diff_patch(Diff *self);
|
||||||
|
|
||||||
|
#endif
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_error_h
|
#ifndef INCLUDE_pygit2_error_h
|
||||||
#define INCLUDE_pygit2_error_h
|
#define INCLUDE_pygit2_error_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_index_h
|
#ifndef INCLUDE_pygit2_index_h
|
||||||
#define INCLUDE_pygit2_index_h
|
#define INCLUDE_pygit2_index_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_object_h
|
#ifndef INCLUDE_pygit2_object_h
|
||||||
#define INCLUDE_pygit2_object_h
|
#define INCLUDE_pygit2_object_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_oid_h
|
#ifndef INCLUDE_pygit2_oid_h
|
||||||
#define INCLUDE_pygit2_oid_h
|
#define INCLUDE_pygit2_oid_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_reference_h
|
#ifndef INCLUDE_pygit2_reference_h
|
||||||
#define INCLUDE_pygit2_reference_h
|
#define INCLUDE_pygit2_reference_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_repository_h
|
#ifndef INCLUDE_pygit2_repository_h
|
||||||
#define INCLUDE_pygit2_repository_h
|
#define INCLUDE_pygit2_repository_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_signature_h
|
#ifndef INCLUDE_pygit2_signature_h
|
||||||
#define INCLUDE_pygit2_signature_h
|
#define INCLUDE_pygit2_signature_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_tag_h
|
#ifndef INCLUDE_pygit2_tag_h
|
||||||
#define INCLUDE_pygit2_tag_h
|
#define INCLUDE_pygit2_tag_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_tree_h
|
#ifndef INCLUDE_pygit2_tree_h
|
||||||
#define INCLUDE_pygit2_tree_h
|
#define INCLUDE_pygit2_tree_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
@ -13,6 +14,7 @@ PyObject* TreeEntry_to_object(TreeEntry *self);
|
|||||||
|
|
||||||
TreeEntry* Tree_getitem_by_index(Tree *self, PyObject *py_index);
|
TreeEntry* Tree_getitem_by_index(Tree *self, PyObject *py_index);
|
||||||
TreeEntry* Tree_getitem(Tree *self, PyObject *value);
|
TreeEntry* Tree_getitem(Tree *self, PyObject *value);
|
||||||
|
PyObject* Tree_diff_tree(Tree *self, PyObject *args);
|
||||||
|
|
||||||
PyObject* TreeBuilder_insert(TreeBuilder *self, PyObject *args);
|
PyObject* TreeBuilder_insert(TreeBuilder *self, PyObject *args);
|
||||||
PyObject* TreeBuilder_write(TreeBuilder *self);
|
PyObject* TreeBuilder_write(TreeBuilder *self);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_objects_h
|
#ifndef INCLUDE_pygit2_objects_h
|
||||||
#define INCLUDE_pygit2_objects_h
|
#define INCLUDE_pygit2_objects_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
@ -35,6 +36,24 @@ typedef struct {
|
|||||||
const git_tree_entry *entry;
|
const git_tree_entry *entry;
|
||||||
} TreeEntry;
|
} TreeEntry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
Tree *t0;
|
||||||
|
Tree *t1;
|
||||||
|
} Diff;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
int old_start;
|
||||||
|
int old_lines;
|
||||||
|
char* old_file;
|
||||||
|
int new_start;
|
||||||
|
int new_lines;
|
||||||
|
char* new_file;
|
||||||
|
PyObject *old_data;
|
||||||
|
PyObject *new_data;
|
||||||
|
} Hunk;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
Tree *owner;
|
Tree *owner;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_utils_h
|
#ifndef INCLUDE_pygit2_utils_h
|
||||||
#define INCLUDE_pygit2_utils_h
|
#define INCLUDE_pygit2_utils_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDE_pygit2_walker_h
|
#ifndef INCLUDE_pygit2_walker_h
|
||||||
#define INCLUDE_pygit2_walker_h
|
#define INCLUDE_pygit2_walker_h
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -40,6 +40,8 @@ extern PyObject *GitError;
|
|||||||
PyTypeObject RepositoryType;
|
PyTypeObject RepositoryType;
|
||||||
PyTypeObject ObjectType;
|
PyTypeObject ObjectType;
|
||||||
PyTypeObject CommitType;
|
PyTypeObject CommitType;
|
||||||
|
PyTypeObject DiffType;
|
||||||
|
PyTypeObject HunkType;
|
||||||
PyTypeObject TreeType;
|
PyTypeObject TreeType;
|
||||||
PyTypeObject TreeBuilderType;
|
PyTypeObject TreeBuilderType;
|
||||||
PyTypeObject TreeEntryType;
|
PyTypeObject TreeEntryType;
|
||||||
@ -129,6 +131,12 @@ moduleinit(PyObject* m)
|
|||||||
CommitType.tp_base = &ObjectType;
|
CommitType.tp_base = &ObjectType;
|
||||||
if (PyType_Ready(&CommitType) < 0)
|
if (PyType_Ready(&CommitType) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
DiffType.tp_base = &ObjectType;
|
||||||
|
if (PyType_Ready(&DiffType) < 0)
|
||||||
|
return NULL;
|
||||||
|
HunkType.tp_base = &ObjectType;
|
||||||
|
if (PyType_Ready(&HunkType) < 0)
|
||||||
|
return NULL;
|
||||||
TreeType.tp_base = &ObjectType;
|
TreeType.tp_base = &ObjectType;
|
||||||
if (PyType_Ready(&TreeType) < 0)
|
if (PyType_Ready(&TreeType) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/object.h>
|
#include <pygit2/object.h>
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/utils.h>
|
#include <pygit2/utils.h>
|
||||||
#include <pygit2/signature.h>
|
#include <pygit2/signature.h>
|
||||||
#include <pygit2/commit.h>
|
#include <pygit2/commit.h>
|
||||||
#include <pygit2/oid.h>
|
|
||||||
#include <pygit2/repository.h>
|
|
||||||
|
|
||||||
extern PyTypeObject TreeType;
|
extern PyTypeObject TreeType;
|
||||||
|
|
||||||
|
330
src/pygit2/diff.c
Normal file
330
src/pygit2/diff.c
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
|
#include <Python.h>
|
||||||
|
#include <structmember.h>
|
||||||
|
#include <pygit2/error.h>
|
||||||
|
#include <pygit2/types.h>
|
||||||
|
#include <pygit2/utils.h>
|
||||||
|
#include <pygit2/diff.h>
|
||||||
|
|
||||||
|
extern PyTypeObject DiffType;
|
||||||
|
extern PyTypeObject HunkType;
|
||||||
|
|
||||||
|
static int diff_data_cb(
|
||||||
|
void *cb_data,
|
||||||
|
git_diff_delta *delta,
|
||||||
|
git_diff_range *range,
|
||||||
|
char usage,
|
||||||
|
const char *line,
|
||||||
|
size_t line_len)
|
||||||
|
{
|
||||||
|
PyObject *hunks, *tmp;
|
||||||
|
Hunk *hunk;
|
||||||
|
Py_ssize_t size;
|
||||||
|
|
||||||
|
hunks = PyDict_GetItemString(cb_data, "hunks");
|
||||||
|
if(hunks == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
size = PyList_Size(hunks);
|
||||||
|
hunk = (Hunk*) PyList_GetItem(hunks, size-1);
|
||||||
|
if(hunk == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
tmp = PyBytes_FromStringAndSize(line, line_len);
|
||||||
|
|
||||||
|
if(usage != GIT_DIFF_LINE_DELETION)
|
||||||
|
PyBytes_Concat(&hunk->new_data, tmp);
|
||||||
|
|
||||||
|
if(usage != GIT_DIFF_LINE_ADDITION)
|
||||||
|
PyBytes_Concat(&hunk->old_data, tmp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int diff_hunk_cb(
|
||||||
|
void *cb_data,
|
||||||
|
git_diff_delta *delta,
|
||||||
|
git_diff_range *range,
|
||||||
|
const char *header,
|
||||||
|
size_t header_len)
|
||||||
|
{
|
||||||
|
PyObject *hunks;
|
||||||
|
Hunk *hunk;
|
||||||
|
|
||||||
|
hunks = PyDict_GetItemString(cb_data, "hunks");
|
||||||
|
if(hunks == NULL) {
|
||||||
|
hunks = PyList_New(0);
|
||||||
|
PyDict_SetItemString(cb_data, "hunks", hunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
hunk = (Hunk*) PyType_GenericNew(&HunkType, NULL, NULL);
|
||||||
|
|
||||||
|
hunk->old_start = range->old_start;
|
||||||
|
hunk->old_lines = range->old_lines;
|
||||||
|
hunk->new_start = range->new_start;
|
||||||
|
hunk->new_lines = range->new_lines;
|
||||||
|
|
||||||
|
int len;
|
||||||
|
char* old_path, *new_path;
|
||||||
|
|
||||||
|
len = strlen(delta->old_file.path) + 1;
|
||||||
|
old_path = malloc(sizeof(char) * len);
|
||||||
|
memcpy(old_path, delta->old_file.path, len);
|
||||||
|
hunk->old_file = old_path;
|
||||||
|
|
||||||
|
len = strlen(delta->new_file.path) + 1;
|
||||||
|
new_path = malloc(sizeof(char) * len);
|
||||||
|
memcpy(new_path, delta->new_file.path, len);
|
||||||
|
hunk->new_file = new_path;
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
hunk->old_data = Py_BuildValue("y", "");
|
||||||
|
hunk->new_data = Py_BuildValue("y", "");
|
||||||
|
#else
|
||||||
|
hunk->old_data = Py_BuildValue("s", "");
|
||||||
|
hunk->new_data = Py_BuildValue("s", "");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PyList_Append(hunks, (PyObject*) hunk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int diff_file_cb(void *cb_data, git_diff_delta *delta, float progress)
|
||||||
|
{
|
||||||
|
PyObject *files, *file;
|
||||||
|
|
||||||
|
files = PyDict_GetItemString(cb_data, "files");
|
||||||
|
if(files == NULL) {
|
||||||
|
files = PyList_New(0);
|
||||||
|
PyDict_SetItemString(cb_data, "files", files);
|
||||||
|
}
|
||||||
|
|
||||||
|
file = Py_BuildValue("(s,s,i)",
|
||||||
|
delta->old_file.path,
|
||||||
|
delta->new_file.path,
|
||||||
|
delta->status
|
||||||
|
);
|
||||||
|
|
||||||
|
PyList_Append(files, file);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Diff_changes(Diff *self)
|
||||||
|
{
|
||||||
|
git_diff_options opts = {0};
|
||||||
|
git_diff_list *changes;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = git_diff_tree_to_tree(
|
||||||
|
self->t0->repo->repo,
|
||||||
|
&opts,
|
||||||
|
self->t0->tree,
|
||||||
|
self->t1->tree,
|
||||||
|
&changes);
|
||||||
|
|
||||||
|
if(err < 0) {
|
||||||
|
Error_set(err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *payload;
|
||||||
|
payload = PyDict_New();
|
||||||
|
|
||||||
|
git_diff_foreach(
|
||||||
|
changes,
|
||||||
|
payload,
|
||||||
|
&diff_file_cb,
|
||||||
|
&diff_hunk_cb,
|
||||||
|
&diff_data_cb
|
||||||
|
);
|
||||||
|
git_diff_list_free(changes);
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int diff_print_cb(
|
||||||
|
void *cb_data,
|
||||||
|
git_diff_delta *delta,
|
||||||
|
git_diff_range *range,
|
||||||
|
char usage,
|
||||||
|
const char *line,
|
||||||
|
size_t line_len)
|
||||||
|
{
|
||||||
|
PyObject *data = PyBytes_FromStringAndSize(line, line_len);
|
||||||
|
PyBytes_ConcatAndDel((PyObject**) cb_data, data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Diff_patch(Diff *self)
|
||||||
|
{
|
||||||
|
git_diff_options opts = {0};
|
||||||
|
git_diff_list *changes;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = git_diff_tree_to_tree(
|
||||||
|
self->t0->repo->repo,
|
||||||
|
&opts,
|
||||||
|
self->t0->tree,
|
||||||
|
self->t1->tree,
|
||||||
|
&changes);
|
||||||
|
|
||||||
|
if(err < 0) {
|
||||||
|
Error_set(err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *patch = PyBytes_FromString("");
|
||||||
|
|
||||||
|
git_diff_print_patch(changes, &patch, &diff_print_cb);
|
||||||
|
|
||||||
|
return patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
Hunk_init(Hunk *self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
self->old_start = 0;
|
||||||
|
self->old_lines = 0;
|
||||||
|
|
||||||
|
self->new_start = 0;
|
||||||
|
self->new_lines = 0;
|
||||||
|
|
||||||
|
self->old_data = PyString_FromString("");
|
||||||
|
if (self->old_data == NULL) {
|
||||||
|
Py_DECREF(self);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->new_data = PyString_FromString("");
|
||||||
|
if (self->new_data == NULL) {
|
||||||
|
Py_DECREF(self);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Hunk_dealloc(Hunk *self)
|
||||||
|
{
|
||||||
|
Py_XDECREF(self->old_data);
|
||||||
|
Py_XDECREF(self->new_data);
|
||||||
|
PyObject_Del(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyMemberDef Hunk_members[] = {
|
||||||
|
{"old_start", T_INT, offsetof(Hunk, old_start), 0, "old start"},
|
||||||
|
{"old_lines", T_INT, offsetof(Hunk, old_lines), 0, "old lines"},
|
||||||
|
{"old_file", T_STRING, offsetof(Hunk, old_file), 0, "old file"},
|
||||||
|
{"old_data", T_OBJECT, offsetof(Hunk, old_data), 0, "old data"},
|
||||||
|
{"new_start", T_INT, offsetof(Hunk, new_start), 0, "new start"},
|
||||||
|
{"new_lines", T_INT, offsetof(Hunk, new_lines), 0, "new lines"},
|
||||||
|
{"new_file", T_STRING, offsetof(Hunk, new_file), 0, "old file"},
|
||||||
|
{"new_data", T_OBJECT, offsetof(Hunk, new_data), 0, "new data"},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
PyTypeObject HunkType = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
"pygit2.Hunk", /* tp_name */
|
||||||
|
sizeof(Hunk), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
(destructor)Hunk_dealloc, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
0, /* 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
|
"Hunk object", /* tp_doc */
|
||||||
|
0, /* tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
0, /* tp_iter */
|
||||||
|
0, /* tp_iternext */
|
||||||
|
0, /* tp_methods */
|
||||||
|
Hunk_members, /* tp_members */
|
||||||
|
0, /* tp_getset */
|
||||||
|
0, /* tp_base */
|
||||||
|
0, /* tp_dict */
|
||||||
|
0, /* tp_descr_get */
|
||||||
|
0, /* tp_descr_set */
|
||||||
|
0, /* tp_dictoffset */
|
||||||
|
(initproc)Hunk_init, /* tp_init */
|
||||||
|
0, /* tp_alloc */
|
||||||
|
0, /* tp_new */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
Diff_dealloc(Diff *self)
|
||||||
|
{
|
||||||
|
Py_XDECREF(self->t0);
|
||||||
|
Py_XDECREF(self->t1);
|
||||||
|
PyObject_Del(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyGetSetDef Diff_getseters[] = {
|
||||||
|
{"changes", (getter)Diff_changes, NULL, "raw changes", NULL},
|
||||||
|
{"patch", (getter)Diff_patch, NULL, "patch", NULL},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
PyTypeObject DiffType = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
"pygit2.Diff", /* tp_name */
|
||||||
|
sizeof(Diff), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
(destructor)Diff_dealloc, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
0, /* 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 | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
|
"Diff objects", /* tp_doc */
|
||||||
|
0, /* tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
0, /* tp_iter */
|
||||||
|
0, /* tp_iternext */
|
||||||
|
0, /* tp_methods */
|
||||||
|
0, /* tp_members */
|
||||||
|
Diff_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 */
|
||||||
|
};
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include <pygit2/utils.h>
|
#include <pygit2/utils.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
// with the following define PY_SSIZE_T_CLEAN
|
|
||||||
// the length of PyArg_ParseTuple will be Py_ssize_t rather than int
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/types.h>
|
#include <pygit2/types.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/utils.h>
|
#include <pygit2/utils.h>
|
||||||
@ -6,6 +7,7 @@
|
|||||||
#include <pygit2/tree.h>
|
#include <pygit2/tree.h>
|
||||||
|
|
||||||
extern PyTypeObject TreeType;
|
extern PyTypeObject TreeType;
|
||||||
|
extern PyTypeObject DiffType;
|
||||||
extern PyTypeObject TreeIterType;
|
extern PyTypeObject TreeIterType;
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -226,6 +228,29 @@ Tree_getitem(Tree *self, PyObject *value)
|
|||||||
return wrap_tree_entry(entry, self);
|
return wrap_tree_entry(entry, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Tree_diff_tree(Tree *self, PyObject *args)
|
||||||
|
{
|
||||||
|
Diff *py_diff;
|
||||||
|
Tree *py_tree;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O!", &TreeType, &py_tree)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
py_diff = PyObject_New(Diff, &DiffType);
|
||||||
|
if (py_diff) {
|
||||||
|
Py_INCREF(py_diff);
|
||||||
|
Py_INCREF(py_tree);
|
||||||
|
Py_INCREF(self);
|
||||||
|
|
||||||
|
py_diff->t0 = self;
|
||||||
|
py_diff->t1 = py_tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (PyObject*) py_diff;
|
||||||
|
}
|
||||||
|
|
||||||
PySequenceMethods Tree_as_sequence = {
|
PySequenceMethods Tree_as_sequence = {
|
||||||
0, /* sq_length */
|
0, /* sq_length */
|
||||||
0, /* sq_concat */
|
0, /* sq_concat */
|
||||||
@ -243,6 +268,12 @@ PyMappingMethods Tree_as_mapping = {
|
|||||||
0, /* mp_ass_subscript */
|
0, /* mp_ass_subscript */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PyMethodDef Tree_methods[] = {
|
||||||
|
{"diff", (PyCFunction)Tree_diff_tree, METH_VARARGS,
|
||||||
|
"Diff two trees."},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
PyTypeObject TreeType = {
|
PyTypeObject TreeType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
"_pygit2.Tree", /* tp_name */
|
"_pygit2.Tree", /* tp_name */
|
||||||
@ -271,7 +302,7 @@ PyTypeObject TreeType = {
|
|||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
(getiterfunc)Tree_iter, /* tp_iter */
|
(getiterfunc)Tree_iter, /* tp_iter */
|
||||||
0, /* tp_iternext */
|
0, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
Tree_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
0, /* tp_getset */
|
||||||
0, /* tp_base */
|
0, /* tp_base */
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/utils.h>
|
#include <pygit2/utils.h>
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pygit2/error.h>
|
#include <pygit2/error.h>
|
||||||
#include <pygit2/utils.h>
|
#include <pygit2/utils.h>
|
||||||
|
@ -36,7 +36,7 @@ import unittest
|
|||||||
|
|
||||||
|
|
||||||
names = ['blob', 'commit', 'index', 'refs', 'repository', 'revwalk', 'tag',
|
names = ['blob', 'commit', 'index', 'refs', 'repository', 'revwalk', 'tag',
|
||||||
'tree', 'signature', 'status', 'treebuilder']
|
'tree', 'signature', 'status', 'treebuilder', 'diff']
|
||||||
def test_suite():
|
def test_suite():
|
||||||
modules = ['test.test_%s' % n for n in names]
|
modules = ['test.test_%s' % n for n in names]
|
||||||
return unittest.defaultTestLoader.loadTestsFromNames(modules)
|
return unittest.defaultTestLoader.loadTestsFromNames(modules)
|
||||||
|
97
test/test_diff.py
Normal file
97
test/test_diff.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2012 Nico von Geyso
|
||||||
|
#
|
||||||
|
# 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 Diff objects."""
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import pygit2
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
__author__ = 'Nico.Geyso@FU-Berlin.de (Nico von Geyso)'
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT_SHA1_1 = '5fe808e8953c12735680c257f56600cb0de44b10'
|
||||||
|
COMMIT_SHA1_2 = 'c2792cfa289ae6321ecf2cd5806c2194b0fd070c'
|
||||||
|
PATCH = b"""diff --git a/a b/a
|
||||||
|
index 7f129fd..af431f2 100644
|
||||||
|
--- a/a
|
||||||
|
+++ b/a
|
||||||
|
@@ -1 +1 @@
|
||||||
|
-a contents 2
|
||||||
|
+a contents
|
||||||
|
diff --git a/c/d b/c/d
|
||||||
|
deleted file mode 100644
|
||||||
|
index 297efb8..0000000
|
||||||
|
--- a/c/d
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1 +0,0 @@
|
||||||
|
-c/d contents
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class DiffTest(utils.BareRepoTestCase):
|
||||||
|
|
||||||
|
def test_diff_invalid(self):
|
||||||
|
commit_a = self.repo[COMMIT_SHA1_1]
|
||||||
|
commit_b = self.repo[COMMIT_SHA1_2]
|
||||||
|
self.assertRaises(TypeError, commit_a.tree.diff, commit_b)
|
||||||
|
|
||||||
|
def test_diff_tree(self):
|
||||||
|
commit_a = self.repo[COMMIT_SHA1_1]
|
||||||
|
commit_b = self.repo[COMMIT_SHA1_2]
|
||||||
|
|
||||||
|
diff = commit_a.tree.diff(commit_b.tree)
|
||||||
|
|
||||||
|
self.assertIsNotNone(diff)
|
||||||
|
self.assertIn(('a','a', 3), diff.changes['files'])
|
||||||
|
self.assertEqual(2, len(diff.changes['hunks']))
|
||||||
|
|
||||||
|
hunk = diff.changes['hunks'][0]
|
||||||
|
self.assertEqual(hunk.old_start, 1)
|
||||||
|
self.assertEqual(hunk.old_lines, 0)
|
||||||
|
self.assertEqual(hunk.new_start, 1)
|
||||||
|
self.assertEqual(hunk.new_lines, 0)
|
||||||
|
|
||||||
|
self.assertEqual(hunk.old_file, 'a')
|
||||||
|
self.assertEqual(hunk.new_file, 'a')
|
||||||
|
|
||||||
|
self.assertEqual(hunk.old_data, b'a contents 2\n')
|
||||||
|
self.assertEqual(hunk.new_data, b'a contents\n')
|
||||||
|
|
||||||
|
def test_diff_patch(self):
|
||||||
|
commit_a = self.repo[COMMIT_SHA1_1]
|
||||||
|
commit_b = self.repo[COMMIT_SHA1_2]
|
||||||
|
|
||||||
|
diff = commit_a.tree.diff(commit_b.tree)
|
||||||
|
self.assertEqual(diff.patch, PATCH)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user