[PATCH v4 5/5] completion: fix completion after 'git --option <TAB>'
From: SZEDER Gábor <szeder@ira.uka.de>
Git's bash completion currently doesn't work when certain git options are specified, e.g. 'git --no-pager <TAB>' errors out with "error: invalid key: alias.--no-pager".
The main _git() completion function finds out the git command name by looping through all the words on the command line and searching for the first word that is not a known option for the git command. Unfortunately the list of known git options was not updated in a long time, and newer options are not skipped but mistaken for a git command. Such a misrecognized "command" is then passed to __git_aliased_command(), which in turn passes it to a 'git config' query, hence the error.
Currently the following options are misrecognized for a git command:
-c --no-pager --exec-path --html-path --man-path --info-path
--no-replace-objects --work-tree= --namespace=
To fix this we could just update the list of options to be skipped, but the same issue will likely arise, if the git command learns a new option in the future. Therefore, to make it more future proof against new options, this patch changes that loop to skip all option-looking words, i.e. words starting with a dash.
We also have to handle the '-c' option specially, because it takes a configutation parameter in a separate word, which must be skipped, too.
Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
[added tests]
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/completion/git-completion.bash | 3 ++-
t/t9902-completion.sh | 17 +++++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
Show changes to 2 files +19 −1
contrib/completion/git-completion.bash, t/t9902-completion.sh
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 6486a09..9f56ec7 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2623,8 +2623,9 @@ _git ()
case "$i" in
--git-dir=*) __git_dir="${i#--git-dir=}" ;;
--bare) __git_dir="." ;;
- --version|-p|--paginate) ;;
--help) command="help"; break ;;
+ -c) c=$((++c)) ;;
+ -*) ;;
*) command="$i"; break ;;
esac
((c++))
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index dfef809..ab72378 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -138,4 +138,21 @@ test_expect_success 'general options' '
test_completion "git --inf" "--info-path " &&
test_completion "git --no-r" "--no-replace-objects "
'
+
+test_expect_success 'general options plus command' '
+ test_completion "git --version check" "checkout " &&
+ test_completion "git --paginate check" "checkout " &&
+ test_completion "git --git-dir=foo check" "checkout " &&
+ test_completion "git --bare check" "checkout " &&
+ test_completion "git --help des" "describe " &&
+ test_completion "git --exec-path=foo check" "checkout " &&
+ test_completion "git --html-path check" "checkout " &&
+ test_completion "git --no-pager check" "checkout " &&
+ test_completion "git --work-tree=foo check" "checkout " &&
+ test_completion "git --namespace=foo check" "checkout " &&
+ test_completion "git --paginate check" "checkout " &&
+ test_completion "git --info-path check" "checkout " &&
+ test_completion "git --no-replace-objects check" "checkout "
+'
+
test_done
--
1.7.10.1.g1f19b8.dirty