GitPython icon indicating copy to clipboard operation
GitPython copied to clipboard

commit.diff(branch, create_patch=True) gets "+" and "-" backwards

Open lhannest opened this issue 4 years ago • 3 comments

When I do this:

>>> import git
>>> r = git.Repo('.')
>>> from pprint import pprint
>>> pprint(r.active_branch.commit.diff('master', create_patch=True)[0].diff.decode('utf-8').split('\n'))

Then I see the same first file as when I do git diff master in the terminal. But, it gets the "+" and "-" backwards. In python I see lines such as:

...
'-import static org.mockito.Matchers.anyLong;',
'-import static org.mockito.Matchers.anyString;',
'-import static org.mockito.Mockito.times;',
...

But this is a file I've added in the active branch that isn't in the master! In the terminal when I do git diff master I see:

...
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.times;
...

On the other hand, when I use pprint(r.git.diff('master').split('\n')) then I get the right result:

...
'+import static org.mockito.Matchers.anyLong;',
'+import static org.mockito.Matchers.anyString;',
'+import static org.mockito.Mockito.times;',
...

lhannest avatar Jul 13 '21 13:07 lhannest

I guess this is related to https://github.com/gitpython-developers/GitPython/issues/852#issuecomment-472553235

If I add R=True to the line:

pprint(r.active_branch.commit.diff('master', create_patch=True, R=True)[0].diff.decode('utf-8').split('\n')) 

Then I seem to get the right results. But this still seems like a bug! Will this be fixed someday?

I'm worried that if I add R=True now, then someday when this is fixed my program will silently stop working correctly.

lhannest avatar Jul 13 '21 13:07 lhannest

Apparently this was believed to be fixed here: 14d7034adc2698c1e7dd13570c23d217c753e932. Maybe in your particular case it still is inverted? Or is the version you are using not the most recent one?

Thanks to a particularly occluded API GitPython can be really confusing, making it hard to understand what's diffed against what. Thus I would not be surprised if there are more issues slumbering there or the fix above isn't correct in all cases.

If you figure it out a PR would be welcome.

Byron avatar Jul 13 '21 23:07 Byron

This is still inverted in my testing -- below reproduces this committing a new file foo.txt, and the diff shows this as a_path (while b_path is None) despite the documentation saying "a_path is None" for the "New File" case

/tmp$ mkdir reproduce

/tmp$ cd reproduce/

/tmp/reproduce$ git init .
Initialized empty Git repository in /tmp/reproduce/.git/

/tmp/reproduce$ echo hello > README.md

/tmp/reproduce$ git add README.md

/tmp/reproduce$ git commit -am "initial commit"
[main (root-commit) 5044049] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

/tmp/reproduce$ echo foo > foo.txt

/tmp/reproduce$ git add foo.txt 

/tmp/reproduce$ git commit -am "add foo"
[main a0b75c6] add foo
 1 file changed, 1 insertion(+)
 create mode 100644 foo.txt

/tmp/reproduce$ python3.10 -m venv venv

/tmp/reproduce$ source venv/bin/activate

(venv) /tmp/reproduce$ pip install GitPython==3.1.41
Collecting GitPython==3.1.41
  Using cached GitPython-3.1.41-py3-none-any.whl (196 kB)
Collecting gitdb<5,>=4.0.1
  Using cached gitdb-4.0.11-py3-none-any.whl (62 kB)
Collecting smmap<6,>=3.0.1
  Using cached smmap-5.0.1-py3-none-any.whl (24 kB)
Installing collected packages: smmap, gitdb, GitPython
Successfully installed GitPython-3.1.41 gitdb-4.0.11 smmap-5.0.1

[notice] A new release of pip available: 22.3.1 -> 24.0
[notice] To update, run: pip install --upgrade pip

(venv) /tmp/reproduce$ python
Python 3.10.9 (main, Aug 18 2023, 10:33:31) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import git
>>> rv = git.Repo('.').head.commit.diff('HEAD~1', create_patch=True)
>>> for i in rv:
...   print('a_path', i.a_path)
...   print('b_path', i.b_path)
...   print()
... 
a_path foo.txt
b_path None

>>> 
(venv) /tmp/reproduce$ git log --stat
commit a0b75c63d805e21fb5b5df64f18baa76e43cb90b (HEAD -> main)
Author: jdimatteo <[email protected]>
Date:   Mon Feb 12 14:27:23 2024 -0700

    add foo

 foo.txt | 1 +
 1 file changed, 1 insertion(+)

commit 5044049c44e6c89ef79330703255fd3372ae32b7
Author: jdimatteo <[email protected]>
Date:   Mon Feb 12 14:26:51 2024 -0700

    initial commit

 README.md | 1 +
 1 file changed, 1 insertion(+)
(venv) /tmp/reproduce$ git diff-tree a0b75c63d805e21fb5b5df64f18baa76e43cb90b HEAD~1 -r --abbrev=40 --full-index -M -p --no-color
diff --git a/foo.txt b/foo.txt
deleted file mode 100644
index 257cc5642cb1a054f08cc83f2d943e56fd3ebe99..0000000000000000000000000000000000000000
--- a/foo.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo
(venv) /tmp/reproduce$ 

jdimatteo avatar Feb 12 '24 21:02 jdimatteo