Skip to content

Commit 40babf6

Browse files
committed
Add Repository.parse_diff to wrap git_diff_from_buffer
1 parent 9e42130 commit 40babf6

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

src/repository.c

+27
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "oid.h"
3636
#include "note.h"
3737
#include "repository.h"
38+
#include "diff.h"
3839
#include "branch.h"
3940
#include "signature.h"
4041
#include <git2/odb_backend.h>
@@ -1464,6 +1465,31 @@ Repository_create_reference_symbolic(Repository *self, PyObject *args,
14641465
return wrap_reference(c_reference, self);
14651466
}
14661467

1468+
PyDoc_STRVAR(Repository_parse_diff__doc__,
1469+
"parse_diff(git_diff: str) -> Diff\n"
1470+
"\n"
1471+
"Parses a git unified diff into a diff object applied to the repository");
1472+
1473+
PyObject *
1474+
Repository_parse_diff(PyObject *self, PyObject *args)
1475+
{
1476+
/* A wrapper around
1477+
* git_diff_from_buffer
1478+
*/
1479+
git_diff *diff;
1480+
const char *content = NULL;
1481+
Py_ssize_t content_len;
1482+
int err;
1483+
1484+
if (!PyArg_ParseTuple(args, "s#", &content, &content_len))
1485+
return NULL;
1486+
1487+
err = git_diff_from_buffer(&diff, content, content_len);
1488+
if (err < 0)
1489+
return Error_set(err);
1490+
1491+
return wrap_diff(diff, (Repository *) self);
1492+
}
14671493

14681494
PyDoc_STRVAR(Repository_status__doc__,
14691495
"status() -> {str: int}\n"
@@ -1813,6 +1839,7 @@ PyMethodDef Repository_methods[] = {
18131839
METHOD(Repository, init_submodules, METH_VARARGS | METH_KEYWORDS),
18141840
METHOD(Repository, lookup_reference, METH_O),
18151841
METHOD(Repository, revparse_single, METH_O),
1842+
METHOD(Repository, parse_diff, METH_VARARGS),
18161843
METHOD(Repository, status, METH_NOARGS),
18171844
METHOD(Repository, status_file, METH_O),
18181845
METHOD(Repository, notes, METH_VARARGS),

test/test_repository.py

+40
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import binascii
3636
import unittest
3737
import tempfile
38+
import textwrap
3839
import os
3940
from os.path import join, realpath
4041
import sys
@@ -196,6 +197,45 @@ def test_hash(self):
196197
written_sha1 = self.repo.create_blob(data)
197198
self.assertEqual(hashed_sha1, written_sha1)
198199

200+
def test_parse_diff_null(self):
201+
with self.assertRaises(Exception):
202+
self.repo.parse_diff(None)
203+
204+
def test_parse_diff_bad(self):
205+
diff = textwrap.dedent(
206+
"""
207+
diff --git a/file1 b/file1
208+
old mode 0644
209+
new mode 0644
210+
@@ -1,1 +1,1 @@
211+
-Hi!
212+
""")
213+
with self.assertRaises(Exception):
214+
self.repo.parse_diff(diff)
215+
216+
def test_parse_diff(self):
217+
diff = textwrap.dedent(
218+
"""
219+
diff --git a/file1 b/file1
220+
old mode 0644
221+
new mode 0644
222+
@@ -1,1 +1,1 @@
223+
-Hello, world!
224+
+Hola, Mundo!
225+
"""
226+
)
227+
git_diff = self.repo.parse_diff(diff)
228+
stats = git_diff.stats
229+
deltas = list(git_diff.deltas)
230+
231+
self.assertEqual(1, stats.deletions)
232+
self.assertEqual(1, stats.insertions)
233+
self.assertEqual(1, stats.files_changed)
234+
235+
self.assertEqual(1, len(deltas))
236+
self.assertEqual("file1", deltas[0].old_file.path)
237+
self.assertEqual("file1", deltas[0].new_file.path)
238+
199239
def test_hashfile(self):
200240
data = "bazbarfoo"
201241
handle, tempfile_path = tempfile.mkstemp()

0 commit comments

Comments
 (0)