I chose to CC those who have commits in our tree in the last year among those who touched contrib/completion/git-completion.bash in the past 3 years, hoping that they are much much more clueful than I am in this script. Let's say I have a checkout of our source files in $HOME/w/git.git and have a few files modified: $ cd $HOME/w/git.git $ git diff --name-status M COPYING M Makefile Going one level up, and trying to run various common commands shows differing level of completion support. $ cd $HOME/w/ $ ls git.git/CO<TAB> CODE_OF_CONDUCT.md COPYING $ git -C git.git add CO<TAB> # completes to 'COPYING' This completes to COPYING even though CO is *not* a unique prefix (as seen in the completion of "ls"), simply because the other tracked file has no modification and there is no point in adding it. The completion of "add" seems even nicer. See. $ >git.git/CONTRIBUTING $ git -C git.git add CO<TAB> CONTRIBUTING COPYING It notices that an untracked file CONTRIBUTING could be added, so includes it in the candidates. I guess __git_complete_index_file that is called at the end of _git_add is what has the whole smart to do this? "git status" is equally nice. $ git -C git.git status CO<TAB> CODE_OF_CONDUCT.md CONTRIBUTING COPYING And It is benefiting from the same __git_complete_index_file at the end of _git_status, I think. But "git diff" is not. Among these three commands, this is the one I most often use (so expect to behave the best). $ git -C git.git diff CO<TAB> # nothing. A cursory look of __git_complete_revlist_file tells me that it does not do anything special on the pathspec on the command line. It calls __git_complete_refs so it may be aware of other branches, to wit: $ git -C git.git diff ne<TAB> # completes to 'next'. but does not care anything about the files. When you are in the working tree, I think it is helped by the "list of files relative to the cwd" default completion behaviour kicking in (i.e. I get the same completion as "ls CO<TAB>"). $ cd git.git && git diff CO<TAB> CODE_OF_CONDUCT.md CONTRIBUTING COPYING I think this behaviour is serviceable; some may argue that omitting CONTRIBUTING (which is not tracked yet) and CODE_OF_CONDUCT.md (which has no changes) and directly completing to COPYING would be nicer, but the users who want to run "git diff" want to know which paths have modifications, which in turn means they do not know that CODE_OF_CONDUCT.md has no changes, and may not even know that they have not yet added CONTRIBUTING yet. So I am inclined to say that it is perfectly OK not to omit them. On the other hand, if it is easier to find paths out of the index, I am also fine if they are omitted. But outside the working tree with the "git -C <go-there> diff", behaviour is even worse than the behaviour we get from the falling back to the default. It is completly broken, since the directory listing the default behaviour chooses from is from the current directory and not from the working tree specified by the "-C" option. I find this frustration at least twice a day, every day, when I have do "git -C Meta diff whats-cooking.txt". Help?