{"thread":{"id":"63016","subject":"gripe: bash completion broken for 'diff' from outside working tree","startedAt":"2025-02-27T17:46:41Z","lastAt":"2025-02-27T17:46:41Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"513170","messageId":"xmqqldtr8em9.fsf@gitster.g","threadId":"63016","inReplyTo":null,"subject":"gripe: bash completion broken for 'diff' from outside working tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-02-27T17:46:38Z","receivedAt":"2025-02-27T17:46:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I chose to CC those who have commits in our tree in the last year\namong those who touched contrib/completion/git-completion.bash in\nthe past 3 years, hoping that they are much much more clueful than\nI am in this script.\n\nLet's say I have a checkout of our source files in $HOME/w/git.git\nand have a few files modified:\n\n    $ cd $HOME/w/git.git\n    $ git diff --name-status\n    M       COPYING\n    M       Makefile\n\nGoing one level up, and trying to run various common commands shows\ndiffering level of completion support.\n\n    $ cd $HOME/w/\n    $ ls git.git/CO<TAB>\n    CODE_OF_CONDUCT.md  COPYING\n    $ git -C git.git add CO<TAB>\t# completes to 'COPYING'\n\nThis completes to COPYING even though CO is *not* a unique prefix\n(as seen in the completion of \"ls\"), simply because the other\ntracked file has no modification and there is no point in adding it.\nThe completion of \"add\" seems even nicer.  See.\n\n    $ >git.git/CONTRIBUTING\n    $ git -C git.git add CO<TAB>\n    CONTRIBUTING  COPYING\n\nIt notices that an untracked file CONTRIBUTING could be added, so\nincludes it in the candidates.  I guess __git_complete_index_file\nthat is called at the end of _git_add is what has the whole smart\nto do this?\n\n\"git status\" is equally nice.\n\n    $ git -C git.git status CO<TAB>\n    CODE_OF_CONDUCT.md  CONTRIBUTING   COPYING\n\nAnd It is benefiting from the same __git_complete_index_file at the\nend of _git_status, I think.\n\nBut \"git diff\" is not.  Among these three commands, this is the one\nI most often use (so expect to behave the best).\n\n    $ git -C git.git diff CO<TAB>\t# nothing.\n\nA cursory look of __git_complete_revlist_file tells me that it does\nnot do anything special on the pathspec on the command line.  It\ncalls __git_complete_refs so it may be aware of other branches, to\nwit:\n\n    $ git -C git.git diff ne<TAB>\t# completes to 'next'.\n\nbut does not care anything about the files.\n\nWhen you are in the working tree, I think it is helped by the \"list\nof files relative to the cwd\" default completion behaviour kicking\nin (i.e. I get the same completion as \"ls CO<TAB>\").\n\n    $ cd git.git && git diff CO<TAB>\n    CODE_OF_CONDUCT.md  CONTRIBUTING   COPYING\n\nI think this behaviour is serviceable; some may argue that omitting\nCONTRIBUTING (which is not tracked yet) and CODE_OF_CONDUCT.md\n(which has no changes) and directly completing to COPYING would be\nnicer, but the users who want to run \"git diff\" want to know which\npaths have modifications, which in turn means they do not know that\nCODE_OF_CONDUCT.md has no changes, and may not even know that they\nhave not yet added CONTRIBUTING yet.  So I am inclined to say that\nit is perfectly OK not to omit them.  On the other hand, if it is\neasier to find paths out of the index, I am also fine if they are\nomitted.\n\nBut outside the working tree with the \"git -C <go-there> diff\",\nbehaviour is even worse than the behaviour we get from the falling\nback to the default.  It is completly broken, since the directory\nlisting the default behaviour chooses from is from the current\ndirectory and not from the working tree specified by the \"-C\"\noption.\n\nI find this frustration at least twice a day, every day, when I have\ndo \"git -C Meta diff whats-cooking.txt\".\n\nHelp?\n"}]}