From 044e30e0b1a6c9aadbd973374e5ec2a3368b5c3e Mon Sep 17 00:00:00 2001 From: Edmundo Carmona Antoranz Date: Fri, 18 Apr 2025 04:13:05 +0200 Subject: [PATCH] repository - diff blobs: consider the values of context_lines and interhunk_lines --- pygit2/repository.py | 4 ++- src/blob.c | 17 +++++++--- test/test_diff.py | 76 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/pygit2/repository.py b/pygit2/repository.py index 9a6594d0..61ecd9ec 100644 --- a/pygit2/repository.py +++ b/pygit2/repository.py @@ -541,7 +541,9 @@ def diff( # Case 4: Diff blob to blob if isinstance(a, Blob) and isinstance(b, Blob): - return a.diff(b) + opt_values.insert(1, 'file') + opt_values.insert(1, 'file') + return a.diff(b, *opt_values) raise ValueError('Only blobs and treeish can be diffed') diff --git a/src/blob.c b/src/blob.c index 0561660f..6fd6e734 100644 --- a/src/blob.c +++ b/src/blob.c @@ -60,7 +60,15 @@ PyDoc_STRVAR(Blob_diff__doc__, " Treat old blob as if it had this filename.\n" "\n" "new_as_path : str\n" - " Treat new blob as if it had this filename.\n"); + " Treat new blob as if it had this filename.\n" + "\n" + "context_lines: int\n" + " Number of unchanged lines that define the boundary of a hunk\n" + " (and to display before and after).\n" + "\n" + "interhunk_lines: int\n" + " Maximum number of unchanged lines between hunk boundaries\n" + " before the hunks will be merged into one.\n"); PyObject * Blob_diff(Blob *self, PyObject *args, PyObject *kwds) @@ -70,11 +78,12 @@ Blob_diff(Blob *self, PyObject *args, PyObject *kwds) char *old_as_path = NULL, *new_as_path = NULL; Blob *other = NULL; int err; - char *keywords[] = {"blob", "flag", "old_as_path", "new_as_path", NULL}; + char *keywords[] = {"blob", "flag", "old_as_path", "new_as_path", "context_lines", "interhunk_lines", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!Iss", keywords, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!IssHH", keywords, &BlobType, &other, &opts.flags, - &old_as_path, &new_as_path)) + &old_as_path, &new_as_path, + &opts.context_lines, &opts.interhunk_lines)) return NULL; if (Object__load((Object*)self) == NULL) { return NULL; } // Lazy load diff --git a/test/test_diff.py b/test/test_diff.py index 28e1b0c3..f73a4c64 100644 --- a/test/test_diff.py +++ b/test/test_diff.py @@ -107,6 +107,68 @@ delete mode 100644 c/d """ +TEXT_BLOB1 = """Common header of the file +Blob 1 line 1 +Common middle line 1 +Common middle line 2 +Common middle line 3 +Blob 1 line 2 +Common footer of the file +""" + +TEXT_BLOB2 = """Common header of the file +Blob 2 line 1 +Common middle line 1 +Common middle line 2 +Common middle line 3 +Blob 2 line 2 +Common footer of the file +""" + +PATCH_BLOBS_DEFAULT = """diff --git a/file b/file +index 0b5ac93..ddfdbcc 100644 +--- a/file ++++ b/file +@@ -1,7 +1,7 @@ + Common header of the file +-Blob 1 line 1 ++Blob 2 line 1 + Common middle line 1 + Common middle line 2 + Common middle line 3 +-Blob 1 line 2 ++Blob 2 line 2 + Common footer of the file +""" + +PATCH_BLOBS_NO_LEEWAY = """diff --git a/file b/file +index 0b5ac93..ddfdbcc 100644 +--- a/file ++++ b/file +@@ -2 +2 @@ Common header of the file +-Blob 1 line 1 ++Blob 2 line 1 +@@ -6 +6 @@ Common middle line 3 +-Blob 1 line 2 ++Blob 2 line 2 +""" + +PATCH_BLOBS_ONE_CONTEXT_LINE = """diff --git a/file b/file +index 0b5ac93..ddfdbcc 100644 +--- a/file ++++ b/file +@@ -1,3 +1,3 @@ + Common header of the file +-Blob 1 line 1 ++Blob 2 line 1 + Common middle line 1 +@@ -5,3 +5,3 @@ Common middle line 2 + Common middle line 3 +-Blob 1 line 2 ++Blob 2 line 2 + Common footer of the file +""" + def test_diff_empty_index(dirtyrepo): repo = dirtyrepo @@ -382,3 +444,17 @@ def test_parse_diff_bad(): ) with pytest.raises(pygit2.GitError): pygit2.Diff.parse_diff(diff) + + +def test_diff_blobs(emptyrepo): + repo = emptyrepo + blob1 = repo.create_blob(TEXT_BLOB1.encode()) + blob2 = repo.create_blob(TEXT_BLOB2.encode()) + diff_default = repo.diff(blob1, blob2) + assert diff_default.text == PATCH_BLOBS_DEFAULT + diff_no_leeway = repo.diff(blob1, blob2, context_lines=0) + assert diff_no_leeway.text == PATCH_BLOBS_NO_LEEWAY + diff_one_context_line = repo.diff(blob1, blob2, context_lines=1) + assert diff_one_context_line.text == PATCH_BLOBS_ONE_CONTEXT_LINE + diff_all_together = repo.diff(blob1, blob2, context_lines=1, interhunk_lines=1) + assert diff_all_together.text == PATCH_BLOBS_DEFAULT