I want to see a historical version of a given file: .zshrc
This will show me all commits where this file changed:
git log .zshrc
...
...
Now for given commit, I want to see the whole file. But the following actually does not show the file. It shows a diff between that commit and previous commit:
git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4 .zshrc
This does not work at all:
git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:.zshrc
fatal: Path 'test/.zshrc' exists, but not '.zshrc'.
Did you mean 'bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:test/.zshrc' aka '2c0989168a2fbbaaa6ef31dc50616dd236c8b5d4:./.zshrc'?
And finally, this behaves as expected. It will "cat" given version of file
git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:./.zshrc
But why is the behavior of git show so illogical and confusing?
Why is git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4 .zshrc different from git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:.zshrc
Also, why does git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:.zshrc not work, even though git clearly understand, and suggests, I should use: bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:test/.zshrc ?
Why can't I use relative path :.zshrc and instead must use completely unnecessary construct :./.zshrc ?
Because you're running
git show <thing>, and in the first case<thing>is just a commit. The filename acts as a filter on the commit diff, so you only see the diff for that particular file.In the second case (
<commit>:<path>),<thing>is a file in a commit, so you get that instead.I can't reproduce that particular problem (with git 2.31.1). If I have a file named
.zshrcat the top level of the repository, I can rungit show <commit>:.zshrcand git shows me the file contents.Some of these commands have been around for a long time and people have grown to rely on the behavior, confusing though it may be. There have been efforts in recent years to offer more modern alternatives to some commands (see e.g.
git switch, which tries to provide a more obvious interface for some actions that were previously part ofgit checkout. I don't know ifgit showhas been the target of this sort of work.