commit.diff with parent vs NULL_TREE not coherent
After adding a new file I made a diff vs NULL_TREE, I have the expected behaviour change_type == 'A'. When making the diff of the same commit vs the parent I get change_type == 'D', I think the sha keys are not correctly passed.
Perhaps I'm wrong and I missed something... If you confirm the issue, I can fix it!
Here is an example to reproduce the issue:
test.py
import git
repo = git.Repo('.')
print('Diff with NULL_TREE')
diffs = repo.head.commit.diff(git.NULL_TREE)
for diff in diffs:
print(diff)
print('type', diff.change_type)
print()
print('-' * 10)
print()
print('*' * 10)
print()
print('Diff with parent')
diffs = repo.head.commit.diff(repo.head.commit.parents[0])
for diff in diffs:
print(diff)
print('type', diff.change_type)
print()
print('-' * 10)
test.sh
#!/bin/sh
mkdir test
cd test
git init
touch A
git add .
git commit -m "add A"
touch B
git add .
git commit -m "add B"
python ../test.py
cd ..
rm -rf test
Here is the result
tmp $ sh test.sh
Initialized empty Git repository in /tmp/test/.git/
[master (root-commit) 779b71f] add A
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 A
[master d27e0b1] add B
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 B
Diff with NULL_TREE
B
=======================================================
lhs: None
rhs: 100644 | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
file added in rhs
('type', u'A')
()
----------
**********
Diff with parent
B
=======================================================
lhs: 100644 | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
rhs: None
file deleted in rhs
('type', u'D')
()
----------
Thanks for making it so easy to follow along! A great issue! I agree that the behavior seems to be inconsistent, even though I believe the behavior seen with the parent is correct. It answers the question of 'what do you have to do to get from state A to state B?', which is delete the previously added file.
Thus I believe some order is wrong when using the special 'NULL_TREE', which is what I would fix. I would very much welcome a PR which accomplishes this.
@Byron indeed, this is not a bug. To get the correct DIFF, one has always to do: git diff PARENT -> CURRENT
so NULL_TREE -> CURRENT.
The correct solution is:
import git
repo = git.Repo('.')
print('Diff with NULL_TREE')
# this is the null tree, not sure why git.NULL_TREE doesn't work
parent = repo.tree('4b825dc642cb6eb9a060e54bf8d69288fbee4904')
diffs = parent.diff(repo.head.commit.tree)
for diff in diffs:
print(diff)
print('type', diff.change_type)
print()
print('-' * 10)
print()
print('*' * 10)
print()
print('Diff with parent')
## IMPORTANT: this is inverted, parents vs head commit
diffs = repo.head.commit.parents[0].diff(repo.head.commit)
for diff in diffs:
print(diff)
print('type', diff.change_type)
print()
print('-' * 10)
and the output is:
Initialized empty Git repository in /private/tmp/temp/test/.git/
[master (root-commit) 4bac140] add A
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 A
[master a4ceb50] add B
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 B
Diff with NULL_TREE
A
=======================================================
lhs: None
rhs: 100644 | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
file added in rhs
type A
----------
B
=======================================================
lhs: None
rhs: 100644 | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
file added in rhs
type A
----------
**********
Diff with parent
B
=======================================================
lhs: None
rhs: 100644 | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
file added in rhs
type A
----------