Reputation: 46422
I'm using
git diff mycommit
for comparing my working tree with mycommit
, but it seems to ignore files not present in the current index. You can reproduce it as follows:
git init
echo A > A.txt; git add .; git commit -m A; git branch A
echo B > B.txt; git add .; git commit -m B; git branch B
git reset --hard A
echo BB > B.txt
git diff B
The output (as of git version 1.7.3.3) is empty. Using --diff-filter=ACDMRTUXB
shows "deleted file" which is wrong as well, since the file B.txt
exists both in the working tree and in commit B
. IMHO, the file should be shown as modified. Surprisingly, it works after adding the file to the index, although it's not the index what gets compared. How can I get the right diff without it?
Upvotes: 53
Views: 31014
Reputation: 46422
manojlds wrote in his answer
Basically, diff does not take into account untracked files. That is why you see that the file is deleted, because the diff is same as git diff B A
This is true and worth upvoting, but it didn't satisfy me, as it says neither "how can I compare it" nor gave the deeper reason behind it. I still thought it was a bug, so I asked at the git forum and got a long answer by somebody who surely knows. The important parts for me are:
The definition of paths in the working tree in these sentences is not "all files on the filesystem", or "all files on the filesystem, filtered with the ignore mechanism". It is "all files on the filesystem that are in the index" ...
and
...that will give a clean semantics to "git diff HEAD": what change would I be recording if I said "git commit -a" at this point?
Upvotes: 8
Reputation: 150615
A simple graphic might be of help:
So there are three types of diff you can ask for:
git diff --cached
This is the difference between what is in the index and the last commit. It shows you that changes that will be in the next commit.
git diff
This shows the difference in between the index and the working tree. These are the changes that you have made to files since you last added them to the index. This is why I wasn’t getting any results. I had no changes between the index and the working tree.
git diff HEAD
This shows the difference between the files in the working tree and the last commit. There is a gotcha here: if you've made changes, added them to the index, and then backed out these changes in the working tree, you’ll get no results for git diff HEAD
(because there is no difference) but you will get output for git diff --cached
because there are still changes in the index.
And if you want to compare it against previous commits:
This just compares against the previous commits, but you can replace HEAD~
with any other reference to a commit.
Upvotes: 114
Reputation: 301147
The question is: I have added some file in my working tree, that exists in the other commit. Why is git diff <commit>
not showing me the difference between the file content that exists in my working tree and the content of the file that is in the other commit.
This is because the new file that you added is untracked and hence, well, git doesn't track it.
Try git diff HEAD
you won't see that you have added B.txt in your working tree.
Basically, diff does not take into account untracked files. That is why you see that the file is deleted, because the diff is same as git diff B A
Now, if you were to add the file, you will see the expected result, because git is tracking it now.
Say, you committed the file and then modify the content in the working tree:
Now, git diff HEAD
will show the difference between working tree and HEAD, showing the change you have done in your working tree on tracked files. Same with git diff B
Upvotes: 12