Merge branch 'uk/ls-remote-in-get-remote-url'
[gitweb.git] / contrib / completion / git-completion.bash
index 25c431469fc85bcf2fc1089091d6f11821f2f570..ccdc172a06bcc55ff5c5c3c1854bb34f84910f90 100755 (executable)
@@ -246,6 +246,8 @@ __git_ps1 ()
                                fi
                        elif [ -f "$g/MERGE_HEAD" ]; then
                                r="|MERGING"
+                       elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
+                               r="|CHERRY-PICKING"
                        elif [ -f "$g/BISECT_LOG" ]; then
                                r="|BISECTING"
                        fi
@@ -327,11 +329,168 @@ __gitcomp_1 ()
        done
 }
 
+# The following function is based on code from:
+#
+#   bash_completion - programmable completion functions for bash 3.2+
+#
+#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
+#             © 2009-2010, Bash Completion Maintainers
+#                     <bash-completion-devel@lists.alioth.debian.org>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2, or (at your option)
+#   any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software Foundation,
+#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#   The latest version of this software can be obtained here:
+#
+#   http://bash-completion.alioth.debian.org/
+#
+#   RELEASE: 2.x
+
+# This function can be used to access a tokenized list of words
+# on the command line:
+#
+#      __git_reassemble_comp_words_by_ref '=:'
+#      if test "${words_[cword_-1]}" = -w
+#      then
+#              ...
+#      fi
+#
+# The argument should be a collection of characters from the list of
+# word completion separators (COMP_WORDBREAKS) to treat as ordinary
+# characters.
+#
+# This is roughly equivalent to going back in time and setting
+# COMP_WORDBREAKS to exclude those characters.  The intent is to
+# make option types like --date=<type> and <rev>:<path> easy to
+# recognize by treating each shell word as a single token.
+#
+# It is best not to set COMP_WORDBREAKS directly because the value is
+# shared with other completion scripts.  By the time the completion
+# function gets called, COMP_WORDS has already been populated so local
+# changes to COMP_WORDBREAKS have no effect.
+#
+# Output: words_, cword_, cur_.
+
+__git_reassemble_comp_words_by_ref()
+{
+       local exclude i j first
+       # Which word separators to exclude?
+       exclude="${1//[^$COMP_WORDBREAKS]}"
+       cword_=$COMP_CWORD
+       if [ -z "$exclude" ]; then
+               words_=("${COMP_WORDS[@]}")
+               return
+       fi
+       # List of word completion separators has shrunk;
+       # re-assemble words to complete.
+       for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
+               # Append each nonempty word consisting of just
+               # word separator characters to the current word.
+               first=t
+               while
+                       [ $i -gt 0 ] &&
+                       [ -n "${COMP_WORDS[$i]}" ] &&
+                       # word consists of excluded word separators
+                       [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
+               do
+                       # Attach to the previous token,
+                       # unless the previous token is the command name.
+                       if [ $j -ge 2 ] && [ -n "$first" ]; then
+                               ((j--))
+                       fi
+                       first=
+                       words_[$j]=${words_[j]}${COMP_WORDS[i]}
+                       if [ $i = $COMP_CWORD ]; then
+                               cword_=$j
+                       fi
+                       if (($i < ${#COMP_WORDS[@]} - 1)); then
+                               ((i++))
+                       else
+                               # Done.
+                               return
+                       fi
+               done
+               words_[$j]=${words_[j]}${COMP_WORDS[i]}
+               if [ $i = $COMP_CWORD ]; then
+                       cword_=$j
+               fi
+       done
+}
+
+if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
+if [[ -z ${ZSH_VERSION:+set} ]]; then
+_get_comp_words_by_ref ()
+{
+       local exclude cur_ words_ cword_
+       if [ "$1" = "-n" ]; then
+               exclude=$2
+               shift 2
+       fi
+       __git_reassemble_comp_words_by_ref "$exclude"
+       cur_=${words_[cword_]}
+       while [ $# -gt 0 ]; do
+               case "$1" in
+               cur)
+                       cur=$cur_
+                       ;;
+               prev)
+                       prev=${words_[$cword_-1]}
+                       ;;
+               words)
+                       words=("${words_[@]}")
+                       ;;
+               cword)
+                       cword=$cword_
+                       ;;
+               esac
+               shift
+       done
+}
+else
+_get_comp_words_by_ref ()
+{
+       while [ $# -gt 0 ]; do
+               case "$1" in
+               cur)
+                       cur=${COMP_WORDS[COMP_CWORD]}
+                       ;;
+               prev)
+                       prev=${COMP_WORDS[COMP_CWORD-1]}
+                       ;;
+               words)
+                       words=("${COMP_WORDS[@]}")
+                       ;;
+               cword)
+                       cword=$COMP_CWORD
+                       ;;
+               -n)
+                       # assume COMP_WORDBREAKS is already set sanely
+                       shift
+                       ;;
+               esac
+               shift
+       done
+}
+fi
+fi
+
 # __gitcomp accepts 1, 2, 3, or 4 arguments
 # generates completion reply with compgen
 __gitcomp ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        if [ $# -gt 2 ]; then
                cur="$3"
        fi
@@ -392,7 +551,8 @@ __git_tags ()
 __git_refs ()
 {
        local i is_hash=y dir="$(__gitdir "${1-}")" track="${2-}"
-       local cur="${COMP_WORDS[COMP_CWORD]}" format refs
+       local cur format refs
+       _get_comp_words_by_ref -n =: cur
        if [ -d "$dir" ]; then
                case "$cur" in
                refs|refs/*)
@@ -506,7 +666,8 @@ __git_compute_merge_strategies ()
 
 __git_complete_file ()
 {
-       local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
+       local pfx ls ref cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        ?*:*)
                ref="${cur%%:*}"
@@ -554,7 +715,8 @@ __git_complete_file ()
 
 __git_complete_revlist ()
 {
-       local pfx cur="${COMP_WORDS[COMP_CWORD]}"
+       local pfx cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        *...*)
                pfx="${cur%...*}..."
@@ -574,11 +736,12 @@ __git_complete_revlist ()
 
 __git_complete_remote_or_refspec ()
 {
-       local cmd="${COMP_WORDS[1]}"
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur words cword
+       _get_comp_words_by_ref -n =: cur words cword
+       local cmd="${words[1]}"
        local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
-       while [ $c -lt $COMP_CWORD ]; do
-               i="${COMP_WORDS[c]}"
+       while [ $c -lt $cword ]; do
+               i="${words[c]}"
                case "$i" in
                --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
                --all)
@@ -646,13 +809,14 @@ __git_complete_remote_or_refspec ()
 
 __git_complete_strategy ()
 {
+       local cur prev
+       _get_comp_words_by_ref -n =: cur prev
        __git_compute_merge_strategies
-       case "${COMP_WORDS[COMP_CWORD-1]}" in
+       case "$prev" in
        -s|--strategy)
                __gitcomp "$__git_merge_strategies"
                return 0
        esac
-       local cur="${COMP_WORDS[COMP_CWORD]}"
        case "$cur" in
        --strategy=*)
                __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
@@ -735,7 +899,6 @@ __git_list_porcelain_commands ()
                quiltimport)      : import;;
                read-tree)        : plumbing;;
                receive-pack)     : plumbing;;
-               reflog)           : plumbing;;
                remote-*)         : transport;;
                repo-config)      : deprecated;;
                rerere)           : plumbing;;
@@ -825,10 +988,10 @@ __git_aliased_command ()
 # __git_find_on_cmdline requires 1 argument
 __git_find_on_cmdline ()
 {
-       local word subcommand c=1
-
-       while [ $c -lt $COMP_CWORD ]; do
-               word="${COMP_WORDS[c]}"
+       local word subcommand c=1 words cword
+       _get_comp_words_by_ref -n =: words cword
+       while [ $c -lt $cword ]; do
+               word="${words[c]}"
                for subcommand in $1; do
                        if [ "$subcommand" = "$word" ]; then
                                echo "$subcommand"
@@ -841,9 +1004,10 @@ __git_find_on_cmdline ()
 
 __git_has_doubledash ()
 {
-       local c=1
-       while [ $c -lt $COMP_CWORD ]; do
-               if [ "--" = "${COMP_WORDS[c]}" ]; then
+       local c=1 words cword
+       _get_comp_words_by_ref -n =: words cword
+       while [ $c -lt $cword ]; do
+               if [ "--" = "${words[c]}" ]; then
                        return 0
                fi
                c=$((++c))
@@ -855,7 +1019,8 @@ __git_whitespacelist="nowarn warn error error-all fix"
 
 _git_am ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
+       local cur dir="$(__gitdir)"
+       _get_comp_words_by_ref -n =: cur
        if [ -d "$dir"/rebase-apply ]; then
                __gitcomp "--skip --continue --resolved --abort"
                return
@@ -879,7 +1044,8 @@ _git_am ()
 
 _git_apply ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --whitespace=*)
                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
@@ -902,7 +1068,8 @@ _git_add ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@ -916,7 +1083,8 @@ _git_add ()
 
 _git_archive ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --format=*)
                __gitcomp "$(git archive --list)" "" "${cur##--format=}"
@@ -964,10 +1132,11 @@ _git_bisect ()
 
 _git_branch ()
 {
-       local i c=1 only_local_ref="n" has_r="n"
+       local i c=1 only_local_ref="n" has_r="n" cur words cword
 
-       while [ $c -lt $COMP_CWORD ]; do
-               i="${COMP_WORDS[c]}"
+       _get_comp_words_by_ref -n =: cur words cword
+       while [ $c -lt $cword ]; do
+               i="${words[c]}"
                case "$i" in
                -d|-m)  only_local_ref="y" ;;
                -r)     has_r="y" ;;
@@ -975,7 +1144,7 @@ _git_branch ()
                c=$((++c))
        done
 
-       case "${COMP_WORDS[COMP_CWORD]}" in
+       case "$cur" in
        --*)
                __gitcomp "
                        --color --no-color --verbose --abbrev= --no-abbrev
@@ -995,8 +1164,10 @@ _git_branch ()
 
 _git_bundle ()
 {
-       local cmd="${COMP_WORDS[2]}"
-       case "$COMP_CWORD" in
+       local words cword
+       _get_comp_words_by_ref -n =: words cword
+       local cmd="${words[2]}"
+       case "$cword" in
        2)
                __gitcomp "create list-heads verify unbundle"
                ;;
@@ -1017,7 +1188,8 @@ _git_checkout ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --conflict=*)
                __gitcomp "diff3 merge" "" "${cur##--conflict=}"
@@ -1047,7 +1219,8 @@ _git_cherry ()
 
 _git_cherry_pick ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--edit --no-commit"
@@ -1062,7 +1235,8 @@ _git_clean ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--dry-run --quiet"
@@ -1074,7 +1248,8 @@ _git_clean ()
 
 _git_clone ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@ -1101,7 +1276,8 @@ _git_commit ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --cleanup=*)
                __gitcomp "default strip verbatim whitespace
@@ -1136,7 +1312,8 @@ _git_commit ()
 
 _git_describe ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@ -1168,7 +1345,8 @@ _git_diff ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
@@ -1182,14 +1360,15 @@ _git_diff ()
 }
 
 __git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
-                       tkdiff vimdiff gvimdiff xxdiff araxis p4merge
+                       tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3
 "
 
 _git_difftool ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --tool=*)
                __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
@@ -1214,7 +1393,8 @@ __git_fetch_options="
 
 _git_fetch ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "$__git_fetch_options"
@@ -1226,7 +1406,8 @@ _git_fetch ()
 
 _git_format_patch ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --thread=*)
                __gitcomp "
@@ -1258,7 +1439,8 @@ _git_format_patch ()
 
 _git_fsck ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@ -1273,7 +1455,8 @@ _git_fsck ()
 
 _git_gc ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--prune --aggressive"
@@ -1292,7 +1475,8 @@ _git_grep ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@ -1315,7 +1499,8 @@ _git_grep ()
 
 _git_help ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--all --info --man --web"
@@ -1333,7 +1518,8 @@ _git_help ()
 
 _git_init ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --shared=*)
                __gitcomp "
@@ -1353,7 +1539,8 @@ _git_ls_files ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--cached --deleted --modified --others --ignored
@@ -1407,12 +1594,13 @@ _git_log ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
        local g="$(git rev-parse --git-dir 2>/dev/null)"
        local merge=""
        if [ -f "$g/MERGE_HEAD" ]; then
                merge="--merge"
        fi
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --pretty=*)
                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
@@ -1466,7 +1654,8 @@ _git_merge ()
 {
        __git_complete_strategy && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "$__git_merge_options"
@@ -1477,7 +1666,8 @@ _git_merge ()
 
 _git_mergetool ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --tool=*)
                __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
@@ -1498,7 +1688,8 @@ _git_merge_base ()
 
 _git_mv ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--dry-run"
@@ -1517,14 +1708,15 @@ _git_notes ()
 {
        local subcommands='add append copy edit list prune remove show'
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur words cword
+       _get_comp_words_by_ref -n =: cur words cword
 
        case "$subcommand,$cur" in
        ,--*)
                __gitcomp '--ref'
                ;;
        ,*)
-               case "${COMP_WORDS[COMP_CWORD-1]}" in
+               case "${words[cword-1]}" in
                --ref)
                        __gitcomp "$(__git_refs)"
                        ;;
@@ -1552,7 +1744,7 @@ _git_notes ()
        prune,*)
                ;;
        *)
-               case "${COMP_WORDS[COMP_CWORD-1]}" in
+               case "${words[cword-1]}" in
                -m|-F)
                        ;;
                *)
@@ -1567,7 +1759,8 @@ _git_pull ()
 {
        __git_complete_strategy && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@ -1583,8 +1776,9 @@ _git_pull ()
 
 _git_push ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
-       case "${COMP_WORDS[COMP_CWORD-1]}" in
+       local cur prev
+       _get_comp_words_by_ref -n =: cur prev
+       case "$prev" in
        --repo)
                __gitcomp "$(__git_remotes)"
                return
@@ -1607,7 +1801,9 @@ _git_push ()
 
 _git_rebase ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
+       local dir="$(__gitdir)"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
                __gitcomp "--continue --skip --abort"
                return
@@ -1632,12 +1828,25 @@ _git_rebase ()
        __gitcomp "$(__git_refs)"
 }
 
+_git_reflog ()
+{
+       local subcommands="show delete expire"
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+
+       if [ -z "$subcommand" ]; then
+               __gitcomp "$subcommands"
+       else
+               __gitcomp "$(__git_refs)"
+       fi
+}
+
 __git_send_email_confirm_options="always never auto cc compose"
 __git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
 
 _git_send_email ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --confirm=*)
                __gitcomp "
@@ -1679,9 +1888,11 @@ _git_stage ()
 
 __git_config_get_set_variables ()
 {
-       local prevword word config_file= c=$COMP_CWORD
+       local words cword
+       _get_comp_words_by_ref -n =: words cword
+       local prevword word config_file= c=$cword
        while [ $c -gt 1 ]; do
-               word="${COMP_WORDS[c]}"
+               word="${words[c]}"
                case "$word" in
                --global|--system|--file=*)
                        config_file="$word"
@@ -1709,9 +1920,9 @@ __git_config_get_set_variables ()
 
 _git_config ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
-       local prv="${COMP_WORDS[COMP_CWORD-1]}"
-       case "$prv" in
+       local cur prev
+       _get_comp_words_by_ref -n =: cur prev
+       case "$prev" in
        branch.*.remote)
                __gitcomp "$(__git_remotes)"
                return
@@ -1721,13 +1932,13 @@ _git_config ()
                return
                ;;
        remote.*.fetch)
-               local remote="${prv#remote.}"
+               local remote="${prev#remote.}"
                remote="${remote%.fetch}"
                __gitcomp "$(__git_refs_remotes "$remote")"
                return
                ;;
        remote.*.push)
-               local remote="${prv#remote.}"
+               local remote="${prev#remote.}"
                remote="${remote%.push}"
                __gitcomp "$(git --git-dir="$(__gitdir)" \
                        for-each-ref --format='%(refname):%(refname)' \
@@ -2180,7 +2391,8 @@ _git_reset ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--merge --mixed --hard --soft --patch"
@@ -2192,7 +2404,8 @@ _git_reset ()
 
 _git_revert ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
@@ -2206,7 +2419,8 @@ _git_rm ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
@@ -2220,7 +2434,8 @@ _git_shortlog ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@ -2238,7 +2453,8 @@ _git_show ()
 {
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --pretty=*)
                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
@@ -2262,7 +2478,8 @@ _git_show ()
 
 _git_show_branch ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@ -2279,7 +2496,8 @@ _git_show_branch ()
 
 _git_stash ()
 {
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
+       _get_comp_words_by_ref -n =: cur
        local save_opts='--keep-index --no-keep-index --quiet --patch'
        local subcommands='save list show apply clear drop pop create branch'
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
@@ -2324,7 +2542,8 @@ _git_submodule ()
 
        local subcommands="add status init update summary foreach sync"
        if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
-               local cur="${COMP_WORDS[COMP_CWORD]}"
+               local cur
+               _get_comp_words_by_ref -n =: cur
                case "$cur" in
                --*)
                        __gitcomp "--quiet --cached"
@@ -2368,7 +2587,8 @@ _git_svn ()
                        --edit --rmdir --find-copies-harder --copy-similarity=
                        "
 
-               local cur="${COMP_WORDS[COMP_CWORD]}"
+               local cur
+               _get_comp_words_by_ref -n =: cur
                case "$subcommand,$cur" in
                fetch,--*)
                        __gitcomp "--revision= --fetch-all $fc_opts"
@@ -2440,8 +2660,10 @@ _git_svn ()
 _git_tag ()
 {
        local i c=1 f=0
-       while [ $c -lt $COMP_CWORD ]; do
-               i="${COMP_WORDS[c]}"
+       local words cword prev
+       _get_comp_words_by_ref -n =: words cword prev
+       while [ $c -lt $cword ]; do
+               i="${words[c]}"
                case "$i" in
                -d|-v)
                        __gitcomp "$(__git_tags)"
@@ -2454,7 +2676,7 @@ _git_tag ()
                c=$((++c))
        done
 
-       case "${COMP_WORDS[COMP_CWORD-1]}" in
+       case "$prev" in
        -m|-F)
                COMPREPLY=()
                ;;
@@ -2485,8 +2707,10 @@ _git ()
                setopt KSH_TYPESET
        fi
 
-       while [ $c -lt $COMP_CWORD ]; do
-               i="${COMP_WORDS[c]}"
+       local cur words cword
+       _get_comp_words_by_ref -n =: cur words cword
+       while [ $c -lt $cword ]; do
+               i="${words[c]}"
                case "$i" in
                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
                --bare)      __git_dir="." ;;
@@ -2498,7 +2722,7 @@ _git ()
        done
 
        if [ -z "$command" ]; then
-               case "${COMP_WORDS[COMP_CWORD]}" in
+               case "$cur" in
                --*)   __gitcomp "
                        --paginate
                        --no-pager
@@ -2536,12 +2760,13 @@ _gitk ()
 
        __git_has_doubledash && return
 
-       local cur="${COMP_WORDS[COMP_CWORD]}"
+       local cur
        local g="$(__gitdir)"
        local merge=""
        if [ -f "$g/MERGE_HEAD" ]; then
                merge="--merge"
        fi
+       _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "