File tree Expand file tree Collapse file tree 3 files changed +38
-2
lines changed
Expand file tree Collapse file tree 3 files changed +38
-2
lines changed Original file line number Diff line number Diff line change @@ -432,8 +432,8 @@ class Diff:
432432def from_c (diff , repo ) -> Diff : ...
433433@staticmethod
434434def parse_diff (git_diff : str | bytes ) -> Diff : ...
435- def __getitem__ (self , index : int ) -> Patch : ... # Diff_getitem
436- def __iter__ (self ) -> Iterator [Patch ]: ... # -> DiffIter
435+ def __getitem__ (self , index : int ) -> Patch | None : ... # Diff_getitem
436+ def __iter__ (self ) -> Iterator [Patch | None ]: ... # -> DiffIter
437437def __len__ (self ) -> int : ...
438438
439439class DiffDelta :
Original file line number Diff line number Diff line change @@ -533,6 +533,11 @@ diff_get_patch_byindex(git_diff *diff, size_t idx)
533533if (err < 0 )
534534return Error_set (err );
535535
536+ /* libgit2 may decide not to create a patch if the file is
537+ "unchanged or binary", but this isn't an error case */
538+ if (patch == NULL )
539+ Py_RETURN_NONE ;
540+
536541return (PyObject * ) wrap_patch (patch , NULL , NULL );
537542}
538543
Original file line number Diff line number Diff line change 2828import textwrap
2929from collections .abc import Iterator
3030from itertools import chain
31+ from pathlib import Path
3132
3233import pytest
3334
@@ -459,3 +460,33 @@ def test_diff_blobs(emptyrepo: Repository) -> None:
459460assert diff_one_context_line .text == PATCH_BLOBS_ONE_CONTEXT_LINE
460461diff_all_together = repo .diff (blob1 , blob2 , context_lines = 1 , interhunk_lines = 1 )
461462assert diff_all_together .text == PATCH_BLOBS_DEFAULT
463+
464+
465+ def test_diff_unchanged_file_no_patch (testrepo ) -> None :
466+ repo = testrepo
467+
468+ # Convert hello.txt line endings to CRLF
469+ path = Path (repo .workdir ) / 'hello.txt'
470+ data = path .read_bytes ()
471+ data = data .replace (b'\n ' , b'\r \n ' )
472+ path .write_bytes (data )
473+
474+ # Enable CRLF filter
475+ repo .config ['core.autocrlf' ] = 'input'
476+
477+ diff = repo .diff ()
478+ assert len (diff ) == 1
479+
480+ # Get patch #0 in the same diff several times.
481+ # git_patch_from_diff eventually decides that the file is "unchanged"
482+ # it returns a NULL patch in this case.
483+ # https://libgit2.org/docs/reference/main/patch/git_patch_from_diff
484+ for i in range (10 ): # loop typically exits in the third iteration
485+ patch = diff [0 ]
486+ if patch is None : # libgit2 decides the file is unchanged
487+ break
488+ assert patch .delta .new_file .path == path .name
489+ assert patch .text == '' # no content change (just line endings)
490+ else :
491+ # Didn't find the edge case that this test is supposed to exercise.
492+ assert False , 'libgit2 rebuilt a new patch every time'
You can’t perform that action at this time.
0 commit comments