Revert "completions/git: cache subcommand computation"

Commit ad9b4290e optimized git completions by adding a completion that would
run on every completion request, which allows to precompute data used by
other completion entries. Unfortunately, the completion entry is not run
when the commandline contains a flag like `git -C`. If we didn't
already load git.fish, we'd error. Additionally, we got false positive
completions for `git diff -c`.

So this hack was a very bad idea. We should optimize in another way.

(cherry picked from commit fee5a9125a)
This commit is contained in:
Johannes Altmanninger 2022-06-26 22:41:44 +02:00
parent 98bf01568d
commit a6898467ab
3 changed files with 49 additions and 33 deletions

View File

@ -1,3 +1,12 @@
fish 3.5.1 (released ???)
====================================
This release of fish fixes the following problems identified in fish 3.5.0:
- A change in the completion script for ``git`` caused problems when completing ``git blame`` or ``git -C``, which has been fixed (:issue:`9053`).
--------------
fish 3.5.0 (released June 16, 2022) fish 3.5.0 (released June 16, 2022)
=================================== ===================================

View File

@ -563,6 +563,25 @@ function __fish_git_ranges
end end
end end
function __fish_git_needs_command
# Figure out if the current invocation already has a command.
set -l cmd (commandline -opc)
set -e cmd[1]
argparse -s (__fish_git_global_optspecs) -- $cmd 2>/dev/null
or return 0
# These flags function as commands, effectively.
set -q _flag_version; and return 1
set -q _flag_html_path; and return 1
set -q _flag_man_path; and return 1
set -q _flag_info_path; and return 1
if set -q argv[1]
# Also print the command, so this can be used to figure out what it is.
echo $argv[1]
return 1
end
return 0
end
function __fish_git_config_keys function __fish_git_config_keys
# Print already defined config values first # Print already defined config values first
# Config keys may span multiple lines, so parse using null char # Config keys may span multiple lines, so parse using null char
@ -614,12 +633,19 @@ git config -z --get-regexp 'alias\..*' | while read -lz alias cmdline
set -g __fish_git_alias_$alias $command $cmdline set -g __fish_git_alias_$alias $command $cmdline
end end
function __fish_git_needs_command
$__fish_git_needs_command
end
function __fish_git_using_command function __fish_git_using_command
contains $__fish_git_subcommand $argv set -l cmd (__fish_git_needs_command)
test -z "$cmd"
and return 1
contains -- $cmd $argv
and return 0
# Check aliases.
set -l varname __fish_git_alias_(string escape --style=var -- $cmd)
set -q $varname
and contains -- $$varname[1][1] $argv
and return 0
return 1
end end
function __fish_git_contains_opt function __fish_git_contains_opt
@ -630,8 +656,10 @@ function __fish_git_contains_opt
# Now check the alias # Now check the alias
argparse s= -- $argv argparse s= -- $argv
if set -q __fish_git_expanded_alias[1] set -l cmd (__fish_git_needs_command)
echo -- $__fish_git_expanded_alias | read -lat toks set -l varname __fish_git_alias_(string escape --style=var -- $cmd)
if set -q $varname
echo -- $$varname | read -lat toks
set toks (string replace -r '(-.*)=.*' '' -- $toks) set toks (string replace -r '(-.*)=.*' '' -- $toks)
for i in $argv for i in $argv
if contains -- --$i $toks if contains -- --$i $toks
@ -2267,29 +2295,3 @@ for file in $PATH/git-*
complete -c git -f -n "__fish_git_using_command $subcommand" -a "(__fish_git_complete_custom_command $subcommand)" complete -c git -f -n "__fish_git_using_command $subcommand" -a "(__fish_git_complete_custom_command $subcommand)"
set -a __fish_git_custom_commands_completion $subcommand set -a __fish_git_custom_commands_completion $subcommand
end end
complete -c git -f -a '(
set -g __fish_git_needs_command true
set -g __fish_git_subcommand ""
set -g __fish_git_expanded_alias
set -l cmd (commandline -opc)
set -e cmd[1]
argparse -s (__fish_git_global_optspecs) -- $cmd 2>/dev/null
or return
if set -q argv[1] || set -q _flag_version || set -q _flag_html_path || set -q _flag_man_path || set -q _flag_info_path
set __fish_git_needs_command false
end
if set -q argv[1]
set -l subcommand $argv[1]
# TODO Expand recursive aliases.
set -l varname __fish_git_alias_(string escape --style=var -- $subcommand)
if set -q $varname
set -g __fish_git_expanded_alias $$varname
set subcommand $__fish_git_expanded_alias[1]
end
set -g __fish_git_subcommand "$subcommand"
end
)'

View File

@ -3,6 +3,8 @@
# e.g. the fish_git_prompt variable handlers test `status is-interactive`. # e.g. the fish_git_prompt variable handlers test `status is-interactive`.
#REQUIRES: command -v git #REQUIRES: command -v git
set -g fish (status fish-path)
# Tests run from git (e.g. git rebase --exec 'ninja test'...) inherit a weird git environment. # Tests run from git (e.g. git rebase --exec 'ninja test'...) inherit a weird git environment.
# Ensure that no git environment variables are inherited. # Ensure that no git environment variables are inherited.
for varname in (set -x | string match 'GIT_*' | string replace -r ' .*' '') for varname in (set -x | string match 'GIT_*' | string replace -r ' .*' '')
@ -134,3 +136,6 @@ test "$(complete -C'git re ')" = "$(complete -C'git restore --staged ')"
or begin or begin
echo -- Oops re completes unlike restore --staged echo -- Oops re completes unlike restore --staged
end end
$fish -c 'complete -C "git -C ./.gi"'
# CHECK: ./.git/ Directory