Skip to content

Commit ae6cd8a

Browse files
Nico von GeysoNico von Geyso
authored andcommitted
refactoring Tree.diff() into seperate methods
* Tree.diff_to_tree() * Tree.diff_to_workdir() * Tree.diff-to_index()
1 parent 2d812b6 commit ae6cd8a

File tree

4 files changed

+99
-60
lines changed

4 files changed

+99
-60
lines changed

src/diff.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,21 @@ extern PyTypeObject HunkType;
4242

4343
PyTypeObject PatchType;
4444

45+
PyObject*
46+
wrap_diff(git_diff_list *diff, Repository *repo)
47+
{
48+
Diff *py_diff;
49+
50+
py_diff = PyObject_New(Diff, &DiffType);
51+
if (py_diff) {
52+
Py_INCREF(repo);
53+
py_diff->repo = repo;
54+
py_diff->list = diff;
55+
}
56+
57+
return (PyObject*) py_diff;
58+
}
59+
4560
PyObject*
4661
diff_get_patch_byindex(git_diff_list* list, size_t idx)
4762
{

src/diff.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,6 @@
4141
PyObject* Diff_changes(Diff *self);
4242
PyObject* Diff_patch(Diff *self);
4343

44+
PyObject* wrap_diff(git_diff_list *diff, Repository *repo);
45+
4446
#endif

src/tree.c

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "repository.h"
3434
#include "oid.h"
3535
#include "tree.h"
36+
#include "diff.h"
3637

3738
extern PyTypeObject TreeType;
3839
extern PyTypeObject DiffType;
@@ -270,70 +271,87 @@ Tree_getitem(Tree *self, PyObject *value)
270271
}
271272

272273

273-
PyDoc_STRVAR(Tree_diff__doc__,
274-
"diff([obj, flags]) -> Diff\n"
275-
"\n"
276-
"Get changes between current tree instance with another tree, an index or\n"
277-
"the working dir.\n"
278-
"\n"
279-
"Arguments:\n"
280-
"\n"
281-
"obj\n"
282-
" If not given compare diff against working dir. Possible valid\n"
283-
" arguments are instances of Tree or Index.\n"
284-
"\n"
285-
"flags\n"
286-
" TODO");
274+
PyDoc_STRVAR(Tree_diff_to_workdir__doc__, "\n");
287275

288276
PyObject *
289-
Tree_diff(Tree *self, PyObject *args, PyObject *kwds)
277+
Tree_diff_to_workdir(Tree *self, PyObject *args)
290278
{
291279
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
292280
git_diff_list *diff;
293-
git_tree* tree = NULL;
294-
git_index* index;
295281
git_repository* repo;
296-
int err, empty_tree = 0;
297-
char *keywords[] = {"obj", "flags", "empty_tree", NULL};
282+
int err;
298283

299284
Diff *py_diff;
300285
PyObject *py_obj = NULL;
301286

302-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oii", keywords,
303-
&py_obj, &opts.flags, &empty_tree))
287+
if (!PyArg_ParseTuple(args, "|i", &opts.flags))
304288
return NULL;
305289

306290
repo = self->repo->repo;
307-
if (py_obj == NULL) {
308-
if (empty_tree > 0)
309-
err = git_diff_tree_to_tree(&diff, repo, self->tree, NULL, &opts);
310-
else
311-
err = git_diff_tree_to_workdir(&diff, repo, self->tree, &opts);
312-
313-
} else if (PyObject_TypeCheck(py_obj, &TreeType)) {
314-
tree = ((Tree *)py_obj)->tree;
315-
err = git_diff_tree_to_tree(&diff, repo, self->tree, tree, &opts);
316-
317-
} else if (PyObject_TypeCheck(py_obj, &IndexType)) {
318-
index = ((Index *)py_obj)->index;
319-
err = git_diff_tree_to_index(&diff, repo, self->tree, index, &opts);
320-
321-
} else {
322-
PyErr_SetObject(PyExc_TypeError, py_obj);
291+
err = git_diff_tree_to_workdir(&diff, repo, self->tree, &opts);
292+
293+
if (err < 0)
294+
return Error_set(err);
295+
296+
return wrap_diff(diff, self->repo);
297+
}
298+
299+
300+
PyDoc_STRVAR(Tree_diff_to_index__doc__, "\n");
301+
302+
PyObject *
303+
Tree_diff_to_index(Tree *self, PyObject *args)
304+
{
305+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
306+
git_diff_list *diff;
307+
git_index* index;
308+
git_repository* repo;
309+
int err;
310+
char *keywords[] = {"obj", "flags", NULL};
311+
312+
Diff *py_diff;
313+
Index *py_idx = NULL;
314+
315+
if (!PyArg_ParseTuple(args, "O!|i", &IndexType, &py_idx, &opts.flags))
323316
return NULL;
324-
}
317+
318+
repo = self->repo->repo;
319+
err = git_diff_tree_to_index(&diff, repo, self->tree, py_idx->index, &opts);
325320

326321
if (err < 0)
327322
return Error_set(err);
328323

329-
py_diff = PyObject_New(Diff, &DiffType);
330-
if (py_diff) {
331-
Py_INCREF(self->repo);
332-
py_diff->repo = self->repo;
333-
py_diff->list = diff;
334-
}
324+
return wrap_diff(diff, self->repo);
325+
}
326+
327+
328+
PyDoc_STRVAR(Tree_diff_to_tree__doc__, "\n");
329+
330+
PyObject *
331+
Tree_diff_to_tree(Tree *self, PyObject *args, PyObject *kwds)
332+
{
333+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
334+
git_diff_list *diff;
335+
git_tree* tree;
336+
git_repository* repo;
337+
int err;
338+
char *keywords[] = {"obj", "flags", NULL};
339+
340+
Diff *py_diff;
341+
Tree *py_tree = NULL;
342+
343+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!i", keywords,
344+
&TreeType, &py_tree, &opts.flags))
345+
return NULL;
346+
347+
repo = self->repo->repo;
348+
tree = (py_tree == NULL) ? NULL : py_tree->tree;
349+
err = git_diff_tree_to_tree(&diff, repo, self->tree, tree, &opts);
350+
351+
if (err < 0)
352+
return Error_set(err);
335353

336-
return (PyObject*)py_diff;
354+
return wrap_diff(diff, self->repo);
337355
}
338356

339357

@@ -355,7 +373,9 @@ PyMappingMethods Tree_as_mapping = {
355373
};
356374

357375
PyMethodDef Tree_methods[] = {
358-
METHOD(Tree, diff, METH_VARARGS | METH_KEYWORDS),
376+
METHOD(Tree, diff_to_tree, METH_VARARGS | METH_KEYWORDS),
377+
METHOD(Tree, diff_to_workdir, METH_VARARGS),
378+
METHOD(Tree, diff_to_index, METH_VARARGS),
359379
{NULL}
360380
};
361381

test/test_diff.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,15 @@ class DiffDirtyTest(utils.DirtyRepoTestCase):
9191
def test_diff_empty_index(self):
9292
repo = self.repo
9393
head = repo[repo.lookup_reference('HEAD').resolve().target]
94-
diff = head.tree.diff(repo.index)
94+
diff = head.tree.diff_to_index(repo.index)
9595

9696
files = [patch.new_file_path for patch in diff]
9797
self.assertEqual(DIFF_INDEX_EXPECTED, files)
9898

9999
def test_workdir_to_tree(self):
100100
repo = self.repo
101101
head = repo[repo.lookup_reference('HEAD').resolve().target]
102-
diff = head.tree.diff()
102+
diff = head.tree.diff_to_workdir()
103103

104104
files = [patch.new_file_path for patch in diff]
105105
self.assertEqual(DIFF_WORKDIR_EXPECTED, files)
@@ -110,12 +110,13 @@ class DiffTest(utils.BareRepoTestCase):
110110
def test_diff_invalid(self):
111111
commit_a = self.repo[COMMIT_SHA1_1]
112112
commit_b = self.repo[COMMIT_SHA1_2]
113-
self.assertRaises(TypeError, commit_a.tree.diff, commit_b)
113+
self.assertRaises(TypeError, commit_a.tree.diff_to_tree, commit_b)
114+
self.assertRaises(TypeError, commit_a.tree.diff_to_index, commit_b)
114115

115116
def test_diff_empty_index(self):
116117
repo = self.repo
117118
head = repo[repo.lookup_reference('HEAD').resolve().target]
118-
diff = head.tree.diff(repo.index)
119+
diff = head.tree.diff_to_index(repo.index)
119120

120121
files = [patch.new_file_path.split('/')[0] for patch in diff]
121122
self.assertEqual([x.name for x in head.tree], files)
@@ -124,7 +125,7 @@ def test_diff_tree(self):
124125
commit_a = self.repo[COMMIT_SHA1_1]
125126
commit_b = self.repo[COMMIT_SHA1_2]
126127

127-
diff = commit_a.tree.diff(commit_b.tree)
128+
diff = commit_a.tree.diff_to_tree(commit_b.tree)
128129

129130
# self.assertIsNotNone is 2.7 only
130131
self.assertTrue(diff is not None)
@@ -143,7 +144,7 @@ def test_diff_tree(self):
143144

144145
def test_diff_empty_tree(self):
145146
commit_a = self.repo[COMMIT_SHA1_1]
146-
diff = commit_a.tree.diff(empty_tree=True)
147+
diff = commit_a.tree.diff_to_tree()
147148
entries = [p.new_file_path for p in diff]
148149
self.assertAll(lambda x: commit_a.tree[x], entries)
149150

@@ -153,11 +154,11 @@ def test_diff_tree_opts(self):
153154

154155
for opt in [pygit2.GIT_DIFF_IGNORE_WHITESPACE,
155156
pygit2.GIT_DIFF_IGNORE_WHITESPACE_EOL]:
156-
diff = commit_c.tree.diff(commit_d.tree, opt)
157+
diff = commit_c.tree.diff_to_tree(commit_d.tree, opt)
157158
self.assertTrue(diff is not None)
158159
self.assertEqual(0, len(diff[0].hunks))
159160

160-
diff = commit_c.tree.diff(commit_d.tree)
161+
diff = commit_c.tree.diff_to_tree(commit_d.tree)
161162
self.assertTrue(diff is not None)
162163
self.assertEqual(1, len(diff[0].hunks))
163164

@@ -166,11 +167,11 @@ def test_diff_merge(self):
166167
commit_b = self.repo[COMMIT_SHA1_2]
167168
commit_c = self.repo[COMMIT_SHA1_3]
168169

169-
diff_b = commit_a.tree.diff(commit_b.tree)
170+
diff_b = commit_a.tree.diff_to_tree(commit_b.tree)
170171
# self.assertIsNotNone is 2.7 only
171172
self.assertTrue(diff_b is not None)
172173

173-
diff_c = commit_b.tree.diff(commit_c.tree)
174+
diff_c = commit_b.tree.diff_to_tree(commit_c.tree)
174175
# self.assertIsNotNone is 2.7 only
175176
self.assertTrue(diff_c is not None)
176177

@@ -197,13 +198,13 @@ def test_diff_patch(self):
197198
commit_a = self.repo[COMMIT_SHA1_1]
198199
commit_b = self.repo[COMMIT_SHA1_2]
199200

200-
diff = commit_a.tree.diff(commit_b.tree)
201+
diff = commit_a.tree.diff_to_tree(commit_b.tree)
201202
self.assertEqual(diff.patch, PATCH)
202203

203204
def test_diff_oids(self):
204205
commit_a = self.repo[COMMIT_SHA1_1]
205206
commit_b = self.repo[COMMIT_SHA1_2]
206-
patch = commit_a.tree.diff(commit_b.tree)[0]
207+
patch = commit_a.tree.diff_to_tree(commit_b.tree)[0]
207208
self.assertEqual(patch.old_oid,
208209
'7f129fd57e31e935c6d60a0c794efe4e6927664b')
209210
self.assertEqual(patch.new_oid,
@@ -212,7 +213,7 @@ def test_diff_oids(self):
212213
def test_hunk_content(self):
213214
commit_a = self.repo[COMMIT_SHA1_1]
214215
commit_b = self.repo[COMMIT_SHA1_2]
215-
patch = commit_a.tree.diff(commit_b.tree)[0]
216+
patch = commit_a.tree.diff_to_tree(commit_b.tree)[0]
216217
hunk = patch.hunks[0]
217218
lines = ('{0} {1}'.format(*x) for x in hunk.lines)
218219
self.assertEqual(HUNK_EXPECTED, ''.join(lines))
@@ -223,7 +224,8 @@ def test_find_similar(self):
223224

224225
#~ Must pass GIT_DIFF_INCLUDE_UNMODIFIED if you expect to emulate
225226
#~ --find-copies-harder during rename transformion...
226-
diff = commit_a.tree.diff(commit_b.tree, GIT_DIFF_INCLUDE_UNMODIFIED)
227+
diff = commit_a.tree.diff_to_tree(commit_b.tree,
228+
GIT_DIFF_INCLUDE_UNMODIFIED)
227229
self.assertAll(lambda x: x.status != 'R', diff)
228230
diff.find_similar()
229231
self.assertAny(lambda x: x.status == 'R', diff)

0 commit comments

Comments
 (0)