hitchhiker
hitchhiker

Reputation: 1319

Why git diff doesn't show information on a specific commit and file?

I made changes to file source.json by removing a line from it. I committed the change (other files were changed as well). I then made another commit.

Now I want to see the changes I made to source.json using git diff.

What I do is:

git diff HEAD^^ -- path/to/source.json

I don't get any output though (the command's exit status is 0). If I enter git diff HEAD^^ I do see the change source.json along with all other changed files.

This is the output of git diff-tree --no-commit-id --name-only -r HEAD^:

path/to/AboutUs.js
path/to/Contact.js
path/to/source.json

This is the output of git diff HEAD^^:

diff --git a/path/to/source.json b/path/to/source.json
index 3ba32e950..d86eb9c25 100644
--- a/path/to/source.json
+++ b/path/to/source.json
@@ -565,7 +565,6 @@
-  "someContent": "someContent",
   "someContent2": "someContent2",

Is there anything I'm missing?

Upvotes: 1

Views: 929

Answers (1)

torek
torek

Reputation: 489678

While git diff does allow pathspecs to limit its output to files matching the pathspec, what is sometimes a bit surprising is that these pathspecs are relative to the current position within the work-tree.

In other words, if:

git diff-tree --no-commit-id --name-only -r HEAD^

produces:

path/to/AboutUs.js
path/to/Contact.js
path/to/source.json

and you are at the top level of your work-tree but then do:

cd path/to

you will need to use:

git diff HEAD^^ -- source.json

as the last argument effectively means ./source.json.

Alternatively, after:

git rev-parse --show-cdup

prints ../.. you can do:

git -C ../.. diff HEAD^^ -- path/to/source.json

as the -C moves that one git diff command temporarily up two levels. (I've used this general pattern in scripts and aliases, e.g.,

git -C "$(git rev-parse --show-cdup)" ls-files --other --exclude-standard

in a bit of shell code to detect untracked files.)


Git is not completely consistent here. If you wish to view the version of source.json that is in commit HEAD^^ while in this subdirectory, you must run:

git show HEAD^^:./source.json

as:

git show HEAD^^:filename

refers to the file named filename in the top level of the repository—even though you're still in path/to. The trick for git show in particular is that the file name supplied after the commit-specifier is not a pathspec argument. But other Git commands that do take pathspecs may in effect assume :(toplevel).

For more about pathspecs, see the gitglossary.

Upvotes: 2

Related Questions