To get a definitive list of what's changed (but not yet staged):
# Gives a list of the differing objects
diff_list = repo.head.commit.diff()
for diff in diff_list:
print(diff.change_type) # Gives the change type. eg. 'A': added, 'M': modified etc.
# Returns true if it is a new file
print(diff.new_file)
# Print the old file path
print(diff.a_path)
# Print the new file path. If the filename (or path) was changed it will differ
print(diff.b_path)
# Too many options to show. This gives a comprehensive description of what is available
help(diff_list[0])
I found the diff object to be very useful and should give any info you require.
For staged items, use repo.index
From my testing, I found that the previous answer gave a diff output the wrong way round (ie. added files would show up as deleted).
The other option is repo.git.diff(...) which I found less useful as it gives long text strings for output rather than objects that can be easily parsed.