threads / bug / 62086

[bug?] git diff --cached in a non-git directory

Subject: [bug?] git diff --cached in a non-git directory

## tl;dr

6 messages between Sep 9, 2024 and Sep 9, 2024.

replies: 5people: 3as markdown or json

Okke Timm· Sep 9, 2024, 14:26 UTC · lore

Thank you for filling out a Git bug report! Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue) I changed into a non-git directory. Then I called git with 'git diff --cached', which produced this error:

error: unknown option `cached' usage: git diff --no-index [<options>] <path> <path> [...]

What did you expect to happen? (Expected behavior) A helfpul error message.

What happened instead? (Actual behavior) An unhelpful error message saying that cached is an unknown option.

What's different between what you expected and what actually happened? Me being confused why git suddenly forgot that `git diff --cached` is an allowed option.

Anything else you want to add: Please fix and thank you for this great tool!

Please review the rest of the bug report below. You can delete any lines you don't wish to share.

[System Info] git version: git version 2.46.0 cpu: arm64 no commit associated with this build sizeof-long: 8 sizeof-size_t: 8 shell-path: /bin/sh feature: fsmonitor--daemon libcurl: 8.4.0 zlib: 1.2.12 uname: Darwin 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:21 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8103 arm64 compiler info: clang: 15.0.0 (clang-1500.3.9.4) libc info: no libc information available $SHELL (typically, interactive shell): /opt/homebrew/bin/bash

[Enabled Hooks] not run from a git repository - no hooks to show

rsbecker@nexbridge.com· Sep 9, 2024, 15:37 UTC · re: Okke Timm · lore

RE: [bug?] git diff --cached in a non-git directory

On September 9, 2024 10:26 AM, Okke Timm wrote:
Show 10 quoted lines
>What did you do before the bug happened? (Steps to reproduce your issue) I
>changed into a non-git directory.
>Then I called git with 'git diff --cached', which produced this error:
>
>error: unknown option `cached'
>usage: git diff --no-index [<options>] <path> <path> [...]
>
>What did you expect to happen? (Expected behavior) A helfpul error message.
>
>What happened instead? (Actual behavior) An unhelpful error message saying
that
>cached is an unknown option.
>
>What's different between what you expected and what actually happened?
>Me being confused why git suddenly forgot that `git diff --cached` is an
allowed
Show 23 quoted lines
>option.
>
>Anything else you want to add:
>Please fix and thank you for this great tool!
>
>Please review the rest of the bug report below.
>You can delete any lines you don't wish to share.
>
>
>[System Info]
>git version:
>git version 2.46.0
>cpu: arm64
>no commit associated with this build
>sizeof-long: 8
>sizeof-size_t: 8
>shell-path: /bin/sh
>feature: fsmonitor--daemon
>libcurl: 8.4.0
>zlib: 1.2.12
>uname: Darwin 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:21 PDT
>2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8103 arm64 compiler info:
>clang: 15.0.0 (clang-1500.3.9.4) libc info: no libc information available
$SHELL
Show 5 quoted lines
>(typically, interactive shell): /opt/homebrew/bin/bash
>
>
>[Enabled Hooks]
>not run from a git repository - no hooks to show

Because you are not in a git repository clone, the --cached option has no meaning. It refers to the staging area only, so when not in a clone, git does not consider --cached as supported because there is no connection between an external directory and an internal. If you want to perform a diff from cached vs. external, run the git diff from inside the clone referencing the internal and external file after --.

Okke Timm· Sep 9, 2024, 15:51 UTC · re: rsbecker@nexbridge.com · lore

Re: [bug?] git diff --cached in a non-git directory

Show 55 quoted lines
> Am 09.09.2024 um 17:37 schrieb <rsbecker@nexbridge.com> <rsbecker@nexbridge.com>:
> 
> On September 9, 2024 10:26 AM, Okke Timm wrote:
>> What did you do before the bug happened? (Steps to reproduce your issue) I
>> changed into a non-git directory.
>> Then I called git with 'git diff --cached', which produced this error:
>> 
>> error: unknown option `cached'
>> usage: git diff --no-index [<options>] <path> <path> [...]
>> 
>> What did you expect to happen? (Expected behavior) A helfpul error message.
>> 
>> What happened instead? (Actual behavior) An unhelpful error message saying
> that
>> cached is an unknown option.
>> 
>> What's different between what you expected and what actually happened?
>> Me being confused why git suddenly forgot that `git diff --cached` is an
> allowed
>> option.
>> 
>> Anything else you want to add:
>> Please fix and thank you for this great tool!
>> 
>> Please review the rest of the bug report below.
>> You can delete any lines you don't wish to share.
>> 
>> 
>> [System Info]
>> git version:
>> git version 2.46.0
>> cpu: arm64
>> no commit associated with this build
>> sizeof-long: 8
>> sizeof-size_t: 8
>> shell-path: /bin/sh
>> feature: fsmonitor--daemon
>> libcurl: 8.4.0
>> zlib: 1.2.12
>> uname: Darwin 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:21 PDT
>> 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8103 arm64 compiler info:
>> clang: 15.0.0 (clang-1500.3.9.4) libc info: no libc information available
> $SHELL
>> (typically, interactive shell): /opt/homebrew/bin/bash
>> 
>> 
>> [Enabled Hooks]
>> not run from a git repository - no hooks to show
> 
> Because you are not in a git repository clone, the --cached option has no
> meaning. It refers to the staging area only, so when not in a clone, git
> does not consider --cached as supported because there is no connection
> between an external directory and an internal. If you want to perform a diff
> from cached vs. external, run the git diff from inside the clone referencing
> the internal and external file after —.

i criticized the error message in my bug report. If it would tell me that this is not a git repository, I’d be happy. But telling me that `—cached` is not an allowed option for `git diff` is very unhelpful and confusing.

The reason why I reported this is that git gets run in tools these days and not all check for the presence of a git repository correctly all the time. Also sometimes permission issue hide the `.git` directory for some reason (reported for Windows and VSCode).

Junio C Hamano· Sep 9, 2024, 18:40 UTC · re: rsbecker@nexbridge.com · lore

Re: [bug?] git diff --cached in a non-git directory

<rsbecker@nexbridge.com> writes:
Show 5 quoted lines
>>error: unknown option `cached'
>>usage: git diff --no-index [<options>] <path> <path> [...]
> ...
> Because you are not in a git repository clone, the --cached option has no
> meaning.

Yes. "git diff" unfortunately has a mode where a limited subset of its features is available and that is called the "--no-index" mode.

Because the command is capable of working outside a repository, "You are not in a repository" is a not a good error message in this situation, either. It is not that you stepped outside a repository that is your error. It is not that you used "--cached" that is your error, either. You used "--cached" outside a repository, that is where your error is.

A patch to improve the error messages in such a situation is certainly welcome.

Thanks.
rsbecker@nexbridge.com· Sep 9, 2024, 19:28 UTC · re: Junio C Hamano · lore

RE: [bug?] git diff --cached in a non-git directory

On September 9, 2024 2:40 PM, Junio C Hamano wrote:
Show 9 quoted lines
><rsbecker@nexbridge.com> writes:
>
>>>error: unknown option `cached'
>>>usage: git diff --no-index [<options>] <path> <path> [...]
>> ...
>> Because you are not in a git repository clone, the --cached option has
>> no meaning.
>
>Yes.  "git diff" unfortunately has a mode where a limited subset of its
features is
>available and that is called the "--no-index" mode.
>
>Because the command is capable of working outside a repository, "You are
not in a
>repository" is a not a good error message in this situation, either.  It is
not that you
>stepped outside a repository that is your error.  It is not that you used
"--cached"
>that is your error, either.  You used "--cached" outside a repository, that
is where
>your error is.
>
>A patch to improve the error messages in such a situation is certainly
welcome.
Glad to. Can you point me at where this is generated?
Junio C Hamano· Sep 9, 2024, 20:26 UTC · re: Junio C Hamano · lore

Re: [bug?] git diff --cached in a non-git directory

Junio C Hamano <gitster@pobox.com> writes:
Show 20 quoted lines
> <rsbecker@nexbridge.com> writes:
>
>>>error: unknown option `cached'
>>>usage: git diff --no-index [<options>] <path> <path> [...]
>> ...
>> Because you are not in a git repository clone, the --cached option has no
>> meaning.
>
> Yes.  "git diff" unfortunately has a mode where a limited subset of
> its features is available and that is called the "--no-index" mode.
>
> Because the command is capable of working outside a repository, "You
> are not in a repository" is a not a good error message in this
> situation, either.  It is not that you stepped outside a repository
> that is your error.  It is not that you used "--cached" that is your
> error, either.  You used "--cached" outside a repository, that is
> where your error is.
>
> A patch to improve the error messages in such a situation is
> certainly welcome.
Having said that, there is already a warning() close by.
	argc = parse_options(argc, argv, revs->prefix, options,
			     diff_no_index_usage, 0);
	if (argc != 2) {
		if (implicit_no_index)
			warning(_("Not a git repository. Use --no-index to "
				  "compare two paths outside a working tree"));
		usage_with_options(diff_no_index_usage, options);
	}
and this gives

$ cd / && git diff foo 2>&1 | grep -e error: -e fatal: -e warning: warning: Not a git repository. Use --no-index to compare two paths outside a working tree

a relevant warning.

But this is a bit too short to be effective for all failure modes. parse_options() would die if it sees an invalid option. For that, I suspect that we'd need to pass the usage string conditionally, i.e.

    argc = parse_options(argc, argv, revs->prefix, options,
			 implicit_no_index 
			 ? diff_no_index_usage_with_non_repo_warning
			 : diff_no_index_usage, 0);
with
    static const char * const diff_no_index_usage_with_non_repo_warning[] = {
            N_("git diff --no-index [<options>] <path> <path>"),
            N_("Not in a git repository; some options may not make sense"),
            NULL,
    };

near where diff_no_index_usage[] is defined, or something silly like that.

← back to recent threads