gitgit-diffgit-worktree

git diff --cached: unknown option `cached'


Within a Git worktree directory within a Docker container, I'm getting the error error: unknown option `cached' when running git diff --cached.

Git is on version 2.32.0 which clearly states it should exist.

When switching back to the main repository and mounting it in the container, the command works fine.

What's going on here?


Solution

  • So the problem was two-pronged.

    git diff is designed to work even outside Git repository trees, unlike most other Git commands. It achieves this by changing the CLI interface depending on whether or not it's detected a Git repository.

    This change-CLI-interface logic seems to be "if the current repository is not valid, then use non-Git CLI options".

    In our case, we were bind-mounting the current directory into a Docker container. If the current directory was a Git worktree, then the .git node was a regular file with the path to the main repository within it. However, that repository's path did not exist within the container, so Git determined that the current directory is not a "valid repository" and thus switched out the git diff options from under our feet.

    Further, Git's detection doesn't seem to want to error on "found .git but it's not valid" and silently ignores such cases, and according to a user in the IRC channel there is no way to force git diff to expect the current directory to be a Git repository and error if it's invalid.

    There are a few workarounds, but most are hacks - I'll leave that as an exercise to the reader.


    tl;dr If .git is a file (as it is in a worktree) and the directory pointed to by that file doesn't exist, git silently treats the current directory as a non-repository, which changes the CLI options for git diff due to it being designed to support non-repositories (unlike most other git commands).