]> git.ipfire.org Git - thirdparty/git.git/blobdiff - contrib/completion/git-completion.bash
completion: improve ls-remote output filtering in __git_refs_remotes()
[thirdparty/git.git] / contrib / completion / git-completion.bash
index 8648a36e7b8239e969dc8971f451431c298e405e..f992b1399d94fc5b20a475412efc855f27af2595 100755 (executable)
@@ -485,8 +485,13 @@ _get_comp_words_by_ref ()
 fi
 fi
 
-# __gitcomp accepts 1, 2, 3, or 4 arguments
-# generates completion reply with compgen
+# Generates completion reply with compgen, appending a space to possible
+# completion words, if necessary.
+# It accepts 1 to 4 arguments:
+# 1: List of possible completion words.
+# 2: A prefix to be added to each possible completion word (optional).
+# 3: Generate possible completion matches for this word (optional).
+# 4: A suffix to be appended to each possible completion word (optional).
 __gitcomp ()
 {
        local cur_="$cur"
@@ -507,6 +512,31 @@ __gitcomp ()
        esac
 }
 
+# Generates completion reply with compgen from newline-separated possible
+# completion words by appending a space to all of them.
+# It accepts 1 to 4 arguments:
+# 1: List of possible completion words, separated by a single newline.
+# 2: A prefix to be added to each possible completion word (optional).
+# 3: Generate possible completion matches for this word (optional).
+# 4: A suffix to be appended to each possible completion word instead of
+#    the default space (optional).  If specified but empty, nothing is
+#    appended.
+__gitcomp_nl ()
+{
+       local s=$'\n' IFS=' '$'\t'$'\n'
+       local cur_="$cur" suffix=" "
+
+       if [ $# -gt 2 ]; then
+               cur_="$3"
+               if [ $# -gt 3 ]; then
+                       suffix="$4"
+               fi
+       fi
+
+       IFS=$s
+       COMPREPLY=($(compgen -P "${2-}" -S "$suffix" -W "$1" -- "$cur_"))
+}
+
 # __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
 __git_heads ()
 {
@@ -550,7 +580,7 @@ __git_tags ()
 # by checkout for tracking branches
 __git_refs ()
 {
-       local i is_hash=y dir="$(__gitdir "${1-}")" track="${2-}"
+       local i hash dir="$(__gitdir "${1-}")" track="${2-}"
        local format refs
        if [ -d "$dir" ]; then
                case "$cur" in
@@ -586,16 +616,27 @@ __git_refs ()
                fi
                return
        fi
-       for i in $(git ls-remote "$dir" 2>/dev/null); do
-               case "$is_hash,$i" in
-               y,*) is_hash=n ;;
-               n,*^{}) is_hash=y ;;
-               n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
-               n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
-               n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
-               n,*) is_hash=y; echo "$i" ;;
-               esac
-       done
+       case "$cur" in
+       refs|refs/*)
+               git ls-remote "$dir" "$cur*" 2>/dev/null | \
+               while read hash i; do
+                       case "$i" in
+                       *^{}) ;;
+                       *) echo "$i" ;;
+                       esac
+               done
+               ;;
+       *)
+               git ls-remote "$dir" HEAD ORIG_HEAD 'refs/tags/*' 'refs/heads/*' 'refs/remotes/*' 2>/dev/null | \
+               while read hash i; do
+                       case "$i" in
+                       *^{}) ;;
+                       refs/*) echo "${i#refs/*/}" ;;
+                       *) echo "$i" ;;
+                       esac
+               done
+               ;;
+       esac
 }
 
 # __git_refs2 requires 1 argument (to pass to __git_refs)
@@ -610,18 +651,10 @@ __git_refs2 ()
 # __git_refs_remotes requires 1 argument (to pass to ls-remote)
 __git_refs_remotes ()
 {
-       local cmd i is_hash=y
-       for i in $(git ls-remote "$1" 2>/dev/null); do
-               case "$is_hash,$i" in
-               n,refs/heads/*)
-                       is_hash=y
-                       echo "$i:refs/remotes/$1/${i#refs/heads/}"
-                       ;;
-               y,*) is_hash=n ;;
-               n,*^{}) is_hash=y ;;
-               n,refs/tags/*) is_hash=y;;
-               n,*) is_hash=y; ;;
-               esac
+       local i hash
+       git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
+       while read hash i; do
+               echo "$i:refs/remotes/$1/${i#refs/heads/}"
        done
 }
 
@@ -711,15 +744,15 @@ __git_complete_revlist_file ()
        *...*)
                pfx="${cur_%...*}..."
                cur_="${cur_#*...}"
-               __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+               __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                ;;
        *..*)
                pfx="${cur_%..*}.."
                cur_="${cur_#*..}"
-               __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+               __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                ;;
        *)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                ;;
        esac
 }
@@ -759,7 +792,7 @@ __git_complete_remote_or_refspec ()
                c=$((++c))
        done
        if [ -z "$remote" ]; then
-               __gitcomp "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)"
                return
        fi
        if [ $no_complete_refspec = 1 ]; then
@@ -784,23 +817,23 @@ __git_complete_remote_or_refspec ()
        case "$cmd" in
        fetch)
                if [ $lhs = 1 ]; then
-                       __gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
                else
-                       __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                fi
                ;;
        pull)
                if [ $lhs = 1 ]; then
-                       __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
                else
-                       __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                fi
                ;;
        push)
                if [ $lhs = 1 ]; then
-                       __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                else
-                       __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
                fi
                ;;
        esac
@@ -1079,7 +1112,7 @@ _git_archive ()
                return
                ;;
        --remote=*)
-               __gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
+               __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
                return
                ;;
        --*)
@@ -1110,7 +1143,7 @@ _git_bisect ()
 
        case "$subcommand" in
        bad|good|reset|skip|start)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                ;;
        *)
                COMPREPLY=()
@@ -1141,9 +1174,9 @@ _git_branch ()
                ;;
        *)
                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
-                       __gitcomp "$(__git_heads)"
+                       __gitcomp_nl "$(__git_heads)"
                else
-                       __gitcomp "$(__git_refs)"
+                       __gitcomp_nl "$(__git_refs)"
                fi
                ;;
        esac
@@ -1190,7 +1223,7 @@ _git_checkout ()
                if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
                        track=''
                fi
-               __gitcomp "$(__git_refs '' $track)"
+               __gitcomp_nl "$(__git_refs '' $track)"
                ;;
        esac
 }
@@ -1207,7 +1240,7 @@ _git_cherry_pick ()
                __gitcomp "--edit --no-commit"
                ;;
        *)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                ;;
        esac
 }
@@ -1259,12 +1292,9 @@ _git_commit ()
                        " "" "${cur##--cleanup=}"
                return
                ;;
-       --reuse-message=*)
-               __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
-               return
-               ;;
-       --reedit-message=*)
-               __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
+       --reuse-message=*|--reedit-message=*|\
+       --fixup=*|--squash=*)
+               __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
                return
                ;;
        --untracked-files=*)
@@ -1278,7 +1308,7 @@ _git_commit ()
                        --dry-run --reuse-message= --reedit-message=
                        --reset-author --file= --message= --template=
                        --cleanup= --untracked-files --untracked-files=
-                       --verbose --quiet
+                       --verbose --quiet --fixup= --squash=
                        "
                return
        esac
@@ -1295,7 +1325,7 @@ _git_describe ()
                        "
                return
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 __git_diff_common_options="--stat --numstat --shortstat --summary
@@ -1454,7 +1484,7 @@ _git_grep ()
                ;;
        esac
 
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_help ()
@@ -1512,7 +1542,7 @@ _git_ls_files ()
 
 _git_ls_remote ()
 {
-       __gitcomp "$(__git_remotes)"
+       __gitcomp_nl "$(__git_remotes)"
 }
 
 _git_ls_tree ()
@@ -1556,14 +1586,9 @@ _git_log ()
                merge="--merge"
        fi
        case "$cur" in
-       --pretty=*)
+       --pretty=*|--format=*)
                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
-                       " "" "${cur##--pretty=}"
-               return
-               ;;
-       --format=*)
-               __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
-                       " "" "${cur##--format=}"
+                       " "" "${cur#*=}"
                return
                ;;
        --date=*)
@@ -1613,7 +1638,7 @@ _git_merge ()
                __gitcomp "$__git_merge_options"
                return
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_mergetool ()
@@ -1633,7 +1658,7 @@ _git_mergetool ()
 
 _git_merge_base ()
 {
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_mv ()
@@ -1664,18 +1689,16 @@ _git_notes ()
        ,*)
                case "${words[cword-1]}" in
                --ref)
-                       __gitcomp "$(__git_refs)"
+                       __gitcomp_nl "$(__git_refs)"
                        ;;
                *)
                        __gitcomp "$subcommands --ref"
                        ;;
                esac
                ;;
-       add,--reuse-message=*|append,--reuse-message=*)
-               __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
-               ;;
+       add,--reuse-message=*|append,--reuse-message=*|\
        add,--reedit-message=*|append,--reedit-message=*)
-               __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
+               __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
                ;;
        add,--*|append,--*)
                __gitcomp '--file= --message= --reedit-message=
@@ -1694,7 +1717,7 @@ _git_notes ()
                -m|-F)
                        ;;
                *)
-                       __gitcomp "$(__git_refs)"
+                       __gitcomp_nl "$(__git_refs)"
                        ;;
                esac
                ;;
@@ -1722,18 +1745,18 @@ _git_push ()
 {
        case "$prev" in
        --repo)
-               __gitcomp "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)"
                return
        esac
        case "$cur" in
        --repo=*)
-               __gitcomp "$(__git_remotes)" "" "${cur##--repo=}"
+               __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
                return
                ;;
        --*)
                __gitcomp "
                        --all --mirror --tags --dry-run --force --verbose
-                       --receive-pack= --repo=
+                       --receive-pack= --repo= --set-upstream
                "
                return
                ;;
@@ -1765,7 +1788,7 @@ _git_rebase ()
 
                return
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_reflog ()
@@ -1776,7 +1799,7 @@ _git_reflog ()
        if [ -z "$subcommand" ]; then
                __gitcomp "$subcommands"
        else
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
        fi
 }
 
@@ -1858,23 +1881,23 @@ _git_config ()
 {
        case "$prev" in
        branch.*.remote)
-               __gitcomp "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)"
                return
                ;;
        branch.*.merge)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                return
                ;;
        remote.*.fetch)
                local remote="${prev#remote.}"
                remote="${remote%.fetch}"
-               __gitcomp "$(__git_refs_remotes "$remote")"
+               __gitcomp_nl "$(__git_refs_remotes "$remote")"
                return
                ;;
        remote.*.push)
                local remote="${prev#remote.}"
                remote="${remote%.push}"
-               __gitcomp "$(git --git-dir="$(__gitdir)" \
+               __gitcomp_nl "$(git --git-dir="$(__gitdir)" \
                        for-each-ref --format='%(refname):%(refname)' \
                        refs/heads)"
                return
@@ -1921,7 +1944,7 @@ _git_config ()
                return
                ;;
        --get|--get-all|--unset|--unset-all)
-               __gitcomp "$(__git_config_get_set_variables)"
+               __gitcomp_nl "$(__git_config_get_set_variables)"
                return
                ;;
        *.*)
@@ -1947,7 +1970,7 @@ _git_config ()
                ;;
        branch.*)
                local pfx="${cur%.*}." cur_="${cur#*.}"
-               __gitcomp "$(__git_heads)" "$pfx" "$cur_" "."
+               __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
                return
                ;;
        guitool.*.*)
@@ -1976,7 +1999,7 @@ _git_config ()
        pager.*)
                local pfx="${cur%.*}." cur_="${cur#*.}"
                __git_compute_all_commands
-               __gitcomp "$__git_all_commands" "$pfx" "$cur_"
+               __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
                return
                ;;
        remote.*.*)
@@ -1989,7 +2012,7 @@ _git_config ()
                ;;
        remote.*)
                local pfx="${cur%.*}." cur_="${cur#*.}"
-               __gitcomp "$(__git_remotes)" "$pfx" "$cur_" "."
+               __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
                return
                ;;
        url.*.*)
@@ -2290,7 +2313,7 @@ _git_remote ()
 
        case "$subcommand" in
        rename|rm|show|prune)
-               __gitcomp "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)"
                ;;
        update)
                local i c='' IFS=$'\n'
@@ -2308,7 +2331,7 @@ _git_remote ()
 
 _git_replace ()
 {
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_reset ()
@@ -2321,7 +2344,7 @@ _git_reset ()
                return
                ;;
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_revert ()
@@ -2332,7 +2355,7 @@ _git_revert ()
                return
                ;;
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_rm ()
@@ -2370,14 +2393,9 @@ _git_show ()
        __git_has_doubledash && return
 
        case "$cur" in
-       --pretty=*)
-               __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
-                       " "" "${cur##--pretty=}"
-               return
-               ;;
-       --format=*)
+       --pretty=*|--format=*)
                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
-                       " "" "${cur##--format=}"
+                       " "" "${cur#*=}"
                return
                ;;
        --*)
@@ -2436,7 +2454,7 @@ _git_stash ()
                        COMPREPLY=()
                        ;;
                show,*|apply,*|drop,*|pop,*|branch,*)
-                       __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
+                       __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
                                        | sed -n -e 's/:.*//p')"
                        ;;
                *)
@@ -2570,7 +2588,7 @@ _git_tag ()
                i="${words[c]}"
                case "$i" in
                -d|-v)
-                       __gitcomp "$(__git_tags)"
+                       __gitcomp_nl "$(__git_tags)"
                        return
                        ;;
                -f)
@@ -2586,13 +2604,13 @@ _git_tag ()
                ;;
        -*|tag)
                if [ $f = 1 ]; then
-                       __gitcomp "$(__git_tags)"
+                       __gitcomp_nl "$(__git_tags)"
                else
                        COMPREPLY=()
                fi
                ;;
        *)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                ;;
        esac
 }