From 50e595503eee3d931b61f83b4d7eb24e23b30065 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 3 Mar 2025 14:14:24 +0100 Subject: [PATCH] completions/git: fix completions for third-party git commands Before 798527d79a (completions: fix double evaluation of tokenized commandline, 2024-01-06) git-foo completions did something like set -l subcommand_args (commandline -opc) complete -C "git-foo $subcommand_args " As mentioned in 368017905e (builtin commandline: -x for expanded tokens, supplanting -o, 2024-01-06), the "-o" option is bad because it produces a weird intermediate, half-expanded state. The immediate goal of 798527d79a was to make sure we do not do any more expansion on top of this. To that end, it changed the above to "\$subcommand_args". The meaning is more or less the same[^*] but crucially, the recursive completion invocation does not see through the variable, which breaks some completions. Fix this with the same approach as in 6b5ad163d3 (Fix double expansion of tokenized command line, 2025-01-19). [^*]: It wasn't semantically correct before or after -- this was later corrected by 29f35d6cdf (completion: adopt commandline -x replacing deprecated -o, 2024-01-22)). Closes #11205 --- share/completions/git.fish | 4 ++-- tests/checks/git.fish | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/share/completions/git.fish b/share/completions/git.fish index 68ecd1268..862f3b579 100644 --- a/share/completions/git.fish +++ b/share/completions/git.fish @@ -2565,11 +2565,11 @@ complete -c git -n __fish_git_needs_command -a '(__fish_git_custom_commands)' -d function __fish_git_complete_custom_command -a subcommand set -l cmd (commandline -xpc) set -e cmd[1] # Drop "git". - set -lx subcommand_args + set -l subcommand_args if argparse -s (__fish_git_global_optspecs) -- $cmd set subcommand_args $argv[2..] # Drop the subcommand. end - complete -C "git-$subcommand \$subcommand_args "(commandline -ct) + complete -C "git-$subcommand $(string escape -- $subcommand_args) "(commandline -ct) end # source git-* commands' autocompletion file if exists diff --git a/tests/checks/git.fish b/tests/checks/git.fish index 2dae920ed..c7b13d5ae 100644 --- a/tests/checks/git.fish +++ b/tests/checks/git.fish @@ -40,12 +40,17 @@ echo "echo foo" > git-frobnicate chmod +x git-frobnicate complete -c git-frobnicate -xa 'foo bar baz' +complete -c git-frobnicate -l onto -xa 'onto1 onto2' complete -C'git frobnicate ' #CHECK: bar #CHECK: baz #CHECK: foo +complete -C'git frobnicate --onto ' +#CHECK: onto1 +#CHECK: onto2 + complete -C'git ' | grep '^add'\t # (note: actual tab character in the check here) #CHECK: add Add file contents to the staging area