Skip to content

Commit 0fc7a4f

Browse files
Nico von GeysoNico von Geyso
authored andcommitted
Refactored Index.diff() into Index.diff_to_tree()/diff_to_workdir()
1 parent 196d059 commit 0fc7a4f

File tree

5 files changed

+70
-43
lines changed

5 files changed

+70
-43
lines changed

pygit2/repository.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def treeish_to_tree(obj):
180180

181181
# Case 2: Index to workdir
182182
elif a is None and b is None:
183-
return self.index.diff()
183+
return self.index.diff_to_workdir()
184184

185185
# Case 3: Diff tree to index or workdir
186186
elif isinstance(a, Tree) and b is None:

src/diff.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ diff_get_patch_byindex(git_diff_list* list, size_t idx)
109109
goto cleanup;
110110

111111
PyList_SetItem(py_hunk->lines, j,
112-
Py_BuildValue("cO", line_origin,
112+
Py_BuildValue("OO",
113+
to_unicode_n(&line_origin, 1, NULL, NULL),
113114
to_unicode_n(line, line_len, NULL, NULL)
114115
)
115116
);

src/index.c

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "types.h"
3232
#include "utils.h"
3333
#include "oid.h"
34+
#include "diff.h"
3435
#include "index.h"
3536

3637
extern PyTypeObject IndexType;
@@ -114,54 +115,59 @@ Index_clear(Index *self)
114115
}
115116

116117

117-
PyDoc_STRVAR(Index_diff__doc__,
118-
"diff([tree]) -> Diff\n"
118+
PyDoc_STRVAR(Index_diff_to_workdir__doc__,
119+
"diff_to_workdir() -> Diff\n"
119120
"\n"
120121
"Return a :py:class:`~pygit2.Diff` object with the differences between the\n"
121-
"index and the working copy. If a :py:class:`~pygit2.Tree` object is\n"
122-
"passed, return the diferences between the index and the given tree.");
122+
"index and the working copy.\n");
123123

124124
PyObject *
125-
Index_diff(Index *self, PyObject *args)
125+
Index_diff_to_workdir(Index *self, PyObject *args)
126126
{
127127
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
128128
git_diff_list *diff;
129129
int err;
130130

131-
Diff *py_diff;
132-
PyObject *py_obj = NULL;
133-
134-
if (!PyArg_ParseTuple(args, "|O", &py_obj))
131+
if (!PyArg_ParseTuple(args, "|i", &opts.flags))
135132
return NULL;
136133

137-
if (py_obj == NULL) {
138-
err = git_diff_index_to_workdir(
139-
&diff,
140-
self->repo->repo,
141-
self->index,
142-
&opts);
143-
} else if (PyObject_TypeCheck(py_obj, &TreeType)) {
144-
err = git_diff_tree_to_index(
145-
&diff,
146-
self->repo->repo,
147-
((Tree *)py_obj)->tree,
148-
self->index,
149-
&opts);
150-
} else {
151-
PyErr_SetObject(PyExc_TypeError, py_obj);
152-
return NULL;
153-
}
134+
err = git_diff_index_to_workdir(
135+
&diff,
136+
self->repo->repo,
137+
self->index,
138+
&opts);
139+
154140
if (err < 0)
155141
return Error_set(err);
156142

157-
py_diff = PyObject_New(Diff, &DiffType);
158-
if (py_diff) {
159-
Py_INCREF(self->repo);
160-
py_diff->repo = self->repo;
161-
py_diff->list = diff;
162-
}
143+
return wrap_diff(diff, self->repo);
144+
}
145+
146+
PyDoc_STRVAR(Index_diff_to_tree__doc__,
147+
"diff_to_tree(tree) -> Diff\n"
148+
"\n"
149+
"Return a :py:class:`~pygit2.Diff` object with the differences between the\n"
150+
"index and the given tree.\n");
151+
152+
PyObject *
153+
Index_diff_to_tree(Index *self, PyObject *args)
154+
{
155+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
156+
git_diff_list *diff;
157+
git_repository* repo;
158+
int err;
159+
160+
Tree *py_tree = NULL;
161+
162+
if (!PyArg_ParseTuple(args, "O!|i", &TreeType, &py_tree, &opts.flags))
163+
return NULL;
164+
165+
repo = self->repo->repo;
166+
err = git_diff_tree_to_index(&diff, repo, py_tree->tree, self->index, &opts);
167+
if (err < 0)
168+
return Error_set(err);
163169

164-
return (PyObject*)py_diff;
170+
return wrap_diff(diff, self->repo);
165171
}
166172

167173

@@ -393,7 +399,8 @@ PyMethodDef Index_methods[] = {
393399
METHOD(Index, add, METH_VARARGS),
394400
METHOD(Index, remove, METH_VARARGS),
395401
METHOD(Index, clear, METH_NOARGS),
396-
METHOD(Index, diff, METH_VARARGS),
402+
METHOD(Index, diff_to_workdir, METH_VARARGS),
403+
METHOD(Index, diff_to_tree, METH_VARARGS),
397404
METHOD(Index, _find, METH_O),
398405
METHOD(Index, read, METH_NOARGS),
399406
METHOD(Index, write, METH_NOARGS),

src/tree.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,6 @@ Tree_diff_to_index(Tree *self, PyObject *args, PyObject *kwds)
317317

318318
repo = self->repo->repo;
319319
err = git_diff_tree_to_index(&diff, repo, self->tree, py_idx->index, &opts);
320-
321320
if (err < 0)
322321
return Error_set(err);
323322

test/test_diff.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
-c/d contents
6262
"""
6363

64-
DIFF_INDEX_EXPECTED = [
64+
DIFF_HEAD_TO_INDEX_EXPECTED = [
6565
'staged_changes',
6666
'staged_changes_file_deleted',
6767
'staged_changes_file_modified',
@@ -72,7 +72,7 @@
7272
'staged_new_file_modified'
7373
]
7474

75-
DIFF_WORKDIR_EXPECTED = [
75+
DIFF_HEAD_TO_WORKDIR_EXPECTED = [
7676
'file_deleted',
7777
'modified_file',
7878
'staged_changes',
@@ -84,6 +84,17 @@
8484
'subdir/modified_file'
8585
]
8686

87+
DIFF_INDEX_TO_WORK_EXPECTED = [
88+
'file_deleted',
89+
'modified_file',
90+
'staged_changes_file_deleted',
91+
'staged_changes_file_modified',
92+
'staged_new_file_deleted',
93+
'staged_new_file_modified',
94+
'subdir/deleted_file',
95+
'subdir/modified_file'
96+
]
97+
8798
HUNK_EXPECTED = """- a contents 2
8899
+ a contents
89100
"""
@@ -95,23 +106,28 @@ def test_diff_empty_index(self):
95106
head = repo[repo.lookup_reference('HEAD').resolve().target]
96107
diff = head.tree.diff_to_index(repo.index)
97108
files = [patch.new_file_path for patch in diff]
98-
self.assertEqual(DIFF_INDEX_EXPECTED, files)
109+
self.assertEqual(DIFF_HEAD_TO_INDEX_EXPECTED, files)
99110

100111
diff = repo.diff('HEAD', cached=True)
101112
files = [patch.new_file_path for patch in diff]
102-
self.assertEqual(DIFF_INDEX_EXPECTED, files)
113+
self.assertEqual(DIFF_HEAD_TO_INDEX_EXPECTED, files)
103114

104115
def test_workdir_to_tree(self):
105116
repo = self.repo
106117
head = repo[repo.lookup_reference('HEAD').resolve().target]
107118

108119
diff = head.tree.diff_to_workdir()
109120
files = [patch.new_file_path for patch in diff]
110-
self.assertEqual(DIFF_WORKDIR_EXPECTED, files)
121+
self.assertEqual(DIFF_HEAD_TO_WORKDIR_EXPECTED, files)
111122

112123
diff = repo.diff('HEAD')
113124
files = [patch.new_file_path for patch in diff]
114-
self.assertEqual(DIFF_WORKDIR_EXPECTED, files)
125+
self.assertEqual(DIFF_HEAD_TO_WORKDIR_EXPECTED, files)
126+
127+
def test_index_to_workdir(self):
128+
diff = self.repo.diff()
129+
files = [patch.new_file_path for patch in diff]
130+
self.assertEqual(DIFF_INDEX_TO_WORK_EXPECTED, files)
115131

116132

117133
class DiffTest(utils.BareRepoTestCase):
@@ -126,6 +142,10 @@ def test_diff_empty_index(self):
126142
repo = self.repo
127143
head = repo[repo.lookup_reference('HEAD').resolve().target]
128144

145+
diff = self.repo.index.diff_to_tree(head.tree)
146+
files = [patch.new_file_path.split('/')[0] for patch in diff]
147+
self.assertEqual([x.name for x in head.tree], files)
148+
129149
diff = head.tree.diff_to_index(repo.index)
130150
files = [patch.new_file_path.split('/')[0] for patch in diff]
131151
self.assertEqual([x.name for x in head.tree], files)

0 commit comments

Comments
 (0)