bash: refactor searching for subcommands on the command line
[gitweb.git] / contrib / completion / git-completion.bash
index 8d6733abe4063cebbb0ac2d6e020077ed78fe438..438e193bd0de7506bf3d8b286f655acb97a776bc 100755 (executable)
@@ -70,22 +70,30 @@ __git_ps1 ()
                local b
                if [ -d "$g/../.dotest" ]
                then
-                       r="|AM/REBASE"
+                       if test -f "$g/../.dotest/rebasing"
+                       then
+                               r="|REBASE"
+                       elif test -f "$g/../.dotest/applying"
+                       then
+                               r="|AM"
+                       else
+                               r="|AM/REBASE"
+                       fi
                        b="$(git symbolic-ref HEAD 2>/dev/null)"
                elif [ -f "$g/.dotest-merge/interactive" ]
                then
                        r="|REBASE-i"
-                       b="$(cat $g/.dotest-merge/head-name)"
+                       b="$(cat "$g/.dotest-merge/head-name")"
                elif [ -d "$g/.dotest-merge" ]
                then
                        r="|REBASE-m"
-                       b="$(cat $g/.dotest-merge/head-name)"
+                       b="$(cat "$g/.dotest-merge/head-name")"
                elif [ -f "$g/MERGE_HEAD" ]
                then
                        r="|MERGING"
                        b="$(git symbolic-ref HEAD 2>/dev/null)"
                else
-                       if [ -f $g/BISECT_LOG ]
+                       if [ -f "$g/BISECT_LOG" ]
                        then
                                r="|BISECTING"
                        fi
@@ -93,7 +101,7 @@ __git_ps1 ()
                        then
                                if ! b="$(git describe --exact-match HEAD 2>/dev/null)"
                                then
-                                       b="$(cut -c1-7 $g/HEAD)..."
+                                       b="$(cut -c1-7 "$g/HEAD")..."
                                fi
                        fi
                fi
@@ -420,6 +428,22 @@ __git_aliased_command ()
        done
 }
 
+__git_find_subcommand ()
+{
+       local word subcommand c=1
+
+       while [ $c -lt $COMP_CWORD ]; do
+               word="${COMP_WORDS[c]}"
+               for subcommand in $1; do
+                       if [ "$subcommand" = "$word" ]; then
+                               echo "$subcommand"
+                               return
+                       fi
+               done
+               c=$((++c))
+       done
+}
+
 __git_whitespacelist="nowarn warn error error-all strip"
 
 _git_am ()
@@ -477,24 +501,14 @@ _git_add ()
 
 _git_bisect ()
 {
-       local i c=1 command
-       while [ $c -lt $COMP_CWORD ]; do
-               i="${COMP_WORDS[c]}"
-               case "$i" in
-               start|bad|good|reset|visualize|replay|log)
-                       command="$i"
-                       break
-                       ;;
-               esac
-               c=$((++c))
-       done
-
-       if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
-               __gitcomp "start bad good reset visualize replay log"
+       local subcommands="start bad good reset visualize replay log"
+       local subcommand="$(__git_find_subcommand "$subcommands")"
+       if [ -z "$subcommand" ]; then
+               __gitcomp "$subcommands"
                return
        fi
 
-       case "$command" in
+       case "$subcommand" in
        bad|good|reset)
                __gitcomp "$(__git_refs)"
                ;;
@@ -506,6 +520,17 @@ _git_bisect ()
 
 _git_branch ()
 {
+       local i c=1 only_local_ref="n" has_r="n"
+
+       while [ $c -lt $COMP_CWORD ]; do
+               i="${COMP_WORDS[c]}"
+               case "$i" in
+               -d|-m)  only_local_ref="y" ;;
+               -r)     has_r="y" ;;
+               esac
+               c=$((++c))
+       done
+
        case "${COMP_WORDS[COMP_CWORD]}" in
        --*=*)  COMPREPLY=() ;;
        --*)
@@ -514,7 +539,13 @@ _git_branch ()
                        --track --no-track
                        "
                ;;
-       *)      __gitcomp "$(__git_refs)" ;;
+       *)
+               if [ $only_local_ref = "y" -a $has_r = "n" ]; then
+                       __gitcomp "$(__git_heads)"
+               else
+                       __gitcomp "$(__git_refs)"
+               fi
+               ;;
        esac
 }
 
@@ -1008,21 +1039,13 @@ _git_config ()
 
 _git_remote ()
 {
-       local i c=1 command
-       while [ $c -lt $COMP_CWORD ]; do
-               i="${COMP_WORDS[c]}"
-               case "$i" in
-               add|rm|show|prune|update) command="$i"; break ;;
-               esac
-               c=$((++c))
-       done
-
-       if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
-               __gitcomp "add rm show prune update"
+       local subcommands="add rm show prune update"
+       local subcommand="$(__git_find_subcommand "$subcommands")"
+       if [ -z "$subcommand" ]; then
                return
        fi
 
-       case "$command" in
+       case "$subcommand" in
        rm|show|prune)
                __gitcomp "$(__git_remotes)"
                ;;
@@ -1096,28 +1119,23 @@ _git_show ()
 
 _git_stash ()
 {
-       __gitcomp 'list show apply clear'
+       local subcommands='list show apply clear'
+       if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
+               __gitcomp "$subcommands"
+       fi
 }
 
 _git_submodule ()
 {
-       local i c=1 command
-       while [ $c -lt $COMP_CWORD ]; do
-               i="${COMP_WORDS[c]}"
-               case "$i" in
-               add|status|init|update) command="$i"; break ;;
-               esac
-               c=$((++c))
-       done
-
-       if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
+       local subcommands="add status init update"
+       if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
                local cur="${COMP_WORDS[COMP_CWORD]}"
                case "$cur" in
                --*)
                        __gitcomp "--quiet --cached"
                        ;;
                *)
-                       __gitcomp "add status init update"
+                       __gitcomp "$subcommands"
                        ;;
                esac
                return
@@ -1173,7 +1191,7 @@ _git ()
                c=$((++c))
        done
 
-       if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
+       if [ -z "$command" ]; then
                case "${COMP_WORDS[COMP_CWORD]}" in
                --*=*) COMPREPLY=() ;;
                --*)   __gitcomp "