Skip to content

repo.index.diff("HEAD", create_patch=True) always empty #852

Description

@jadinm

I am using GitPython v2.1.11 with Python 3.6. My git version is 2.17.1.

I see inconsistent behavior of the diff method of a repo index if create_patch option set to True.
I am running the following script in a git repository with staged and unstaged changes.

from git import Repo

repo = Repo(".")

print(repo.index.diff("HEAD"))
print(repo.index.diff("HEAD", create_patch=True)) # Problem here

print(repo.index.diff(None))
print(repo.index.diff(None, create_patch=True))

But it prints:

[<git.diff.Diff object at 0x7fd54c328678>, <git.diff.Diff object at 0x7fd549e405e8>, <git.diff.Diff object at 0x7fd54c328558>]
[]
[<git.diff.Diff object at 0x7fd54c328678>]
[<git.diff.Diff object at 0x7fd54c328678>]

Somehow, the diff is empty if I set create_patch to True and the first argument to anything but None.
Do you know why it happens ?

Activity

  1. jadinm commented on Mar 13, 2019

    @jadinm
    Author

    I found out the problem.

    When running repo.index.diff("HEAD", create_patch=True), the command used is:

    $ git diff -R <reference-hash> --cached --abbrev=40 --full-index -M -p --no-color

    And this produces:

    diff --git b/other_file.txt a/other_file.txt
    deleted file mode 100644
    index d733472942281cd2f19f52ab4b5ddecb4151bb72..0000000000000000000000000000000000000000
    --- b/other_file.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -Other file
    

    But the regex that is used for parsing (i.e., Diff.re_header) expects a/other_file.txt to be before b/other_file.txt.
    The inversion is due to the "-R" flag in the command line.


    A temporary fix for my use of GitPython is to set R to True to prevent the reversal.

    print(repo.index.diff("HEAD", create_patch=True, R=True))
  2. Byron commented on Jul 20, 2019

    @Byron
    Member

    Thanks a lot for sharing the issue, and for posting the workaround here as well!

  3. can-taslicukur commented on Feb 18, 2024

    @can-taslicukur
    Contributor

    I am using version 3.1.42 and experiencing this issue currently.

    from git import Repo
    
    repo = Repo(".")
    print(repo.index.diff("HEAD"))
    print(repo.index.diff("HEAD", create_patch=True))
    
    print(repo.index.diff(None))
    print(repo.index.diff(None, create_patch=True))

    prints

    [<git.diff.Diff object at 0x10cbb08b0>]
    []
    [<git.diff.Diff object at 0x103d49d30>]
    []

    R=True workaround does not help either:

    print(repo.index.diff("HEAD", create_patch=True, R=True))
    # []

    This also happens when I try to diff tree against index or working tree

    print(repo.head.commit.diff(None, create_patch=True))
    print(repo.head.commit.diff(None))
    
    print(repo.head.commit.diff())
    print(repo.head.commit.diff(create_patch=True))

    returns

    []
    [<git.diff.Diff object at 0x103d69670>, <git.diff.Diff object at 0x103d699d0>]
    []
    [<git.diff.Diff object at 0x103d69700>]

    It looks like using create_patch=True when comparison includes index or working tree always returns empty list. So right now only way to reliably use create_patch=True is to diff tree against tree.

  4. added a commit that references this issue on Apr 28, 2025
    14d7034
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions