Suppose there is a commit C
which have a single parent commit P
.
Let's say that TC
and TP
are the corresponding tree objects.
Why git diff P C
is not always equal to git diff-tree TP TC -p
?
According to a git protocol specification, each commit object is pointing on only one tree objects. Different commit objects could use the same tree object, but not vice-versa.
For instance, let's take this public repo : [email protected]:dmalikov/dotfiles.git
.
Here is some commit object:
>> git cat-file -p 67019a5daef556ef5c3e2bea4f425d9a5044bc44
tree 1e9c97a5f0da406f4e74d02897393606e902408d
parent 435f7e6a78d5c5797c0997c1ad73f11d38d89d7a
author Dmitry Malikov <[email protected]> 1374867081 +0400
committer Dmitry Malikov <[email protected]> 1374867754 +0400
Vifm: cue2tracks mapping
Here is parent commit:
>> git cat-file -p 435f7e6a78d5c5797c0997c1ad73f11d38d89d7a
tree eb00b6ee310bda76280c515c5bd698e3247d3416
parent 00a1c0f55cd6c9eaa6621b0c7799c56d6bf76df5
author Dmitry Malikov <[email protected]> 1374831285 +0400
committer Dmitry Malikov <[email protected]> 1374834097 +0400
Vim: correct tabs for js and eruby
Commits' diff:
>> git diff 435f7e6a78d5c5797c0997c1ad73f11d38d89d7a 67019a5daef556ef5c3e2bea4f425d9a5044bc44 --stat
configs/vifm/vifmrc | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
Trees' diff:
>> git diff-tree eb00b6ee310bda76280c515c5bd698e3247d3416 1e9c97a5f0da406f4e74d02897393606e902408d --stat
configs/vifm/vifmrc | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
Unfortunately they're are different. Let's take a closer look again
>> git diff 435f7e6a78d5c5797c0997c1ad73f11d38d89d7a 67019a5daef556ef5c3e2bea4f425d9a5044bc44
diff --git a/configs/vifm/vifmrc b/configs/vifm/vifmrc
index 95b540d..a41bd54 100644
--- a/configs/vifm/vifmrc
+++ b/configs/vifm/vifmrc
@@ -167,14 +167,15 @@ filetype *.ssh FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR
set vifminfo=bookmarks
" Sample mappings
+nmap ,c :!cue2tracks -RF<CR>
-nmap s :shell<cr>
-nmap S :sort<cr>
-nmap w :view<cr>
-nmap o :!gvim --remote-tab-silent %f<cr>
-nmap O :!gvim %f<cr>
-" open file in the background using its default program
-nmap gb :file &<cr>l
+" nmap s :shell<cr>
+" nmap S :sort<cr>
+" nmap w :view<cr>
+" nmap o :!gvim --remote-tab-silent %f<cr>
+" nmap O :!gvim %f<cr>
+" " open file in the background using its default program
+" nmap gb :file &<cr>l
nmap <f3> :!less %f<cr>
nmap <f4> :edit<cr>
And a trees' analogue:
>> git diff-tree eb00b6ee310bda76280c515c5bd698e3247d3416 1e9c97a5f0da406f4e74d02897393606e902408d -p
diff --git a/configs/vifm/vifmrc b/configs/vifm/vifmrc
index 95b540d..a41bd54 100644
--- a/configs/vifm/vifmrc
+++ b/configs/vifm/vifmrc
@@ -167,14 +167,15 @@ filetype *.ssh FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR
set vifminfo=bookmarks
" Sample mappings
-
-nmap s :shell<cr>
-nmap S :sort<cr>
-nmap w :view<cr>
-nmap o :!gvim --remote-tab-silent %f<cr>
-nmap O :!gvim %f<cr>
-" open file in the background using its default program
-nmap gb :file &<cr>l
+nmap ,c :!cue2tracks -RF<CR>
+
+" nmap s :shell<cr>
+" nmap S :sort<cr>
+" nmap w :view<cr>
+" nmap o :!gvim --remote-tab-silent %f<cr>
+" nmap O :!gvim %f<cr>
+" " open file in the background using its default program
+" nmap gb :file &<cr>l
nmap <f3> :!less %f<cr>
nmap <f4> :edit<cr>
So what we have here is some kind of different difference strategies used for calculating diff.
For a repository mentioned above there are 10 commits with the issue out of 735 commits.
What is the difference between diff
and diff-tree
commands?
Good news 8 years later: the output in both cases is now identical, at least with Git version 2.40.1.
I was expected differences in cases of merge commits, but not with a single parent commit. That bug must have been fixed I guess.