]> git.ipfire.org Git - thirdparty/git.git/commitdiff
completion: bash: support recursive aliases
authorFelipe Contreras <felipe.contreras@gmail.com>
Tue, 10 Nov 2020 02:03:42 +0000 (20:03 -0600)
committerJunio C Hamano <gitster@pobox.com>
Tue, 10 Nov 2020 02:09:21 +0000 (18:09 -0800)
It is possible to have recursive aliases like:

  l = log --oneline
  lg = l --graph

So the completion should detect such aliases as well.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
contrib/completion/git-completion.bash
t/t9902-completion.sh

index 7c81e4ba497fb6ab1b9b32a40336f5995b0b5b55..97eccffa4a1e82fc0918649a8c9b901dd14840c9 100644 (file)
@@ -1120,26 +1120,38 @@ __git_pretty_aliases ()
 # __git_aliased_command requires 1 argument
 __git_aliased_command ()
 {
-       local word cmdline=$(__git config --get "alias.$1")
-       for word in $cmdline; do
-               case "$word" in
-               \!gitk|gitk)
-                       echo "gitk"
-                       return
-                       ;;
-               \!*)    : shell command alias ;;
-               -*)     : option ;;
-               *=*)    : setting env ;;
-               git)    : git itself ;;
-               \(\))   : skip parens of shell function definition ;;
-               {)      : skip start of shell helper function ;;
-               :)      : skip null command ;;
-               \'*)    : skip opening quote after sh -c ;;
-               *)
-                       echo "$word"
-                       return
-               esac
+       local cur=$1 last word cmdline
+
+       while [[ -n "$cur" ]]; do
+               cmdline=$(__git config --get "alias.$cur")
+               last=$cur
+               cur=
+
+               for word in $cmdline; do
+                       case "$word" in
+                       \!gitk|gitk)
+                               cur="gitk"
+                               break
+                               ;;
+                       \!*)    : shell command alias ;;
+                       -*)     : option ;;
+                       *=*)    : setting env ;;
+                       git)    : git itself ;;
+                       \(\))   : skip parens of shell function definition ;;
+                       {)      : skip start of shell helper function ;;
+                       :)      : skip null command ;;
+                       \'*)    : skip opening quote after sh -c ;;
+                       *)
+                               cur="$word"
+                               break
+                       esac
+               done
        done
+
+       cur=$last
+       if [[ "$cur" != "$1" ]]; then
+               echo "$cur"
+       fi
 }
 
 # Check whether one of the given words is present on the command line,
index 2be9190425bb1dc6f9ab0eb1b8e030c99e0d2920..5c01c75d408955ed75384454394ad843f94d4263 100755 (executable)
@@ -2195,6 +2195,25 @@ test_expect_success 'complete files' '
        test_completion "git add mom" "momified"
 '
 
+test_expect_success "simple alias" '
+       test_config alias.co checkout &&
+       test_completion "git co m" <<-\EOF
+       master Z
+       mybranch Z
+       mytag Z
+       EOF
+'
+
+test_expect_success "recursive alias" '
+       test_config alias.co checkout &&
+       test_config alias.cod "co --detached" &&
+       test_completion "git cod m" <<-\EOF
+       master Z
+       mybranch Z
+       mytag Z
+       EOF
+'
+
 test_expect_success "completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'" '
        test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
        test_completion "git co m" <<-\EOF