From ae6cd8a0ca378c3911dc86b949d90402bfdbe1be Mon Sep 17 00:00:00 2001 From: Nico von Geyso Date: Tue, 7 May 2013 14:06:20 +0200 Subject: [PATCH] refactoring Tree.diff() into seperate methods * Tree.diff_to_tree() * Tree.diff_to_workdir() * Tree.diff-to_index() --- src/diff.c | 15 ++++++ src/diff.h | 2 + src/tree.c | 114 +++++++++++++++++++++++++++------------------- test/test_diff.py | 30 ++++++------ 4 files changed, 100 insertions(+), 61 deletions(-) diff --git a/src/diff.c b/src/diff.c index 0994209..fd78f49 100644 --- a/src/diff.c +++ b/src/diff.c @@ -42,6 +42,21 @@ extern PyTypeObject HunkType; PyTypeObject PatchType; +PyObject* +wrap_diff(git_diff_list *diff, Repository *repo) +{ + Diff *py_diff; + + py_diff = PyObject_New(Diff, &DiffType); + if (py_diff) { + Py_INCREF(repo); + py_diff->repo = repo; + py_diff->list = diff; + } + + return (PyObject*) py_diff; +} + PyObject* diff_get_patch_byindex(git_diff_list* list, size_t idx) { diff --git a/src/diff.h b/src/diff.h index b045593..75e6333 100644 --- a/src/diff.h +++ b/src/diff.h @@ -41,4 +41,6 @@ PyObject* Diff_changes(Diff *self); PyObject* Diff_patch(Diff *self); +PyObject* wrap_diff(git_diff_list *diff, Repository *repo); + #endif diff --git a/src/tree.c b/src/tree.c index f6a01cf..13309be 100644 --- a/src/tree.c +++ b/src/tree.c @@ -33,6 +33,7 @@ #include "repository.h" #include "oid.h" #include "tree.h" +#include "diff.h" extern PyTypeObject TreeType; extern PyTypeObject DiffType; @@ -270,70 +271,87 @@ Tree_getitem(Tree *self, PyObject *value) } -PyDoc_STRVAR(Tree_diff__doc__, - "diff([obj, flags]) -> Diff\n" - "\n" - "Get changes between current tree instance with another tree, an index or\n" - "the working dir.\n" - "\n" - "Arguments:\n" - "\n" - "obj\n" - " If not given compare diff against working dir. Possible valid\n" - " arguments are instances of Tree or Index.\n" - "\n" - "flags\n" - " TODO"); +PyDoc_STRVAR(Tree_diff_to_workdir__doc__, "\n"); PyObject * -Tree_diff(Tree *self, PyObject *args, PyObject *kwds) +Tree_diff_to_workdir(Tree *self, PyObject *args) { git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_diff_list *diff; - git_tree* tree = NULL; - git_index* index; git_repository* repo; - int err, empty_tree = 0; - char *keywords[] = {"obj", "flags", "empty_tree", NULL}; + int err; Diff *py_diff; PyObject *py_obj = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oii", keywords, - &py_obj, &opts.flags, &empty_tree)) + if (!PyArg_ParseTuple(args, "|i", &opts.flags)) return NULL; repo = self->repo->repo; - if (py_obj == NULL) { - if (empty_tree > 0) - err = git_diff_tree_to_tree(&diff, repo, self->tree, NULL, &opts); - else - err = git_diff_tree_to_workdir(&diff, repo, self->tree, &opts); - - } else if (PyObject_TypeCheck(py_obj, &TreeType)) { - tree = ((Tree *)py_obj)->tree; - err = git_diff_tree_to_tree(&diff, repo, self->tree, tree, &opts); - - } else if (PyObject_TypeCheck(py_obj, &IndexType)) { - index = ((Index *)py_obj)->index; - err = git_diff_tree_to_index(&diff, repo, self->tree, index, &opts); - - } else { - PyErr_SetObject(PyExc_TypeError, py_obj); - return NULL; - } + err = git_diff_tree_to_workdir(&diff, repo, self->tree, &opts); if (err < 0) return Error_set(err); - py_diff = PyObject_New(Diff, &DiffType); - if (py_diff) { - Py_INCREF(self->repo); - py_diff->repo = self->repo; - py_diff->list = diff; - } + return wrap_diff(diff, self->repo); +} - return (PyObject*)py_diff; + +PyDoc_STRVAR(Tree_diff_to_index__doc__, "\n"); + +PyObject * +Tree_diff_to_index(Tree *self, PyObject *args) +{ + git_diff_options opts = GIT_DIFF_OPTIONS_INIT; + git_diff_list *diff; + git_index* index; + git_repository* repo; + int err; + char *keywords[] = {"obj", "flags", NULL}; + + Diff *py_diff; + Index *py_idx = NULL; + + if (!PyArg_ParseTuple(args, "O!|i", &IndexType, &py_idx, &opts.flags)) + return NULL; + + repo = self->repo->repo; + err = git_diff_tree_to_index(&diff, repo, self->tree, py_idx->index, &opts); + + if (err < 0) + return Error_set(err); + + return wrap_diff(diff, self->repo); +} + + +PyDoc_STRVAR(Tree_diff_to_tree__doc__, "\n"); + +PyObject * +Tree_diff_to_tree(Tree *self, PyObject *args, PyObject *kwds) +{ + git_diff_options opts = GIT_DIFF_OPTIONS_INIT; + git_diff_list *diff; + git_tree* tree; + git_repository* repo; + int err; + char *keywords[] = {"obj", "flags", NULL}; + + Diff *py_diff; + Tree *py_tree = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!i", keywords, + &TreeType, &py_tree, &opts.flags)) + return NULL; + + repo = self->repo->repo; + tree = (py_tree == NULL) ? NULL : py_tree->tree; + err = git_diff_tree_to_tree(&diff, repo, self->tree, tree, &opts); + + if (err < 0) + return Error_set(err); + + return wrap_diff(diff, self->repo); } @@ -355,7 +373,9 @@ PyMappingMethods Tree_as_mapping = { }; PyMethodDef Tree_methods[] = { - METHOD(Tree, diff, METH_VARARGS | METH_KEYWORDS), + METHOD(Tree, diff_to_tree, METH_VARARGS | METH_KEYWORDS), + METHOD(Tree, diff_to_workdir, METH_VARARGS), + METHOD(Tree, diff_to_index, METH_VARARGS), {NULL} }; diff --git a/test/test_diff.py b/test/test_diff.py index 7dd5a01..d68d7ed 100644 --- a/test/test_diff.py +++ b/test/test_diff.py @@ -91,7 +91,7 @@ class DiffDirtyTest(utils.DirtyRepoTestCase): def test_diff_empty_index(self): repo = self.repo head = repo[repo.lookup_reference('HEAD').resolve().target] - diff = head.tree.diff(repo.index) + diff = head.tree.diff_to_index(repo.index) files = [patch.new_file_path for patch in diff] self.assertEqual(DIFF_INDEX_EXPECTED, files) @@ -99,7 +99,7 @@ class DiffDirtyTest(utils.DirtyRepoTestCase): def test_workdir_to_tree(self): repo = self.repo head = repo[repo.lookup_reference('HEAD').resolve().target] - diff = head.tree.diff() + diff = head.tree.diff_to_workdir() files = [patch.new_file_path for patch in diff] self.assertEqual(DIFF_WORKDIR_EXPECTED, files) @@ -110,12 +110,13 @@ 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) + self.assertRaises(TypeError, commit_a.tree.diff_to_tree, commit_b) + self.assertRaises(TypeError, commit_a.tree.diff_to_index, commit_b) def test_diff_empty_index(self): repo = self.repo head = repo[repo.lookup_reference('HEAD').resolve().target] - diff = head.tree.diff(repo.index) + diff = head.tree.diff_to_index(repo.index) files = [patch.new_file_path.split('/')[0] for patch in diff] self.assertEqual([x.name for x in head.tree], files) @@ -124,7 +125,7 @@ class DiffTest(utils.BareRepoTestCase): commit_a = self.repo[COMMIT_SHA1_1] commit_b = self.repo[COMMIT_SHA1_2] - diff = commit_a.tree.diff(commit_b.tree) + diff = commit_a.tree.diff_to_tree(commit_b.tree) # self.assertIsNotNone is 2.7 only self.assertTrue(diff is not None) @@ -143,7 +144,7 @@ class DiffTest(utils.BareRepoTestCase): def test_diff_empty_tree(self): commit_a = self.repo[COMMIT_SHA1_1] - diff = commit_a.tree.diff(empty_tree=True) + diff = commit_a.tree.diff_to_tree() entries = [p.new_file_path for p in diff] self.assertAll(lambda x: commit_a.tree[x], entries) @@ -153,11 +154,11 @@ class DiffTest(utils.BareRepoTestCase): for opt in [pygit2.GIT_DIFF_IGNORE_WHITESPACE, pygit2.GIT_DIFF_IGNORE_WHITESPACE_EOL]: - diff = commit_c.tree.diff(commit_d.tree, opt) + diff = commit_c.tree.diff_to_tree(commit_d.tree, opt) self.assertTrue(diff is not None) self.assertEqual(0, len(diff[0].hunks)) - diff = commit_c.tree.diff(commit_d.tree) + diff = commit_c.tree.diff_to_tree(commit_d.tree) self.assertTrue(diff is not None) self.assertEqual(1, len(diff[0].hunks)) @@ -166,11 +167,11 @@ class DiffTest(utils.BareRepoTestCase): commit_b = self.repo[COMMIT_SHA1_2] commit_c = self.repo[COMMIT_SHA1_3] - diff_b = commit_a.tree.diff(commit_b.tree) + diff_b = commit_a.tree.diff_to_tree(commit_b.tree) # self.assertIsNotNone is 2.7 only self.assertTrue(diff_b is not None) - diff_c = commit_b.tree.diff(commit_c.tree) + diff_c = commit_b.tree.diff_to_tree(commit_c.tree) # self.assertIsNotNone is 2.7 only self.assertTrue(diff_c is not None) @@ -197,13 +198,13 @@ class DiffTest(utils.BareRepoTestCase): commit_a = self.repo[COMMIT_SHA1_1] commit_b = self.repo[COMMIT_SHA1_2] - diff = commit_a.tree.diff(commit_b.tree) + diff = commit_a.tree.diff_to_tree(commit_b.tree) self.assertEqual(diff.patch, PATCH) def test_diff_oids(self): commit_a = self.repo[COMMIT_SHA1_1] commit_b = self.repo[COMMIT_SHA1_2] - patch = commit_a.tree.diff(commit_b.tree)[0] + patch = commit_a.tree.diff_to_tree(commit_b.tree)[0] self.assertEqual(patch.old_oid, '7f129fd57e31e935c6d60a0c794efe4e6927664b') self.assertEqual(patch.new_oid, @@ -212,7 +213,7 @@ class DiffTest(utils.BareRepoTestCase): def test_hunk_content(self): commit_a = self.repo[COMMIT_SHA1_1] commit_b = self.repo[COMMIT_SHA1_2] - patch = commit_a.tree.diff(commit_b.tree)[0] + patch = commit_a.tree.diff_to_tree(commit_b.tree)[0] hunk = patch.hunks[0] lines = ('{0} {1}'.format(*x) for x in hunk.lines) self.assertEqual(HUNK_EXPECTED, ''.join(lines)) @@ -223,7 +224,8 @@ class DiffTest(utils.BareRepoTestCase): #~ Must pass GIT_DIFF_INCLUDE_UNMODIFIED if you expect to emulate #~ --find-copies-harder during rename transformion... - diff = commit_a.tree.diff(commit_b.tree, GIT_DIFF_INCLUDE_UNMODIFIED) + diff = commit_a.tree.diff_to_tree(commit_b.tree, + GIT_DIFF_INCLUDE_UNMODIFIED) self.assertAll(lambda x: x.status != 'R', diff) diff.find_similar() self.assertAny(lambda x: x.status == 'R', diff)