{"thread":{"id":"25912","subject":"[PATCH v4 0/2] *** SUBJECT HERE ***","startedAt":"2010-12-01T20:49:40Z","lastAt":"2010-12-15T06:42:35Z","messageCount":22,"participants":["Peter van der Does","Jonathan Nieder","SZEDER Gábor","Stephen Boyd","Junio C Hamano"],"isPatch":true,"patchVersion":4,"patchTotal":2},"messages":[{"id":"157017","messageId":"1291236582-28603-1-git-send-email-peter@avirtualhome.com","threadId":"25912","inReplyTo":null,"subject":"[PATCH v4 0/2] *** SUBJECT HERE ***","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-12-01T20:49:40Z","receivedAt":"2010-12-01T20:49:40Z","isPatch":true,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"*** BLURB HERE ***\nMake git-completion Bash 4 compatible.\n\nI've made the following changes since v3:\n- Patch is based upon the next branch.\n- Grammatical error in commit message\n\nPeter van der Does (2):\n  Introduce functions from bash-completion project.\n  Use the new functions to get the current cword.\n\n contrib/completion/git-completion.bash |  446 ++++++++++++++++++++++++++------\n 1 files changed, 363 insertions(+), 83 deletions(-)\n\n-- \n1.7.3.2\n"},{"id":"157018","messageId":"1291236582-28603-2-git-send-email-peter@avirtualhome.com","threadId":"25912","inReplyTo":"1291236582-28603-1-git-send-email-peter@avirtualhome.com","subject":"[PATCH v4 1/2] Introduce functions from bash-completion project.","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-12-01T20:49:41Z","receivedAt":"2010-12-01T20:49:41Z","isPatch":true,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"The completion script does not work as expected under Bash 4.\nBash: 3\noutput:\n$ git log --pretty=<tab><tab>\nemail     full      medium    raw\nformat:   fuller    oneline   short\n\nBash: 4\noutput:\n$ git log --pretty=<tab><tab>\n.bash_logout         .local/\n.bash_profile        Music/\n--More--\n\nWith Bash 4 the way word breaking is done in the programmable completion\ncode has changed. The documentation at the bash project is not very\nclear what was changed, the only reference found is in the NEWS section:\n\ni.  The programmable completion code now uses the same set of characters\nas readline when breaking the command line into a list of words.\n\nThe word breaking problem occurs with certain characters, like colon and\nequal sign.\n\nThe bash-completion project (http://bash-completion.alioth.debian.org/)\nhas written several functions to overcome this problem. By using these\nfunctions within the git-completion.bash script the word breaking\nproblem is solved.\n\nSigned-off-by: Peter van der Does <peter@avirtualhome.com>\n---\n contrib/completion/git-completion.bash |  223 ++++++++++++++++++++++++++++++++\n 1 files changed, 223 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex f710469..0036e8b 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -82,6 +82,229 @@ case \"$COMP_WORDBREAKS\" in\n *)   COMP_WORDBREAKS=\"$COMP_WORDBREAKS:\"\n esac\n \n+# If the function _get_comp_words_by_ref does not exists, we can assume the\n+# bash_completion 1.2 script isn't loaded and therefor we're defining the\n+# necessary functions ourselves.\n+# The functions come from the bash_completion 1.2 script.\n+# See: http://bash-completion.alioth.debian.org/\n+if ! type _get_comp_words_by_ref &> /dev/null ; then\n+\t# The bash_completion 1.2 library wasn't loaded,\n+\t# we have to define some functions from it ourselves.\n+\n+\t# Assign variables one scope above the caller\n+\t# Usage: local varname [varname ...] &&\n+\t#        _upvars [-v varname value] | [-aN varname [value ...]] ...\n+\t# Available OPTIONS:\n+\t#     -aN  Assign next N values to varname as array\n+\t#     -v   Assign single value to varname\n+\t# Return: 1 if error occurs\n+\t# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference\n+\t_upvars() {\n+\t    if ! (( $# )); then\n+\t        echo \"${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname\"\\\n+\t            \"value] | [-aN varname [value ...]] ...\" 1>&2\n+\t        return 2\n+\t    fi\n+\t    while (( $# )); do\n+\t        case $1 in\n+\t            -a*)\n+\t                # Error checking\n+\t                [[ ${1#-a} ]] || { echo \"bash: ${FUNCNAME[0]}: \\`$1': missing\"\\\n+\t                    \"number specifier\" 1>&2; return 1; }\n+\t                printf %d \"${1#-a}\" &> /dev/null || { echo \"bash:\"\\\n+\t                    \"${FUNCNAME[0]}: \\`$1': invalid number specifier\" 1>&2\n+\t                    return 1; }\n+\t                # Assign array of -aN elements\n+\t                [[ \"$2\" ]] && unset -v \"$2\" && eval $2=\\(\\\"\\${@:3:${1#-a}}\\\"\\) &&\n+\t                shift $((${1#-a} + 2)) || { echo \"bash: ${FUNCNAME[0]}:\"\\\n+\t                    \"\\`$1${2+ }$2': missing argument(s)\" 1>&2; return 1; }\n+\t                ;;\n+\t            -v)\n+\t                # Assign single value\n+\t                [[ \"$2\" ]] && unset -v \"$2\" && eval $2=\\\"\\$3\\\" &&\n+\t                shift 3 || { echo \"bash: ${FUNCNAME[0]}: $1: missing\"\\\n+\t                \"argument(s)\" 1>&2; return 1; }\n+\t                ;;\n+\t            *)\n+\t                echo \"bash: ${FUNCNAME[0]}: $1: invalid option\" 1>&2\n+\t                return 1 ;;\n+\t        esac\n+\t    done\n+\t}\n+\n+\n+\t# Reassemble command line words, excluding specified characters from the\n+\t# list of word completion separators (COMP_WORDBREAKS).\n+\t# @param $1 chars  Characters out of $COMP_WORDBREAKS which should\n+\t#     NOT be considered word breaks. This is useful for things like scp where\n+\t#     we want to return host:path and not only path, so we would pass the\n+\t#     colon (:) as $1 here.\n+\t# @param $2 words  Name of variable to return words to\n+\t# @param $3 cword  Name of variable to return cword to\n+\t#\n+\t__reassemble_comp_words_by_ref() {\n+\t    local exclude i j ref\n+\t    # Exclude word separator characters?\n+\t    if [[ $1 ]]; then\n+\t        # Yes, exclude word separator characters;\n+\t        # Exclude only those characters, which were really included\n+\t        exclude=\"${1//[^$COMP_WORDBREAKS]}\"\n+\t    fi\n+\n+\t    # Default to cword unchanged\n+\t    eval $3=$COMP_CWORD\n+\t    # Are characters excluded which were former included?\n+\t    if [[ $exclude ]]; then\n+\t        # Yes, list of word completion separators has shrunk;\n+\t        # Re-assemble words to complete\n+\t        for (( i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n+\t            # Is current word not word 0 (the command itself) and is word not\n+\t            # empty and is word made up of just word separator characters to be\n+\t            # excluded?\n+\t            while [[ $i -gt 0 && ${COMP_WORDS[$i]} &&\n+\t                ${COMP_WORDS[$i]//[^$exclude]} == ${COMP_WORDS[$i]}\n+\t            ]]; do\n+\t                [ $j -ge 2 ] && ((j--))\n+\t                # Append word separator to current word\n+\t                ref=\"$2[$j]\"\n+\t                eval $2[$j]=\\${!ref}\\${COMP_WORDS[i]}\n+\t                # Indicate new cword\n+\t                [ $i = $COMP_CWORD ] && eval $3=$j\n+\t                # Indicate next word if available, else end *both* while and for loop\n+\t                (( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2\n+\t            done\n+\t            # Append word to current word\n+\t            ref=\"$2[$j]\"\n+\t            eval $2[$j]=\\${!ref}\\${COMP_WORDS[i]}\n+\t            # Indicate new cword\n+\t            [ $i = $COMP_CWORD ] && [[ ${COMP_WORDS[i]} ]] && eval $3=$j\n+\t        done\n+\t    else\n+\t        # No, list of word completions separators hasn't changed;\n+\t        eval $2=\\( \\\"\\${COMP_WORDS[@]}\\\" \\)\n+\t    fi\n+\t} # __reassemble_comp_words_by_ref()\n+\n+\t# @param $1 exclude  Characters out of $COMP_WORDBREAKS which should NOT be\n+\t#     considered word breaks. This is useful for things like scp where\n+\t#     we want to return host:path and not only path, so we would pass the\n+\t#     colon (:) as $1 in this case.  Bash-3 doesn't do word splitting, so this\n+\t#     ensures we get the same word on both bash-3 and bash-4.\n+\t# @param $2 words  Name of variable to return words to\n+\t# @param $3 cword  Name of variable to return cword to\n+\t# @param $4 cur  Name of variable to return current word to complete to\n+\t# @see ___get_cword_at_cursor_by_ref()\n+\t__get_cword_at_cursor_by_ref() {\n+\t    local cword words=()\n+\t    __reassemble_comp_words_by_ref \"$1\" words cword\n+\n+\t    local i cur2\n+\t    local cur=\"$COMP_LINE\"\n+\t    local index=\"$COMP_POINT\"\n+\t    for (( i = 0; i <= cword; ++i )); do\n+\t        while [[\n+\t            # Current word fits in $cur?\n+\t            \"${#cur}\" -ge ${#words[i]} &&\n+\t            # $cur doesn't match cword?\n+\t            \"${cur:0:${#words[i]}}\" != \"${words[i]}\"\n+\t        ]]; do\n+\t            # Strip first character\n+\t            cur=\"${cur:1}\"\n+\t            # Decrease cursor position\n+\t            ((index--))\n+\t        done\n+\n+\t        # Does found word matches cword?\n+\t        if [[ \"$i\" -lt \"$cword\" ]]; then\n+\t            # No, cword lies further;\n+\t            local old_size=\"${#cur}\"\n+\t            cur=\"${cur#${words[i]}}\"\n+\t            local new_size=\"${#cur}\"\n+\t            index=$(( index - old_size + new_size ))\n+\t        fi\n+\t    done\n+\n+\t    if [[ \"${words[cword]:0:${#cur}}\" != \"$cur\" ]]; then\n+\t        # We messed up. At least return the whole word so things keep working\n+\t        cur2=${words[cword]}\n+\t    else\n+\t        cur2=${cur:0:$index}\n+\t    fi\n+\n+\t    local \"$2\" \"$3\" \"$4\" &&\n+\t        _upvars -a${#words[@]} $2 \"${words[@]}\" -v $3 \"$cword\" -v $4 \"$cur2\"\n+\t}\n+\n+\n+\t# Get the word to complete and optional previous words.\n+\t# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases\n+\t# where the user is completing in the middle of a word.\n+\t# (For example, if the line is \"ls foobar\",\n+\t# and the cursor is here -------->   ^\n+\t# Also one is able to cross over possible wordbreak characters.\n+\t# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]\n+\t# Available VARNAMES:\n+\t#     cur         Return cur via $cur\n+\t#     prev        Return prev via $prev\n+\t#     words       Return words via $words\n+\t#     cword       Return cword via $cword\n+\t#\n+\t# Available OPTIONS:\n+\t#     -n EXCLUDE  Characters out of $COMP_WORDBREAKS which should NOT be\n+\t#                 considered word breaks. This is useful for things like scp\n+\t#                 where we want to return host:path and not only path, so we\n+\t#                 would pass the colon (:) as -n option in this case.  Bash-3\n+\t#                 doesn't do word splitting, so this ensures we get the same\n+\t#                 word on both bash-3 and bash-4.\n+\t#     -c VARNAME  Return cur via $VARNAME\n+\t#     -p VARNAME  Return prev via $VARNAME\n+\t#     -w VARNAME  Return words via $VARNAME\n+\t#     -i VARNAME  Return cword via $VARNAME\n+\t#\n+\t# Example usage:\n+\t#\n+\t#    $ _get_comp_words_by_ref -n : cur prev\n+\t#\n+\t_get_comp_words_by_ref()\n+\t{\n+\t    local exclude flag i OPTIND=1\n+\t    local cur cword words=()\n+\t    local upargs=() upvars=() vcur vcword vprev vwords\n+\n+\t    while getopts \"c:i:n:p:w:\" flag \"$@\"; do\n+\t        case $flag in\n+\t            c) vcur=$OPTARG ;;\n+\t            i) vcword=$OPTARG ;;\n+\t            n) exclude=$OPTARG ;;\n+\t            p) vprev=$OPTARG ;;\n+\t            w) vwords=$OPTARG ;;\n+\t        esac\n+\t    done\n+\t    while [[ $# -ge $OPTIND ]]; do\n+\t        case ${!OPTIND} in\n+\t            cur)   vcur=cur ;;\n+\t            prev)  vprev=prev ;;\n+\t            cword) vcword=cword ;;\n+\t            words) vwords=words ;;\n+\t            *) echo \"bash: $FUNCNAME(): \\`${!OPTIND}': unknown argument\" \\\n+\t                1>&2; return 1\n+\t        esac\n+\t        let \"OPTIND += 1\"\n+\t    done\n+\n+\t    __get_cword_at_cursor_by_ref \"$exclude\" words cword cur\n+\n+\t    [[ $vcur   ]] && { upvars+=(\"$vcur\"  ); upargs+=(-v $vcur   \"$cur\"  ); }\n+\t    [[ $vcword ]] && { upvars+=(\"$vcword\"); upargs+=(-v $vcword \"$cword\"); }\n+\t    [[ $vprev  ]] && { upvars+=(\"$vprev\" ); upargs+=(-v $vprev\n+\t        \"${words[cword - 1]}\"); }\n+\t    [[ $vwords ]] && { upvars+=(\"$vwords\"); upargs+=(-a${#words[@]} $vwords\n+\t        \"${words[@]}\"); }\n+\n+\t    (( ${#upvars[@]} )) && local \"${upvars[@]}\" && _upvars \"${upargs[@]}\"\n+\t}\n+fi\n+\n # __gitdir accepts 0 or 1 arguments (i.e., location)\n # returns location of .git repo\n __gitdir ()\n-- \n1.7.3.2\n"},{"id":"157019","messageId":"1291236582-28603-3-git-send-email-peter@avirtualhome.com","threadId":"25912","inReplyTo":"1291236582-28603-1-git-send-email-peter@avirtualhome.com","subject":"[PATCH v4 2/2] Use the new functions to get the current cword.","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-12-01T20:49:42Z","receivedAt":"2010-12-01T20:49:42Z","isPatch":true,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"Change the completion functions to use the newly introduced functions to\nget the current and/or previous cword and to reassemble the COMP_CWORDS,\nmaking sure the options are correctly split.\n\nSigned-off-by: Peter van der Does <peter@avirtualhome.com>\n---\n contrib/completion/git-completion.bash |  223 ++++++++++++++++++++------------\n 1 files changed, 140 insertions(+), 83 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 0036e8b..f915e1f 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -554,7 +554,8 @@ __gitcomp_1 ()\n # generates completion reply with compgen\n __gitcomp ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tif [ $# -gt 2 ]; then\n \t\tcur=\"$3\"\n \tfi\n@@ -615,7 +616,8 @@ __git_tags ()\n __git_refs ()\n {\n \tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\" track=\"${2-}\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" format refs\n+\tlocal cur format refs\n+\t_get_comp_words_by_ref cur\n \tif [ -d \"$dir\" ]; then\n \t\tcase \"$cur\" in\n \t\trefs|refs/*)\n@@ -729,7 +731,8 @@ __git_compute_merge_strategies ()\n \n __git_complete_file ()\n {\n-\tlocal pfx ls ref cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal pfx ls ref cur\n+\t_get_comp_words_by_ref -n \":\" cur\n \tcase \"$cur\" in\n \t?*:*)\n \t\tref=\"${cur%%:*}\"\n@@ -777,7 +780,8 @@ __git_complete_file ()\n \n __git_complete_revlist ()\n {\n-\tlocal pfx cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal pfx cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t*...*)\n \t\tpfx=\"${cur%...*}...\"\n@@ -797,11 +801,13 @@ __git_complete_revlist ()\n \n __git_complete_remote_or_refspec ()\n {\n-\tlocal cmd=\"${COMP_WORDS[1]}\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur words cword\n+\t_get_comp_words_by_ref -n \":\" cur words cword\n+\tlocal cmd=\"${words[1]}\"\n \tlocal i c=2 remote=\"\" pfx=\"\" lhs=1 no_complete_refspec=0\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t--mirror) [ \"$cmd\" = \"push\" ] && no_complete_refspec=1 ;;\n \t\t--all)\n@@ -869,13 +875,15 @@ __git_complete_remote_or_refspec ()\n \n __git_complete_strategy ()\n {\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n \"=\" cur prev\n \t__git_compute_merge_strategies\n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"${prev}\" in\n \t-s|--strategy)\n \t\t__gitcomp \"$__git_merge_strategies\"\n \t\treturn 0\n \tesac\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\n \tcase \"$cur\" in\n \t--strategy=*)\n \t\t__gitcomp \"$__git_merge_strategies\" \"\" \"${cur##--strategy=}\"\n@@ -1048,10 +1056,11 @@ __git_aliased_command ()\n # __git_find_on_cmdline requires 1 argument\n __git_find_on_cmdline ()\n {\n-\tlocal word subcommand c=1\n+\tlocal word subcommand c=1 words cword\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\tword=\"${COMP_WORDS[c]}\"\n+\t_get_comp_words_by_ref words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\tword=\"${words[c]}\"\n \t\tfor subcommand in $1; do\n \t\t\tif [ \"$subcommand\" = \"$word\" ]; then\n \t\t\t\techo \"$subcommand\"\n@@ -1064,9 +1073,10 @@ __git_find_on_cmdline ()\n \n __git_has_doubledash ()\n {\n-\tlocal c=1\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\tif [ \"--\" = \"${COMP_WORDS[c]}\" ]; then\n+\tlocal c=1, words cword\n+\t_get_comp_words_by_ref words cword\n+\twhile [ $c -lt $cwords ]; do\n+\t\tif [ \"--\" = \"${words[c]}\" ]; then\n \t\t\treturn 0\n \t\tfi\n \t\tc=$((++c))\n@@ -1078,7 +1088,9 @@ __git_whitespacelist=\"nowarn warn error error-all fix\"\n \n _git_am ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n+\tlocal cur dir=\"$(__gitdir)\"\n+\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tif [ -d \"$dir\"/rebase-apply ]; then\n \t\t__gitcomp \"--skip --continue --resolved --abort\"\n \t\treturn\n@@ -1102,7 +1114,8 @@ _git_am ()\n \n _git_apply ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--whitespace=*)\n \t\t__gitcomp \"$__git_whitespacelist\" \"\" \"${cur##--whitespace=}\"\n@@ -1125,7 +1138,8 @@ _git_add ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1139,7 +1153,8 @@ _git_add ()\n \n _git_archive ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--format=*)\n \t\t__gitcomp \"$(git archive --list)\" \"\" \"${cur##--format=}\"\n@@ -1187,10 +1202,11 @@ _git_bisect ()\n \n _git_branch ()\n {\n-\tlocal i c=1 only_local_ref=\"n\" has_r=\"n\"\n+\tlocal i c=1 only_local_ref=\"n\" has_r=\"n\" cur words cword\n+\t_get_comp_words_by_ref cur words cword\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t-d|-m)\tonly_local_ref=\"y\" ;;\n \t\t-r)\thas_r=\"y\" ;;\n@@ -1198,7 +1214,7 @@ _git_branch ()\n \t\tc=$((++c))\n \tdone\n \n-\tcase \"${COMP_WORDS[COMP_CWORD]}\" in\n+\tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n \t\t\t--color --no-color --verbose --abbrev= --no-abbrev\n@@ -1218,8 +1234,10 @@ _git_branch ()\n \n _git_bundle ()\n {\n-\tlocal cmd=\"${COMP_WORDS[2]}\"\n-\tcase \"$COMP_CWORD\" in\n+\tlocal words cword\n+\t_get_comp_words_by_ref words cword\n+\tlocal cmd=\"${words[2]}\"\n+\tcase \"$cword\" in\n \t2)\n \t\t__gitcomp \"create list-heads verify unbundle\"\n \t\t;;\n@@ -1240,7 +1258,8 @@ _git_checkout ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--conflict=*)\n \t\t__gitcomp \"diff3 merge\" \"\" \"${cur##--conflict=}\"\n@@ -1270,7 +1289,8 @@ _git_cherry ()\n \n _git_cherry_pick ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--edit --no-commit\"\n@@ -1285,7 +1305,8 @@ _git_clean ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run --quiet\"\n@@ -1297,7 +1318,8 @@ _git_clean ()\n \n _git_clone ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1324,7 +1346,8 @@ _git_commit ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--cleanup=*)\n \t\t__gitcomp \"default strip verbatim whitespace\n@@ -1359,7 +1382,8 @@ _git_commit ()\n \n _git_describe ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1391,7 +1415,8 @@ _git_diff ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --staged --pickaxe-all --pickaxe-regex\n@@ -1412,7 +1437,8 @@ _git_difftool ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--tool=*)\n \t\t__gitcomp \"$__git_mergetools_common kompare\" \"\" \"${cur##--tool=}\"\n@@ -1437,7 +1463,8 @@ __git_fetch_options=\"\n \n _git_fetch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_fetch_options\"\n@@ -1449,7 +1476,8 @@ _git_fetch ()\n \n _git_format_patch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--thread=*)\n \t\t__gitcomp \"\n@@ -1481,7 +1509,8 @@ _git_format_patch ()\n \n _git_fsck ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1496,7 +1525,8 @@ _git_fsck ()\n \n _git_gc ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--prune --aggressive\"\n@@ -1515,7 +1545,8 @@ _git_grep ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1538,7 +1569,8 @@ _git_grep ()\n \n _git_help ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--all --info --man --web\"\n@@ -1556,7 +1588,8 @@ _git_help ()\n \n _git_init ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--shared=*)\n \t\t__gitcomp \"\n@@ -1576,7 +1609,8 @@ _git_ls_files ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --deleted --modified --others --ignored\n@@ -1630,7 +1664,8 @@ _git_log ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tlocal g=\"$(git rev-parse --git-dir 2>/dev/null)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n@@ -1689,7 +1724,8 @@ _git_merge ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_merge_options\"\n@@ -1700,7 +1736,8 @@ _git_merge ()\n \n _git_mergetool ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--tool=*)\n \t\t__gitcomp \"$__git_mergetools_common tortoisemerge\" \"\" \"${cur##--tool=}\"\n@@ -1721,7 +1758,8 @@ _git_merge_base ()\n \n _git_mv ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run\"\n@@ -1740,7 +1778,8 @@ _git_notes ()\n {\n \tlocal subcommands='add append copy edit list prune remove show'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n \"=\" cur prev\n \n \tcase \"$subcommand,$cur\" in\n \t,--*)\n@@ -1775,7 +1814,7 @@ _git_notes ()\n \tprune,*)\n \t\t;;\n \t*)\n-\t\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\t\tcase \"${prev}\" in\n \t\t-m|-F)\n \t\t\t;;\n \t\t*)\n@@ -1790,7 +1829,8 @@ _git_pull ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1806,8 +1846,9 @@ _git_pull ()\n \n _git_push ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n \"=\" cur prev\n+\tcase \"$prev\" in\n \t--repo)\n \t\t__gitcomp \"$(__git_remotes)\"\n \t\treturn\n@@ -1830,7 +1871,9 @@ _git_push ()\n \n _git_rebase ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n+\tlocal cur\n+\tlocal dir=\"$(__gitdir)\"\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tif [ -d \"$dir\"/rebase-apply ] || [ -d \"$dir\"/rebase-merge ]; then\n \t\t__gitcomp \"--continue --skip --abort\"\n \t\treturn\n@@ -1860,7 +1903,8 @@ __git_send_email_suppresscc_options=\"author self cc bodycc sob cccmd body all\"\n \n _git_send_email ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--confirm=*)\n \t\t__gitcomp \"\n@@ -1902,9 +1946,10 @@ _git_stage ()\n \n __git_config_get_set_variables ()\n {\n-\tlocal prevword word config_file= c=$COMP_CWORD\n-\twhile [ $c -gt 1 ]; do\n-\t\tword=\"${COMP_WORDS[c]}\"\n+\tlocal prevword word config_file= words cword\n+\t_get_comp_words_by_ref -n \"=\" words cword\n+\twhile [ $cword -gt 1 ]; do\n+\t\tword=\"${words[cword]}\"\n \t\tcase \"$word\" in\n \t\t--global|--system|--file=*)\n \t\t\tconfig_file=\"$word\"\n@@ -1916,7 +1961,7 @@ __git_config_get_set_variables ()\n \t\t\t;;\n \t\tesac\n \t\tprevword=$word\n-\t\tc=$((--c))\n+\t\tcword=$((--cword))\n \tdone\n \n \tgit --git-dir=\"$(__gitdir)\" config $config_file --list 2>/dev/null |\n@@ -1932,9 +1977,9 @@ __git_config_get_set_variables ()\n \n _git_config ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n-\tlocal prv=\"${COMP_WORDS[COMP_CWORD-1]}\"\n-\tcase \"$prv\" in\n+\tlocal cur prev\n+\t_get_comp_words_by_ref cur prev\n+\tcase \"$prev\" in\n \tbranch.*.remote)\n \t\t__gitcomp \"$(__git_remotes)\"\n \t\treturn\n@@ -1944,13 +1989,13 @@ _git_config ()\n \t\treturn\n \t\t;;\n \tremote.*.fetch)\n-\t\tlocal remote=\"${prv#remote.}\"\n+\t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.fetch}\"\n \t\t__gitcomp \"$(__git_refs_remotes \"$remote\")\"\n \t\treturn\n \t\t;;\n \tremote.*.push)\n-\t\tlocal remote=\"${prv#remote.}\"\n+\t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.push}\"\n \t\t__gitcomp \"$(git --git-dir=\"$(__gitdir)\" \\\n \t\t\tfor-each-ref --format='%(refname):%(refname)' \\\n@@ -2341,7 +2386,8 @@ _git_reset ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--merge --mixed --hard --soft --patch\"\n@@ -2353,7 +2399,8 @@ _git_reset ()\n \n _git_revert ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--edit --mainline --no-edit --no-commit --signoff\"\n@@ -2367,7 +2414,8 @@ _git_rm ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur=\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --dry-run --ignore-unmatch --quiet\"\n@@ -2381,7 +2429,8 @@ _git_shortlog ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2399,7 +2448,8 @@ _git_show ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n \"=\" cur\n \tcase \"$cur\" in\n \t--pretty=*)\n \t\t__gitcomp \"$__git_log_pretty_formats $(__git_pretty_aliases)\n@@ -2423,7 +2473,8 @@ _git_show ()\n \n _git_show_branch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2440,10 +2491,11 @@ _git_show_branch ()\n \n _git_stash ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n \tlocal save_opts='--keep-index --no-keep-index --quiet --patch'\n \tlocal subcommands='save list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n+\t_get_comp_words_by_ref cur\n \tif [ -z \"$subcommand\" ]; then\n \t\tcase \"$cur\" in\n \t\t--*)\n@@ -2485,7 +2537,8 @@ _git_submodule ()\n \n \tlocal subcommands=\"add status init update summary foreach sync\"\n \tif [ -z \"$(__git_find_on_cmdline \"$subcommands\")\" ]; then\n-\t\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\t\tlocal cur\n+\t\t_get_comp_words_by_ref cur\n \t\tcase \"$cur\" in\n \t\t--*)\n \t\t\t__gitcomp \"--quiet --cached\"\n@@ -2529,7 +2582,8 @@ _git_svn ()\n \t\t\t--edit --rmdir --find-copies-harder --copy-similarity=\n \t\t\t\"\n \n-\t\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\t\tlocal cur\n+\t\t_get_comp_words_by_ref cur\n \t\tcase \"$subcommand,$cur\" in\n \t\tfetch,--*)\n \t\t\t__gitcomp \"--revision= --fetch-all $fc_opts\"\n@@ -2600,9 +2654,10 @@ _git_svn ()\n \n _git_tag ()\n {\n-\tlocal i c=1 f=0\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\tlocal i c=1 f=0 words cword prev\n+\t_get_comp_words_by_ref prev words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t-d|-v)\n \t\t\t__gitcomp \"$(__git_tags)\"\n@@ -2615,7 +2670,7 @@ _git_tag ()\n \t\tc=$((++c))\n \tdone\n \n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"${prev}\" in\n \t-m|-F)\n \t\tCOMPREPLY=()\n \t\t;;\n@@ -2639,15 +2694,16 @@ _git_whatchanged ()\n \n _git ()\n {\n-\tlocal i c=1 command __git_dir\n+\tlocal i c=1 command __git_dir words cword\n \n-\tif [[ -n ${ZSH_VERSION-} ]]; then\n+\tif [[ -n $ZSH_VERSION ]]; then\n \t\temulate -L bash\n \t\tsetopt KSH_TYPESET\n \tfi\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\t_get_comp_words_by_ref -n \"=\" words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t--git-dir=*) __git_dir=\"${i#--git-dir=}\" ;;\n \t\t--bare)      __git_dir=\".\" ;;\n@@ -2659,7 +2715,7 @@ _git ()\n \tdone\n \n \tif [ -z \"$command\" ]; then\n-\t\tcase \"${COMP_WORDS[COMP_CWORD]}\" in\n+\t\tcase \"${words[cword]}\" in\n \t\t--*)   __gitcomp \"\n \t\t\t--paginate\n \t\t\t--no-pager\n@@ -2690,19 +2746,20 @@ _git ()\n \n _gitk ()\n {\n-\tif [[ -n ${ZSH_VERSION-} ]]; then\n+\tif [[ -n $ZSH_VERSION ]]; then\n \t\temulate -L bash\n \t\tsetopt KSH_TYPESET\n \tfi\n \n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n \tlocal g=\"$(__gitdir)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n \t\tmerge=\"--merge\"\n \tfi\n+\t_get_comp_words_by_ref cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2730,7 +2787,7 @@ complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \\\n \t|| complete -o default -o nospace -F _git git.exe\n fi\n \n-if [[ -n ${ZSH_VERSION-} ]]; then\n+if [[ -n $ZSH_VERSION ]]; then\n \tshopt () {\n \t\tlocal option\n \t\tif [ $# -ne 2 ]; then\n-- \n1.7.3.2\n"},{"id":"157025","messageId":"20101201210910.GD27845@burratino","threadId":"25912","inReplyTo":"1291236582-28603-1-git-send-email-peter@avirtualhome.com","subject":"Re: [PATCH v4 0/2] Make git-completion Bash 4 compatible","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-01T21:09:10Z","receivedAt":"2010-12-01T21:09:10Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Peter van der Does wrote:\n\n> - Patch is based upon the next branch.\n\nPlease don't do that.  Documentation/SubmittingPatches explains\n(section \"(0) Decide what to base your work on\").\n\n> - Grammatical error in commit message\n\nThanks, I'll look over this version then.\n"},{"id":"157067","messageId":"20101202011048.GA5039@neumann","threadId":"25912","inReplyTo":"1291236582-28603-1-git-send-email-peter@avirtualhome.com","subject":"Re: [PATCH v4 0/2] Make git-completion Bash 4 compatible.","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-12-02T01:10:48Z","receivedAt":"2010-12-02T01:10:48Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\nOn Wed, Dec 01, 2010 at 03:49:40PM -0500, Peter van der Does wrote:\n> *** BLURB HERE ***\n> Make git-completion Bash 4 compatible.\n> \n> I've made the following changes since v3:\n> - Patch is based upon the next branch.\n> - Grammatical error in commit message\n\nI have a few little changes to fix some minor nits and bugs.  Will try\nto find some time tomorrow to dig them up and send them to the list.\n\n\nBest,\nGábor\n"},{"id":"157090","messageId":"20101202074504.GA1771@burratino","threadId":"25912","inReplyTo":"1291236582-28603-3-git-send-email-peter@avirtualhome.com","subject":"Re: [PATCH v4 2/2] Use the new functions to get the current cword.","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-02T07:45:04Z","receivedAt":"2010-12-02T07:45:04Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi Peter,\n\nPeter van der Does wrote:\n\n> Change the completion functions to use the newly introduced functions to\n> get the current and/or previous cword and to reassemble the COMP_CWORDS,\n> making sure the options are correctly split.\n\nSome comments.  Please don't reroll until discussion has quieted down\n(though thoughts and incremental patches would always be welcome, of\ncourse).\n\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -554,7 +554,8 @@ __gitcomp_1 ()\n>  # generates completion reply with compgen\n>  __gitcomp ()\n>  {\n> -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal cur\n> +\t_get_comp_words_by_ref -n \"=\" cur\n\nTo save the reader some time: this excludes '=' from word-breaking\ncharacters, so $cur will include an = when appropriate.  IIUC that is\nprecisely the behavior that bash 4 changed.\n\nPerhaps that is worth explaining in the commit message in the next\nround?\n\n> @@ -615,7 +616,8 @@ __git_tags ()\n>  __git_refs ()\n>  {\n>  \tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\" track=\"${2-}\"\n> -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" format refs\n> +\tlocal cur format refs\n> +\t_get_comp_words_by_ref cur\n\nThis does not exclude '=' from word-breaking characters.  Would that\nbreak completion of\n\n\tgit update-ref refs/topics/foo=bar HEAD\n\tgit checkout refs/topics/foo=<tab><tab>\n\n?\n\n> @@ -729,7 +731,8 @@ __git_compute_merge_strategies ()\n>  \n>  __git_complete_file ()\n>  {\n> -\tlocal pfx ls ref cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal pfx ls ref cur\n> +\t_get_comp_words_by_ref -n \":\" cur\n\nThis treats '=' as a word-breaking character but not ':'.  Is that\nthe right behavior?\n\n> @@ -777,7 +780,8 @@ __git_complete_file ()\n>  \n>  __git_complete_revlist ()\n>  {\n> -\tlocal pfx cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal pfx cur\n> +\t_get_comp_words_by_ref cur\n\n'=' and ':' are word-breakers.\n\n> @@ -797,11 +801,13 @@ __git_complete_revlist ()\n>  \n>  __git_complete_remote_or_refspec ()\n>  {\n> -\tlocal cmd=\"${COMP_WORDS[1]}\"\n> -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal cur words cword\n> +\t_get_comp_words_by_ref -n \":\" cur words cword\n> +\tlocal cmd=\"${words[1]}\"\n\n'=' is a word-breaker, ':' not.\n\n> @@ -869,13 +875,15 @@ __git_complete_remote_or_refspec ()\n>  \n>  __git_complete_strategy ()\n>  {\n> +\tlocal cur prev\n> +\t_get_comp_words_by_ref -n \"=\" cur prev\n\n'=' is not a wordbreaker, so --strategy= can be completed correctly.\n\n> @@ -1048,10 +1056,11 @@ __git_aliased_command ()\n>  # __git_find_on_cmdline requires 1 argument\n>  __git_find_on_cmdline ()\n>  {\n> -\tlocal word subcommand c=1\n> +\tlocal word subcommand c=1 words cword\n>  \n> -\twhile [ $c -lt $COMP_CWORD ]; do\n> -\t\tword=\"${COMP_WORDS[c]}\"\n> +\t_get_comp_words_by_ref words cword\n\n':' and '=' are word-breakers when completing subcommand names.\n\n> @@ -1064,9 +1073,10 @@ __git_find_on_cmdline ()\n>  \n>  __git_has_doubledash ()\n>  {\n> -\tlocal c=1\n> -\twhile [ $c -lt $COMP_CWORD ]; do\n> -\t\tif [ \"--\" = \"${COMP_WORDS[c]}\" ]; then\n> +\tlocal c=1, words cword\n\nExtra comma.\n\n> +\t_get_comp_words_by_ref words cword\n\n':' and '=' are word-breakers when looking for \"--\".\n\n[etc]\n\nSo in general, it seems that : and = are treated as word-breakers\nafter this change much more often than git itself would treat them\nas such.  Is that intentional?  What rule is used to choose -n\narguments?\n"},{"id":"157095","messageId":"20101202091624.GB1771@burratino","threadId":"25912","inReplyTo":"1291236582-28603-1-git-send-email-peter@avirtualhome.com","subject":"Re: [PATCH v4 0/2] Make git-completion Bash 4 compatible","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-02T09:16:24Z","receivedAt":"2010-12-02T09:16:24Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi again,\n\nPeter van der Does wrote:\n\n> Make git-completion Bash 4 compatible.\n\nThanks again for this work and sorry for all the fuss.\n\n> Peter van der Does (2):\n>   Introduce functions from bash-completion project.\n\nThis patch introduces a minor regression in that it breaks the\n(already somewhat incomplete) zsh support.  Should be fixable by\nfalling back to using COMP_WORDS on zsh.\n\n>   Use the new functions to get the current cword.\n\nThis one introduces some subtle differences between commands and imho\ndoes more than it set out to do, by differentiating word splitting\nbehavior between commands.  bash 3 was not splitting COMP_WORDS at\nequal signs or colons, ever.  Maybe we can start with that and then\nmake refinements on top later.\n\nWhile trying that out, I had an idea.  The patch depends on\nunderstanding the bash-completion library function introduced by patch\n1, but I think we can avoid that by rearranging the patch series like\nthis:\n\n 1. If _get_comp_words_by_ref is already defined, use it to fetch\n    completion words.  Otherwise, just use COMP_WORDS (using a stub\n    _get_comp_words_by_ref), maintaining the current behavior.\n    [shown below]\n\n 2. Import the definition of _get_comp_words_by_ref from the\n    bash-completion lib and use it if ZSH_VERSION is unset.\n\n 3. Further refinements, if needed.\n\nWhat do you think?\n\n-- 8< --\nFrom: Peter van der Does <peter@avirtualhome.com>\nSubject: bash: work around bash 4.0 change in COMP_WORDS semantics\n\nBefore bash 4, running\n\n\t$ git log --pretty=m <tab><tab>\n\nwould give a list of pretty formats starting with 'm', but now it\ncompletes on ordinary files instead.  It seems that as part of a\nrework of completion word splitting, bash 4.0 changed the semantics of\nthe COMP_WORDS array: previously, --pretty=m was treated as one word,\nbut now it breaks on '=' if COMP_WORDBREAKS contains an equal sign.\n\nIt would be possible to work around that by removing '=' and ':' from\nCOMP_WORDBREAKS, but as noticed in v1.5.6.4~9^2 (bash completion:\nResolve git show ref:path<tab> losing ref: portion, 2008-07-15), doing\nso is likely to break *other* completion scripts.  Luckily, the\nbash-completion library includes a better workaround --- a\n_get_comp_words_by_ref function to retrieve an array somewhat like\nCOMP_WORDS but:\n\n * excluding some word break characters of your choice\n * returning correct results even when the cursor is in the middle of\n   a word.\n\nUse it.  To avoid breaking setups where the bash-completion library is\nnot already loaded, if that function is not defined then a shim\nreplacement that just reads COMP_WORDS will be used instead.\n\nSigned-off-by: Peter van der Does <peter@avirtualhome.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/completion/git-completion.bash |  236 +++++++++++++++++++++----------\n 1 files changed, 160 insertions(+), 76 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex feab651..0b0eb45 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -327,11 +327,39 @@ __gitcomp_1 ()\n \tdone\n }\n \n+if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n+_get_comp_words_by_ref ()\n+{\n+\twhile [ $# -gt 0 ]; do\n+\t\tcase \"$1\" in\n+\t\tcur)\n+\t\t\tcur=${COMP_WORDS[COMP_CWORD]}\n+\t\t\t;;\n+\t\tprev)\n+\t\t\tprev=${COMP_WORDS[COMP_CWORD-1]}\n+\t\t\t;;\n+\t\twords)\n+\t\t\twords=(\"${COMP_WORDS[@]}\")\n+\t\t\t;;\n+\t\tcword)\n+\t\t\tcword=$COMP_CWORD\n+\t\t\t;;\n+\t\t-n)\n+\t\t\t# assume COMP_WORDBREAKS is already set sanely\n+\t\t\tshift\n+\t\t\t;;\n+\t\tesac\n+\t\tshift\n+\tdone\n+}\n+fi\n+\n # __gitcomp accepts 1, 2, 3, or 4 arguments\n # generates completion reply with compgen\n __gitcomp ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tif [ $# -gt 2 ]; then\n \t\tcur=\"$3\"\n \tfi\n@@ -390,7 +418,8 @@ __git_tags ()\n __git_refs ()\n {\n \tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" format refs\n+\tlocal cur format refs\n+\t_get_comp_words_by_ref -n =: cur\n \tif [ -d \"$dir\" ]; then\n \t\tcase \"$cur\" in\n \t\trefs|refs/*)\n@@ -488,7 +517,8 @@ __git_compute_merge_strategies ()\n \n __git_complete_file ()\n {\n-\tlocal pfx ls ref cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal pfx ls ref cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t?*:*)\n \t\tref=\"${cur%%:*}\"\n@@ -536,7 +566,8 @@ __git_complete_file ()\n \n __git_complete_revlist ()\n {\n-\tlocal pfx cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal pfx cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t*...*)\n \t\tpfx=\"${cur%...*}...\"\n@@ -556,11 +587,12 @@ __git_complete_revlist ()\n \n __git_complete_remote_or_refspec ()\n {\n-\tlocal cmd=\"${COMP_WORDS[1]}\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur words cword\n+\t_get_comp_words_by_ref -n =: cur words cword\n+\tlocal cmd=\"${words[1]}\"\n \tlocal i c=2 remote=\"\" pfx=\"\" lhs=1 no_complete_refspec=0\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t--mirror) [ \"$cmd\" = \"push\" ] && no_complete_refspec=1 ;;\n \t\t--all)\n@@ -628,13 +660,14 @@ __git_complete_remote_or_refspec ()\n \n __git_complete_strategy ()\n {\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n =: cur prev\n \t__git_compute_merge_strategies\n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"$prev\" in\n \t-s|--strategy)\n \t\t__gitcomp \"$__git_merge_strategies\"\n \t\treturn 0\n \tesac\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n \tcase \"$cur\" in\n \t--strategy=*)\n \t\t__gitcomp \"$__git_merge_strategies\" \"\" \"${cur##--strategy=}\"\n@@ -794,10 +827,10 @@ __git_aliased_command ()\n # __git_find_on_cmdline requires 1 argument\n __git_find_on_cmdline ()\n {\n-\tlocal word subcommand c=1\n-\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\tword=\"${COMP_WORDS[c]}\"\n+\tlocal word subcommand c=1 words cword\n+\t_get_comp_words_by_ref -n =: words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\tword=\"${words[c]}\"\n \t\tfor subcommand in $1; do\n \t\t\tif [ \"$subcommand\" = \"$word\" ]; then\n \t\t\t\techo \"$subcommand\"\n@@ -810,9 +843,10 @@ __git_find_on_cmdline ()\n \n __git_has_doubledash ()\n {\n-\tlocal c=1\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\tif [ \"--\" = \"${COMP_WORDS[c]}\" ]; then\n+\tlocal c=1 words cword\n+\t_get_comp_words_by_ref -n =: words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\tif [ \"--\" = \"${words[c]}\" ]; then\n \t\t\treturn 0\n \t\tfi\n \t\tc=$((++c))\n@@ -824,7 +858,8 @@ __git_whitespacelist=\"nowarn warn error error-all fix\"\n \n _git_am ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n+\tlocal cur dir=\"$(__gitdir)\"\n+\t_get_comp_words_by_ref -n =: cur\n \tif [ -d \"$dir\"/rebase-apply ]; then\n \t\t__gitcomp \"--skip --continue --resolved --abort\"\n \t\treturn\n@@ -848,7 +883,8 @@ _git_am ()\n \n _git_apply ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--whitespace=*)\n \t\t__gitcomp \"$__git_whitespacelist\" \"\" \"${cur##--whitespace=}\"\n@@ -871,7 +907,8 @@ _git_add ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -885,7 +922,8 @@ _git_add ()\n \n _git_archive ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--format=*)\n \t\t__gitcomp \"$(git archive --list)\" \"\" \"${cur##--format=}\"\n@@ -929,10 +967,11 @@ _git_bisect ()\n \n _git_branch ()\n {\n-\tlocal i c=1 only_local_ref=\"n\" has_r=\"n\"\n+\tlocal i c=1 only_local_ref=\"n\" has_r=\"n\" cur words cword\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\t_get_comp_words_by_ref -n =: cur words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t-d|-m)\tonly_local_ref=\"y\" ;;\n \t\t-r)\thas_r=\"y\" ;;\n@@ -940,7 +979,7 @@ _git_branch ()\n \t\tc=$((++c))\n \tdone\n \n-\tcase \"${COMP_WORDS[COMP_CWORD]}\" in\n+\tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n \t\t\t--color --no-color --verbose --abbrev= --no-abbrev\n@@ -960,8 +999,10 @@ _git_branch ()\n \n _git_bundle ()\n {\n-\tlocal cmd=\"${COMP_WORDS[2]}\"\n-\tcase \"$COMP_CWORD\" in\n+\tlocal words cword\n+\t_get_comp_words_by_ref -n =: words cword\n+\tlocal cmd=\"${words[2]}\"\n+\tcase \"$cword\" in\n \t2)\n \t\t__gitcomp \"create list-heads verify unbundle\"\n \t\t;;\n@@ -982,7 +1023,8 @@ _git_checkout ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--conflict=*)\n \t\t__gitcomp \"diff3 merge\" \"\" \"${cur##--conflict=}\"\n@@ -1006,7 +1048,8 @@ _git_cherry ()\n \n _git_cherry_pick ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--edit --no-commit\"\n@@ -1021,7 +1064,8 @@ _git_clean ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run --quiet\"\n@@ -1033,7 +1077,8 @@ _git_clean ()\n \n _git_clone ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1060,7 +1105,8 @@ _git_commit ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--cleanup=*)\n \t\t__gitcomp \"default strip verbatim whitespace\n@@ -1095,7 +1141,8 @@ _git_commit ()\n \n _git_describe ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1127,7 +1174,8 @@ _git_diff ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --staged --pickaxe-all --pickaxe-regex\n@@ -1148,7 +1196,8 @@ _git_difftool ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--tool=*)\n \t\t__gitcomp \"$__git_mergetools_common kompare\" \"\" \"${cur##--tool=}\"\n@@ -1173,7 +1222,8 @@ __git_fetch_options=\"\n \n _git_fetch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_fetch_options\"\n@@ -1185,7 +1235,8 @@ _git_fetch ()\n \n _git_format_patch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--thread=*)\n \t\t__gitcomp \"\n@@ -1217,7 +1268,8 @@ _git_format_patch ()\n \n _git_fsck ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1232,7 +1284,8 @@ _git_fsck ()\n \n _git_gc ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--prune --aggressive\"\n@@ -1251,7 +1304,8 @@ _git_grep ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1274,7 +1328,8 @@ _git_grep ()\n \n _git_help ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--all --info --man --web\"\n@@ -1292,7 +1347,8 @@ _git_help ()\n \n _git_init ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--shared=*)\n \t\t__gitcomp \"\n@@ -1312,7 +1368,8 @@ _git_ls_files ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --deleted --modified --others --ignored\n@@ -1366,12 +1423,13 @@ _git_log ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n \tlocal g=\"$(git rev-parse --git-dir 2>/dev/null)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n \t\tmerge=\"--merge\"\n \tfi\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--pretty=*)\n \t\t__gitcomp \"$__git_log_pretty_formats\n@@ -1425,7 +1483,8 @@ _git_merge ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_merge_options\"\n@@ -1436,7 +1495,8 @@ _git_merge ()\n \n _git_mergetool ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--tool=*)\n \t\t__gitcomp \"$__git_mergetools_common tortoisemerge\" \"\" \"${cur##--tool=}\"\n@@ -1457,7 +1517,8 @@ _git_merge_base ()\n \n _git_mv ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run\"\n@@ -1475,12 +1536,14 @@ _git_name_rev ()\n _git_notes ()\n {\n \tlocal subcommands=\"edit show\"\n+\tlocal words cword\n+\t_get_comp_words_by_ref -n =: words cword\n \tif [ -z \"$(__git_find_on_cmdline \"$subcommands\")\" ]; then\n \t\t__gitcomp \"$subcommands\"\n \t\treturn\n \tfi\n \n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"${words[cword-1]}\" in\n \t-m|-F)\n \t\tCOMPREPLY=()\n \t\t;;\n@@ -1494,7 +1557,8 @@ _git_pull ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1510,8 +1574,9 @@ _git_pull ()\n \n _git_push ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n =: cur prev\n+\tcase \"$prev\" in\n \t--repo)\n \t\t__gitcomp \"$(__git_remotes)\"\n \t\treturn\n@@ -1534,7 +1599,9 @@ _git_push ()\n \n _git_rebase ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n+\tlocal dir=\"$(__gitdir)\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tif [ -d \"$dir\"/rebase-apply ] || [ -d \"$dir\"/rebase-merge ]; then\n \t\t__gitcomp \"--continue --skip --abort\"\n \t\treturn\n@@ -1564,7 +1631,8 @@ __git_send_email_suppresscc_options=\"author self cc bodycc sob cccmd body all\"\n \n _git_send_email ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--confirm=*)\n \t\t__gitcomp \"\n@@ -1606,9 +1674,11 @@ _git_stage ()\n \n __git_config_get_set_variables ()\n {\n-\tlocal prevword word config_file= c=$COMP_CWORD\n+\tlocal words cword\n+\t_get_comp_words_by_ref -n =: words cword\n+\tlocal prevword word config_file= c=$cword\n \twhile [ $c -gt 1 ]; do\n-\t\tword=\"${COMP_WORDS[c]}\"\n+\t\tword=\"${words[c]}\"\n \t\tcase \"$word\" in\n \t\t--global|--system|--file=*)\n \t\t\tconfig_file=\"$word\"\n@@ -1636,9 +1706,9 @@ __git_config_get_set_variables ()\n \n _git_config ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n-\tlocal prv=\"${COMP_WORDS[COMP_CWORD-1]}\"\n-\tcase \"$prv\" in\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n =: cur prev\n+\tcase \"$prev\" in\n \tbranch.*.remote)\n \t\t__gitcomp \"$(__git_remotes)\"\n \t\treturn\n@@ -1648,13 +1718,13 @@ _git_config ()\n \t\treturn\n \t\t;;\n \tremote.*.fetch)\n-\t\tlocal remote=\"${prv#remote.}\"\n+\t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.fetch}\"\n \t\t__gitcomp \"$(__git_refs_remotes \"$remote\")\"\n \t\treturn\n \t\t;;\n \tremote.*.push)\n-\t\tlocal remote=\"${prv#remote.}\"\n+\t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.push}\"\n \t\t__gitcomp \"$(git --git-dir=\"$(__gitdir)\" \\\n \t\t\tfor-each-ref --format='%(refname):%(refname)' \\\n@@ -2045,7 +2115,8 @@ _git_reset ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--merge --mixed --hard --soft --patch\"\n@@ -2057,7 +2128,8 @@ _git_reset ()\n \n _git_revert ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--edit --mainline --no-edit --no-commit --signoff\"\n@@ -2071,7 +2143,8 @@ _git_rm ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --dry-run --ignore-unmatch --quiet\"\n@@ -2085,7 +2158,8 @@ _git_shortlog ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2103,7 +2177,8 @@ _git_show ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--pretty=*)\n \t\t__gitcomp \"$__git_log_pretty_formats\n@@ -2127,7 +2202,8 @@ _git_show ()\n \n _git_show_branch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2144,7 +2220,8 @@ _git_show_branch ()\n \n _git_stash ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tlocal save_opts='--keep-index --no-keep-index --quiet --patch'\n \tlocal subcommands='save list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n@@ -2189,7 +2266,8 @@ _git_submodule ()\n \n \tlocal subcommands=\"add status init update summary foreach sync\"\n \tif [ -z \"$(__git_find_on_cmdline \"$subcommands\")\" ]; then\n-\t\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\t\tlocal cur\n+\t\t_get_comp_words_by_ref -n =: cur\n \t\tcase \"$cur\" in\n \t\t--*)\n \t\t\t__gitcomp \"--quiet --cached\"\n@@ -2233,7 +2311,8 @@ _git_svn ()\n \t\t\t--edit --rmdir --find-copies-harder --copy-similarity=\n \t\t\t\"\n \n-\t\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\t\tlocal cur\n+\t\t_get_comp_words_by_ref -n =: cur\n \t\tcase \"$subcommand,$cur\" in\n \t\tfetch,--*)\n \t\t\t__gitcomp \"--revision= --fetch-all $fc_opts\"\n@@ -2305,8 +2384,10 @@ _git_svn ()\n _git_tag ()\n {\n \tlocal i c=1 f=0\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\tlocal words cword prev\n+\t_get_comp_words_by_ref -n =: words cword prev\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t-d|-v)\n \t\t\t__gitcomp \"$(__git_tags)\"\n@@ -2319,7 +2400,7 @@ _git_tag ()\n \t\tc=$((++c))\n \tdone\n \n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"$prev\" in\n \t-m|-F)\n \t\tCOMPREPLY=()\n \t\t;;\n@@ -2350,8 +2431,10 @@ _git ()\n \t\tsetopt KSH_TYPESET\n \tfi\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\tlocal cur words cword\n+\t_get_comp_words_by_ref -n =: cur words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t--git-dir=*) __git_dir=\"${i#--git-dir=}\" ;;\n \t\t--bare)      __git_dir=\".\" ;;\n@@ -2363,7 +2446,7 @@ _git ()\n \tdone\n \n \tif [ -z \"$command\" ]; then\n-\t\tcase \"${COMP_WORDS[COMP_CWORD]}\" in\n+\t\tcase \"$cur\" in\n \t\t--*)   __gitcomp \"\n \t\t\t--paginate\n \t\t\t--no-pager\n@@ -2401,12 +2484,13 @@ _gitk ()\n \n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n \tlocal g=\"$(__gitdir)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n \t\tmerge=\"--merge\"\n \tfi\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n-- \n1.7.2.3\n"},{"id":"157115","messageId":"20101202091613.6ac8f816@MonteCarlo.grandprix.int","threadId":"25912","inReplyTo":"20101202091624.GB1771@burratino","subject":"Re: [PATCH v4 0/2] Make git-completion Bash 4 compatible","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-12-02T14:16:13Z","receivedAt":"2010-12-02T14:16:13Z","isPatch":true,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"On Thu, 2 Dec 2010 03:16:24 -0600\nJonathan Nieder <jrnieder@gmail.com> wrote:\n\n> Hi again,\n> \n> Peter van der Does wrote:\n> \n> > Make git-completion Bash 4 compatible.\n> \n> Thanks again for this work and sorry for all the fuss.\n> \n> > Peter van der Does (2):\n> >   Introduce functions from bash-completion project.\n> \n> This patch introduces a minor regression in that it breaks the\n> (already somewhat incomplete) zsh support.  Should be fixable by\n> falling back to using COMP_WORDS on zsh.\n> \n> >   Use the new functions to get the current cword.\n> \n> This one introduces some subtle differences between commands and imho\n> does more than it set out to do, by differentiating word splitting\n> behavior between commands.  bash 3 was not splitting COMP_WORDS at\n> equal signs or colons, ever.  Maybe we can start with that and then\n> make refinements on top later.\n> \n> While trying that out, I had an idea.  The patch depends on\n> understanding the bash-completion library function introduced by patch\n> 1, but I think we can avoid that by rearranging the patch series like\n> this:\n> \n>  1. If _get_comp_words_by_ref is already defined, use it to fetch\n>     completion words.  Otherwise, just use COMP_WORDS (using a stub\n>     _get_comp_words_by_ref), maintaining the current behavior.\n>     [shown below]\n> \n>  2. Import the definition of _get_comp_words_by_ref from the\n>     bash-completion lib and use it if ZSH_VERSION is unset.\n> \n>  3. Further refinements, if needed.\n> \n> What do you think?\n> \n\nI like the idea and we should go with this solution.\n\nIf by importing you mean using :\n[CODE]. /git_bash_completion-functions[/CODE] in the\ncontrib/completion/git-completion.bash script, which would be the best\nsolution imho. The question is where to place that the function file.\n\nThis would also means changing the documentation inside the\ngit-completion.bash script, currently the instructions are:\n[QUOTE]\n# To use these routines:\n#\n#    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).\n#    2) Added the following line to your .bashrc:\n#        source ~/.git-completion.sh\n[/QUOTE]\n\nIt would have to include copying the functions file somewhere as well.\n\nOr we could use the method used now and include the functions in the\ngit-completion.bash script.\n\nI'll be waiting for further feedback from Gábor, as he mentioned on the\nlist of he had some little changes to fix some minor nits and bugs\nbefore completely implementing this solution.\n\n-- \nPeter van der Does\n\nGPG key: E77E8E98\n\nIRC: Ganseki on irc.freenode.net\nTwitter: @petervanderdoes\n"},{"id":"157154","messageId":"20101202210207.GA4994@burratino","threadId":"25912","inReplyTo":"20101202091613.6ac8f816@MonteCarlo.grandprix.int","subject":"[RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-02T21:02:07Z","receivedAt":"2010-12-02T21:02:07Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a minimal implementation of _get_comp_words_by_ref,\nthe routine used to work around bash 4.0's COMP_WORDS semantics.\n\nBased on bash-completion 2.x (commit bf763033, 2010-10-26) but\ntweaked for simplicity and to allow zsh to at least parse the\ncode.\n\nBased-on-patch-by: Peter van der Does <peter@avirtualhome.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nPeter van der Does wrote:\n> Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n>>  2. Import the definition of _get_comp_words_by_ref from the\n>>     bash-completion lib and use it if ZSH_VERSION is unset.\n>> \n>>  3. Further refinements, if needed.\n>> \n>> What do you think?\n>\n> I like the idea and we should go with this solution.\n> \n> If by importing you mean using :\n> [CODE]. /git_bash_completion-functions[/CODE] in the\n> contrib/completion/git-completion.bash script, which would be the best\n> solution imho. The question is where to place that the function file.\n[...]\n> It would have to include copying the functions file somewhere as well.\n> \n> Or we could use the method used now and include the functions in the\n> git-completion.bash script.\n\nSorry for the lack of clarity.  Here's what I meant.\n\n contrib/completion/git-completion.bash |  125 ++++++++++++++++++++++++++++++++\n 1 files changed, 125 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 0b0eb45..1743319 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -327,7 +327,102 @@ __gitcomp_1 ()\n \tdone\n }\n \n+# The following function is based on code from:\n+#\n+#   bash_completion - programmable completion functions for bash 3.2+\n+#\n+#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>\n+#             © 2009-2010, Bash Completion Maintainers\n+#                     <bash-completion-devel@lists.alioth.debian.org>\n+#\n+#   This program is free software; you can redistribute it and/or modify\n+#   it under the terms of the GNU General Public License as published by\n+#   the Free Software Foundation; either version 2, or (at your option)\n+#   any later version.\n+#\n+#   This program is distributed in the hope that it will be useful,\n+#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+#   GNU General Public License for more details.\n+#\n+#   You should have received a copy of the GNU General Public License\n+#   along with this program; if not, write to the Free Software Foundation,\n+#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n+#\n+#   The latest version of this software can be obtained here:\n+#\n+#   http://bash-completion.alioth.debian.org/\n+#\n+#   RELEASE: 2.x\n+\n+# This function can be used to access a tokenized list of words\n+# on the command line:\n+#\n+#\t__reassemble_comp_words_by_ref '=:'\n+#\tif test \"${words_[cword_-1]}\" = -w\n+#\tthen\n+#\t\t...\n+#\tfi\n+#\n+# The argument should be a collection of characters from the list of\n+# word completion separators (COMP_WORDBREAKS) to treat as ordinary\n+# characters.\n+#\n+# This is roughly equivalent to locally setting COMP_WORDBREAKS to\n+# exclude those characters, but it does not clobber COMP_WORDBREAKS.\n+# The intent is for it to be used by commands like ssh that want to\n+# treat host:path as one token.\n+#\n+# Output: words_, cword_, cur_.\n+\n+__git_reassemble_comp_words_by_ref()\n+{\n+\tlocal exclude i j first\n+\t# Which word separators to exclude?\n+\texclude=\"${1//[^$COMP_WORDBREAKS]}\"\n+\tcword_=$COMP_CWORD\n+\tif [ -z \"$exclude\" ]; then\n+\t\twords_=(\"${COMP_WORDS[@]}\")\n+\t\treturn\n+\tfi\n+\t# List of word completion separators has shrunk;\n+\t# re-assemble words to complete.\n+\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n+\t\t# Append each nonempty word consisting of just\n+\t\t# word separator characters to the current word.\n+\t\tfirst=t\n+\t\twhile\n+\t\t\t[ $i -gt 0 ] &&\n+\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n+\t\t\t# word consists of excluded word separators\n+\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n+\t\tdo\n+\t\t\t# Attach to the previous token,\n+\t\t\t# unless the previous token is the command name.\n+\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n+\t\t\t\t((j--))\n+\t\t\tfi\n+\t\t\tfirst=\n+\t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n+\t\t\tif [ $i = $COMP_CWORD ]; then\n+\t\t\t\tcword_=$j\n+\t\t\tfi\n+\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n+\t\t\t\t((i++))\n+\t\t\telse\n+\t\t\t\t# Done.\n+\t\t\t\treturn\n+\t\t\tfi\n+\t\tdone\n+\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n+\t\tif [ $i = $COMP_CWORD ]; then\n+\t\t\tcword_=$j\n+\t\tfi\n+\tdone\n+}\n+\n if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n+if [[ -n $ZSH_VERSION ]]; then\n _get_comp_words_by_ref ()\n {\n \twhile [ $# -gt 0 ]; do\n@@ -352,6 +447,36 @@ _get_comp_words_by_ref ()\n \t\tshift\n \tdone\n }\n+else\n+_get_comp_words_by_ref ()\n+{\n+\tlocal exclude cur_ cword_\n+\tlocal words_=()\n+\tif [ \"$1\" = \"-n\" ]; then\n+\t\texclude=$2\n+\t\tshift 2\n+\tfi\n+\t__git_reassemble_comp_words_by_ref \"$exclude\"\n+\tcur_=${words_[cword_]}\n+\twhile [ $# -gt 0 ]; do\n+\t\tcase \"$1\" in\n+\t\tcur)\n+\t\t\tcur=$cur_\n+\t\t\t;;\n+\t\tprev)\n+\t\t\tprev=${words_[$cword_-1]}\n+\t\t\t;;\n+\t\twords)\n+\t\t\twords=(\"${words_[@]}\")\n+\t\t\t;;\n+\t\tcword)\n+\t\t\tcword=$cword_\n+\t\t\t;;\n+\t\tesac\n+\t\tshift\n+\tdone\n+}\n+fi\n fi\n \n # __gitcomp accepts 1, 2, 3, or 4 arguments\n-- \n1.7.2.3\n"},{"id":"157159","messageId":"20101202223601.GA3577@neumann","threadId":"25912","inReplyTo":"1291236582-28603-3-git-send-email-peter@avirtualhome.com","subject":"Re: [PATCH v4 2/2] Use the new functions to get the current cword.","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-12-02T22:36:01Z","receivedAt":"2010-12-02T22:36:01Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\n\nHere are my nits I mentioned yesterday.\n\nOn Wed, Dec 01, 2010 at 03:49:42PM -0500, Peter van der Does wrote:\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 0036e8b..f915e1f 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n\n> @@ -1064,9 +1073,10 @@ __git_find_on_cmdline ()\n>  \n>  __git_has_doubledash ()\n>  {\n> -\tlocal c=1\n> -\twhile [ $c -lt $COMP_CWORD ]; do\n> -\t\tif [ \"--\" = \"${COMP_WORDS[c]}\" ]; then\n> +\tlocal c=1, words cword\n\nNo comma, and ...\n\n> +\t_get_comp_words_by_ref words cword\n> +\twhile [ $c -lt $cwords ]; do\n\n... that should be $cword in the condition, without the s at the end.\nThese two typos caused some weird behaviors when completing long\noptions for commands understanding the '--' option-path separator,\ne.g. git diff --<TAB<TAB>.\n\n\n> @@ -1775,7 +1814,7 @@ _git_notes ()\n>  \tprune,*)\n>  \t\t;;\n>  \t*)\n> -\t\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n> +\t\tcase \"${prev}\" in\n\n> @@ -2615,7 +2670,7 @@ _git_tag ()\n>  \t\tc=$((++c))\n>  \tdone\n>  \n> -\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n> +\tcase \"${prev}\" in\n\nNo {} are needed around prev.\n\n\n> @@ -2639,15 +2694,16 @@ _git_whatchanged ()\n>  \n>  _git ()\n>  {\n> -\tlocal i c=1 command __git_dir\n> +\tlocal i c=1 command __git_dir words cword\n>  \n> -\tif [[ -n ${ZSH_VERSION-} ]]; then\n> +\tif [[ -n $ZSH_VERSION ]]; then\n\n> @@ -2690,19 +2746,20 @@ _git ()\n>  \n>  _gitk ()\n>  {\n> -\tif [[ -n ${ZSH_VERSION-} ]]; then\n> +\tif [[ -n $ZSH_VERSION ]]; then\n\n> @@ -2730,7 +2787,7 @@ complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \\\n>  \t|| complete -o default -o nospace -F _git git.exe\n>  fi\n>  \n> -if [[ -n ${ZSH_VERSION-} ]]; then\n> +if [[ -n $ZSH_VERSION ]]; then\n\nThese three changes have nothing to do with bash4 issues, and they\nbreak in 'set -u' environments, because $ZSH_VERSION is, of course,\nundefined in bash.\n\n\nBest,\nGábor\n"},{"id":"157162","messageId":"20101202234053.GB3577@neumann","threadId":"25912","inReplyTo":"20101202210207.GA4994@burratino","subject":"Re: [RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-12-02T23:40:53Z","receivedAt":"2010-12-02T23:40:53Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\n\nOn Thu, Dec 02, 2010 at 03:02:07PM -0600, Jonathan Nieder wrote:\n> Add a minimal implementation of _get_comp_words_by_ref,\n> the routine used to work around bash 4.0's COMP_WORDS semantics.\n\nSome extension:\n\nBash's programmable completion provides the COMP_WORDS array variable,\nwhich holds the individual words in the current command line.  In Bash\nversions prior to v4 \"words are split on shell metacharacters as the\nshell parser would separate them\" (quote from bash v3.2.48's man\npage).  This behavior has changed with Bash v4, and the command line\n\"is split into words as readline would split it, using COMP_WORDBREAKS\nas\" \"the set of characters that the readline library treats as word\nseparators\" (quote from bash v4's man page).\n\nSince COMP_WORDBREAKS contains the characters : and = by default, this\nbehavior change in Bash also affects git's completion script.  For\nexample, when using Bash v4 the completion script can't provide\npossible options for a command line argument (e.g. git log\n--pretty=<TAB><TAB> lists files, but it should list possible log\nformats).\n\n\nI would really, _really_ like to have the above text in the commit\nmessage (either in yours or in Peter's), because it took me weeks to\nfigure this out ;)  Not that it was that difficult, but when I\ndiscovered this issue more than a month ago, \"unfortunately\" I\nremembered a similar issue (db8a9ff, bash completion: Resolve git show\nref:path<tab> losing ref: portion, 2008-07-15), and it got me\nsidetracked really really  badly.\n\n(I'm still wondering what Bash v3.x was doing with COMP_WORDBREAKS,\nthough...)\n\n> Based on bash-completion 2.x (commit bf763033, 2010-10-26) but\n> tweaked for simplicity and to allow zsh to at least parse the\n> code.\n> \n> Based-on-patch-by: Peter van der Does <peter@avirtualhome.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> ---\n> Peter van der Does wrote:\n> > Jonathan Nieder <jrnieder@gmail.com> wrote:\n> \n> >>  2. Import the definition of _get_comp_words_by_ref from the\n> >>     bash-completion lib and use it if ZSH_VERSION is unset.\n> >> \n> >>  3. Further refinements, if needed.\n> >> \n> >> What do you think?\n> >\n> > I like the idea and we should go with this solution.\n> > \n> > If by importing you mean using :\n> > [CODE]. /git_bash_completion-functions[/CODE] in the\n> > contrib/completion/git-completion.bash script, which would be the best\n> > solution imho. The question is where to place that the function file.\n> [...]\n> > It would have to include copying the functions file somewhere as well.\n> > \n> > Or we could use the method used now and include the functions in the\n> > git-completion.bash script.\n> \n> Sorry for the lack of clarity.  Here's what I meant.\n> \n>  contrib/completion/git-completion.bash |  125 ++++++++++++++++++++++++++++++++\n>  1 files changed, 125 insertions(+), 0 deletions(-)\n\nI haven't tried to understand the code yet, but noticed the following\ntwo nits while glancing it over.\n\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 0b0eb45..1743319 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -327,7 +327,102 @@ __gitcomp_1 ()\n>  \tdone\n>  }\n>  \n> +# The following function is based on code from:\n> +#\n> +#   bash_completion - programmable completion functions for bash 3.2+\n> +#\n> +#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>\n> +#             © 2009-2010, Bash Completion Maintainers\n> +#                     <bash-completion-devel@lists.alioth.debian.org>\n> +#\n> +#   This program is free software; you can redistribute it and/or modify\n> +#   it under the terms of the GNU General Public License as published by\n> +#   the Free Software Foundation; either version 2, or (at your option)\n> +#   any later version.\n> +#\n> +#   This program is distributed in the hope that it will be useful,\n> +#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n> +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n> +#   GNU General Public License for more details.\n> +#\n> +#   You should have received a copy of the GNU General Public License\n> +#   along with this program; if not, write to the Free Software Foundation,\n> +#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n> +#\n> +#   The latest version of this software can be obtained here:\n> +#\n> +#   http://bash-completion.alioth.debian.org/\n> +#\n> +#   RELEASE: 2.x\n> +\n> +# This function can be used to access a tokenized list of words\n> +# on the command line:\n> +#\n> +#\t__reassemble_comp_words_by_ref '=:'\n\n__git_reassemble_comp_words_by_ref?\n\n> +#\tif test \"${words_[cword_-1]}\" = -w\n> +#\tthen\n> +#\t\t...\n> +#\tfi\n> +#\n> +# The argument should be a collection of characters from the list of\n> +# word completion separators (COMP_WORDBREAKS) to treat as ordinary\n> +# characters.\n> +#\n> +# This is roughly equivalent to locally setting COMP_WORDBREAKS to\n> +# exclude those characters, but it does not clobber COMP_WORDBREAKS.\n> +# The intent is for it to be used by commands like ssh that want to\n> +# treat host:path as one token.\n> +#\n> +# Output: words_, cword_, cur_.\n> +\n> +__git_reassemble_comp_words_by_ref()\n> +{\n> +\tlocal exclude i j first\n> +\t# Which word separators to exclude?\n> +\texclude=\"${1//[^$COMP_WORDBREAKS]}\"\n> +\tcword_=$COMP_CWORD\n> +\tif [ -z \"$exclude\" ]; then\n> +\t\twords_=(\"${COMP_WORDS[@]}\")\n> +\t\treturn\n> +\tfi\n> +\t# List of word completion separators has shrunk;\n> +\t# re-assemble words to complete.\n> +\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n> +\t\t# Append each nonempty word consisting of just\n> +\t\t# word separator characters to the current word.\n> +\t\tfirst=t\n> +\t\twhile\n> +\t\t\t[ $i -gt 0 ] &&\n> +\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n> +\t\t\t# word consists of excluded word separators\n> +\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n> +\t\tdo\n> +\t\t\t# Attach to the previous token,\n> +\t\t\t# unless the previous token is the command name.\n> +\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n> +\t\t\t\t((j--))\n> +\t\t\tfi\n> +\t\t\tfirst=\n> +\t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n> +\t\t\tif [ $i = $COMP_CWORD ]; then\n> +\t\t\t\tcword_=$j\n> +\t\t\tfi\n> +\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n> +\t\t\t\t((i++))\n> +\t\t\telse\n> +\t\t\t\t# Done.\n> +\t\t\t\treturn\n> +\t\t\tfi\n> +\t\tdone\n> +\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n> +\t\tif [ $i = $COMP_CWORD ]; then\n> +\t\t\tcword_=$j\n> +\t\tfi\n> +\tdone\n> +}\n> +\n>  if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n> +if [[ -n $ZSH_VERSION ]]; then\n\nThis should be ${ZSH_VERSION-} to keep 'set -u' environments happy.\n\n \n"},{"id":"157163","messageId":"20101203000723.GB8438@burratino","threadId":"25912","inReplyTo":"20101202234053.GB3577@neumann","subject":"Re: [RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-03T00:07:23Z","receivedAt":"2010-12-03T00:07:23Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"SZEDER Gábor wrote:\n\n> Bash's programmable completion provides the COMP_WORDS array variable,\n> which holds the individual words in the current command line.  In Bash\n> versions prior to v4 \"words are split on shell metacharacters as the\n> shell parser would separate them\" (quote from bash v3.2.48's man\n> page).  This behavior has changed with Bash v4, and the command line\n> \"is split into words as readline would split it, using COMP_WORDBREAKS\n> as\" \"the set of characters that the readline library treats as word\n> separators\" (quote from bash v4's man page).\n>\n> Since COMP_WORDBREAKS contains the characters : and = by default, this\n> behavior change in Bash also affects git's completion script.  For\n> example, when using Bash v4 the completion script can't provide\n> possible options for a command line argument (e.g. git log\n> --pretty=<TAB><TAB> lists files, but it should list possible log\n> formats).\n> \n> \n> I would really, _really_ like to have the above text in the commit\n> message (either in yours or in Peter's), because it took me weeks to\n> figure this out ;)\n\nSounds good.\n\n> (I'm still wondering what Bash v3.x was doing with COMP_WORDBREAKS,\n> though...)\n\nBased on v1.5.6.4~9^2 (bash completion: Resolve git show ref:path<tab>\nlosing ref: portion, 2008-07-15) it seems COMP_WORDBREAKS determined\nthe interpretation of COMPREPLY (result of completion).  Of course it\nalso governed standard filename completion.\n\n> On Thu, Dec 02, 2010 at 03:02:07PM -0600, Jonathan Nieder wrote:\n\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -327,7 +327,102 @@ __gitcomp_1 ()\n[...]\n>> +# This function can be used to access a tokenized list of words\n>> +# on the command line:\n>> +#\n>> +#\t__reassemble_comp_words_by_ref '=:'\n>\n> __git_reassemble_comp_words_by_ref?\n[...]\n>>  if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n>> +if [[ -n $ZSH_VERSION ]]; then\n>\n> This should be ${ZSH_VERSION-} to keep 'set -u' environments happy.\n\nNice catches; thanks.\n"},{"id":"157176","messageId":"4CF8A401.9010407@gmail.com","threadId":"25912","inReplyTo":"20101202234053.GB3577@neumann","subject":"Re: [RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"Stephen Boyd","fromEmail":"bebarino@gmail.com","sentAt":"2010-12-03T08:02:09Z","receivedAt":"2010-12-03T08:02:09Z","isPatch":true,"sender":{"key":"bebarino@gmail.com","avatar":"https://avatars.githubusercontent.com/u/38832?v=4"},"body":"On 12/02/10 15:40, SZEDER Gábor wrote:\n>\n> I would really, _really_ like to have the above text in the commit\n> message (either in yours or in Peter's), because it took me weeks to\n> figure this out ;)  Not that it was that difficult, but when I\n> discovered this issue more than a month ago, \"unfortunately\" I\n> remembered a similar issue (db8a9ff, bash completion: Resolve git show\n> ref:path<tab> losing ref: portion, 2008-07-15), and it got me\n> sidetracked really really  badly.\n> \n\nI reported this issue over a year ago!\n\nhttp://article.gmane.org/gmane.comp.version-control.git/133067\n\nI'll be glad to see it fixed (but I haven't had time to look over these\npatches and try them out yet).\n"},{"id":"157491","messageId":"20101207160747.GD1867@neumann","threadId":"25912","inReplyTo":"20101202210207.GA4994@burratino","subject":"Re: [RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-12-07T16:07:48Z","receivedAt":"2010-12-07T16:07:48Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi Jonathan,\n\nWhat is this patch based on?\n\n\nThanks,\nGábor\n\n\nOn Thu, Dec 02, 2010 at 03:02:07PM -0600, Jonathan Nieder wrote:\n> Add a minimal implementation of _get_comp_words_by_ref,\n> the routine used to work around bash 4.0's COMP_WORDS semantics.\n> \n> Based on bash-completion 2.x (commit bf763033, 2010-10-26) but\n> tweaked for simplicity and to allow zsh to at least parse the\n> code.\n> \n> Based-on-patch-by: Peter van der Does <peter@avirtualhome.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> ---\n> Peter van der Does wrote:\n> > Jonathan Nieder <jrnieder@gmail.com> wrote:\n> \n> >>  2. Import the definition of _get_comp_words_by_ref from the\n> >>     bash-completion lib and use it if ZSH_VERSION is unset.\n> >> \n> >>  3. Further refinements, if needed.\n> >> \n> >> What do you think?\n> >\n> > I like the idea and we should go with this solution.\n> > \n> > If by importing you mean using :\n> > [CODE]. /git_bash_completion-functions[/CODE] in the\n> > contrib/completion/git-completion.bash script, which would be the best\n> > solution imho. The question is where to place that the function file.\n> [...]\n> > It would have to include copying the functions file somewhere as well.\n> > \n> > Or we could use the method used now and include the functions in the\n> > git-completion.bash script.\n> \n> Sorry for the lack of clarity.  Here's what I meant.\n> \n>  contrib/completion/git-completion.bash |  125 ++++++++++++++++++++++++++++++++\n>  1 files changed, 125 insertions(+), 0 deletions(-)\n> \n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 0b0eb45..1743319 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -327,7 +327,102 @@ __gitcomp_1 ()\n>  \tdone\n>  }\n>  \n> +# The following function is based on code from:\n> +#\n> +#   bash_completion - programmable completion functions for bash 3.2+\n> +#\n> +#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>\n> +#             © 2009-2010, Bash Completion Maintainers\n> +#                     <bash-completion-devel@lists.alioth.debian.org>\n> +#\n> +#   This program is free software; you can redistribute it and/or modify\n> +#   it under the terms of the GNU General Public License as published by\n> +#   the Free Software Foundation; either version 2, or (at your option)\n> +#   any later version.\n> +#\n> +#   This program is distributed in the hope that it will be useful,\n> +#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n> +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n> +#   GNU General Public License for more details.\n> +#\n> +#   You should have received a copy of the GNU General Public License\n> +#   along with this program; if not, write to the Free Software Foundation,\n> +#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n> +#\n> +#   The latest version of this software can be obtained here:\n> +#\n> +#   http://bash-completion.alioth.debian.org/\n> +#\n> +#   RELEASE: 2.x\n> +\n> +# This function can be used to access a tokenized list of words\n> +# on the command line:\n> +#\n> +#\t__reassemble_comp_words_by_ref '=:'\n> +#\tif test \"${words_[cword_-1]}\" = -w\n> +#\tthen\n> +#\t\t...\n> +#\tfi\n> +#\n> +# The argument should be a collection of characters from the list of\n> +# word completion separators (COMP_WORDBREAKS) to treat as ordinary\n> +# characters.\n> +#\n> +# This is roughly equivalent to locally setting COMP_WORDBREAKS to\n> +# exclude those characters, but it does not clobber COMP_WORDBREAKS.\n> +# The intent is for it to be used by commands like ssh that want to\n> +# treat host:path as one token.\n> +#\n> +# Output: words_, cword_, cur_.\n> +\n> +__git_reassemble_comp_words_by_ref()\n> +{\n> +\tlocal exclude i j first\n> +\t# Which word separators to exclude?\n> +\texclude=\"${1//[^$COMP_WORDBREAKS]}\"\n> +\tcword_=$COMP_CWORD\n> +\tif [ -z \"$exclude\" ]; then\n> +\t\twords_=(\"${COMP_WORDS[@]}\")\n> +\t\treturn\n> +\tfi\n> +\t# List of word completion separators has shrunk;\n> +\t# re-assemble words to complete.\n> +\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n> +\t\t# Append each nonempty word consisting of just\n> +\t\t# word separator characters to the current word.\n> +\t\tfirst=t\n> +\t\twhile\n> +\t\t\t[ $i -gt 0 ] &&\n> +\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n> +\t\t\t# word consists of excluded word separators\n> +\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n> +\t\tdo\n> +\t\t\t# Attach to the previous token,\n> +\t\t\t# unless the previous token is the command name.\n> +\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n> +\t\t\t\t((j--))\n> +\t\t\tfi\n> +\t\t\tfirst=\n> +\t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n> +\t\t\tif [ $i = $COMP_CWORD ]; then\n> +\t\t\t\tcword_=$j\n> +\t\t\tfi\n> +\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n> +\t\t\t\t((i++))\n> +\t\t\telse\n> +\t\t\t\t# Done.\n> +\t\t\t\treturn\n> +\t\t\tfi\n> +\t\tdone\n> +\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n> +\t\tif [ $i = $COMP_CWORD ]; then\n> +\t\t\tcword_=$j\n> +\t\tfi\n> +\tdone\n> +}\n> +\n>  if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n> +if [[ -n $ZSH_VERSION ]]; then\n>  _get_comp_words_by_ref ()\n>  {\n>  \twhile [ $# -gt 0 ]; do\n> @@ -352,6 +447,36 @@ _get_comp_words_by_ref ()\n>  \t\tshift\n>  \tdone\n>  }\n> +else\n> +_get_comp_words_by_ref ()\n> +{\n> +\tlocal exclude cur_ cword_\n> +\tlocal words_=()\n> +\tif [ \"$1\" = \"-n\" ]; then\n> +\t\texclude=$2\n> +\t\tshift 2\n> +\tfi\n> +\t__git_reassemble_comp_words_by_ref \"$exclude\"\n> +\tcur_=${words_[cword_]}\n> +\twhile [ $# -gt 0 ]; do\n> +\t\tcase \"$1\" in\n> +\t\tcur)\n> +\t\t\tcur=$cur_\n> +\t\t\t;;\n> +\t\tprev)\n> +\t\t\tprev=${words_[$cword_-1]}\n> +\t\t\t;;\n> +\t\twords)\n> +\t\t\twords=(\"${words_[@]}\")\n> +\t\t\t;;\n> +\t\tcword)\n> +\t\t\tcword=$cword_\n> +\t\t\t;;\n> +\t\tesac\n> +\t\tshift\n> +\tdone\n> +}\n> +fi\n>  fi\n>  \n>  # __gitcomp accepts 1, 2, 3, or 4 arguments\n> -- \n> 1.7.2.3\n> \n"},{"id":"157527","messageId":"20101207194923.GD22587@burratino","threadId":"25912","inReplyTo":"20101207160747.GD1867@neumann","subject":"Re: [RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-07T19:49:23Z","receivedAt":"2010-12-07T19:49:23Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"SZEDER Gábor wrote:\n> On Thu, Dec 02, 2010 at 03:02:07PM -0600, Jonathan Nieder wrote:\n\n>> Add a minimal implementation of _get_comp_words_by_ref,\n>> the routine used to work around bash 4.0's COMP_WORDS semantics.\n>> \n>> Based on bash-completion 2.x (commit bf763033, 2010-10-26) but\n>> tweaked for simplicity and to allow zsh to at least parse the\n>> code.\n>\n> What is this patch based on?\n\nAh, sorry, applies to d93f4a297 (bash: work around bash 4.0 change in\nCOMP_WORDS semantics, 2010-12-02).\n\nCan re-send in a few moments based on maint if you'd like.\n"},{"id":"157535","messageId":"20101207204104.GE1867@neumann","threadId":"25912","inReplyTo":"20101207194923.GD22587@burratino","subject":"Re: [RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-12-07T20:41:04Z","receivedAt":"2010-12-07T20:41:04Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi Jonathan,\n\n\nOn Tue, Dec 07, 2010 at 01:49:23PM -0600, Jonathan Nieder wrote:\n> SZEDER Gábor wrote:\n> > On Thu, Dec 02, 2010 at 03:02:07PM -0600, Jonathan Nieder wrote:\n> \n> >> Add a minimal implementation of _get_comp_words_by_ref,\n> >> the routine used to work around bash 4.0's COMP_WORDS semantics.\n> >> \n> >> Based on bash-completion 2.x (commit bf763033, 2010-10-26) but\n> >> tweaked for simplicity and to allow zsh to at least parse the\n> >> code.\n> >\n> > What is this patch based on?\n> \n> Ah, sorry, applies to d93f4a297 (bash: work around bash 4.0 change in\n> COMP_WORDS semantics, 2010-12-02).\n\nIn which repo? ;)\n\nI don't have d93f4a297, but I have e0a9590 (Introduce functions from\nbash-completion project., 2010-12-01) and c7e75bb (Use the new\nfunctions to get the current cword., 2010-12-01) instead, which were\nmerged into pu at 0c30752 (Merge branch 'pd/bash-4-completion' into\npu, 2010-12-03).\n\nHm, waittaminit...  Ah, OK, nevermind, got it.  There was a patch in\n\n  http://article.gmane.org/gmane.comp.version-control.git/162686\n\nI forgot to apply first...  Now I have it all, seems to work so far.\n\n\nThanks,\nGábor\n"},{"id":"157539","messageId":"20101207205951.GB25008@burratino","threadId":"25912","inReplyTo":"20101207204104.GE1867@neumann","subject":"Re: [RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-07T20:59:51Z","receivedAt":"2010-12-07T20:59:51Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"SZEDER Gábor wrote:\n> On Tue, Dec 07, 2010 at 01:49:23PM -0600, Jonathan Nieder wrote:\n\n>> Ah, sorry, applies to d93f4a297 (bash: work around bash 4.0 change in\n>> COMP_WORDS semantics, 2010-12-02).\n>\n> In which repo? ;)\n\nThanks.  I had meant to say that patch 1 applies to 06f44c3c\n(completion: make compatible with zsh, 2010-09-06) and that the bash 4\nsupport could be rebased to work without that if there is demand.\n\n*goes off to get some coffee*\n\nSorry for the confusion.\nJonathan\n"},{"id":"157540","messageId":"7v1v5tpa7b.fsf@alter.siamese.dyndns.org","threadId":"25912","inReplyTo":"20101207194923.GD22587@burratino","subject":"Re: [RFC/PATCH 2/1] bash: eliminate dependency on bash_completion lib","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-12-07T21:03:20Z","receivedAt":"2010-12-07T21:03:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> SZEDER Gábor wrote:\n>> On Thu, Dec 02, 2010 at 03:02:07PM -0600, Jonathan Nieder wrote:\n>\n>>> Add a minimal implementation of _get_comp_words_by_ref,\n>>> the routine used to work around bash 4.0's COMP_WORDS semantics.\n>>> \n>>> Based on bash-completion 2.x (commit bf763033, 2010-10-26) but\n>>> tweaked for simplicity and to allow zsh to at least parse the\n>>> code.\n>>\n>> What is this patch based on?\n>\n> Ah, sorry, applies to d93f4a297 (bash: work around bash 4.0 change in\n> COMP_WORDS semantics, 2010-12-02).\n\nSorry, but whose repository does that object live in?\n"},{"id":"158136","messageId":"20101215062403.GA20492@burratino","threadId":"25912","inReplyTo":"7v1v5tpa7b.fsf@alter.siamese.dyndns.org","subject":"[PATCH v5.1 0/3] Make git-completion Bash 4 compatible","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-15T06:24:03Z","receivedAt":"2010-12-15T06:24:03Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n>>> On Thu, Dec 02, 2010 at 03:02:07PM -0600, Jonathan Nieder wrote:\n\n>>>> Add a minimal implementation of _get_comp_words_by_ref,\n>>>> the routine used to work around bash 4.0's COMP_WORDS semantics.\n>>>>\n>>>> Based on bash-completion 2.x (commit bf763033, 2010-10-26) but\n>>>> tweaked for simplicity and to allow zsh to at least parse the\n>>>> code.\n[...]\n> Sorry, but whose repository does that object live in?\n\nAgh, sorry for the mess.  Please fetch\n\n  git://repo.or.cz/git/jrn.git pd/bash-4-completion \n\nto receive the following history:\n\n  o [maint-1.7.2] --- A --- B --- M [FETCH_HEAD]\n                                 /\n                                o [master (early part)]\n\n[A] bash: get --pretty=m<tab> completion to work with bash v4\n(by Peter)\n\n[B] bash: simple reimplementation of _get_comp_words_by_ref\n(discussed above)\n\n[M] Merge branch 'master' (early part) into pd/bash-4-completion\n(zsh compatibility)\n\n[master (early part)] completion: fix zsh check under bash with 'set -u'\n(2010-10-28 11:45:00 -0700).\n\nA and B are the patches sent previously in this thread, rebased on an\nolder code base to avoid the zsh support.  A combined diff for the\nmerge 'M' will follow.  Thoughts, suggestions, acks, test reports\nwould be welcome.\n\nThanks for your patience.\nJonathan\n"},{"id":"158137","messageId":"20101215062652.GB20492@burratino","threadId":"25912","inReplyTo":"20101215062403.GA20492@burratino","subject":"[PATCH 1/3] bash: get --pretty=m<tab> completion to work with bash v4","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-15T06:26:52Z","receivedAt":"2010-12-15T06:26:52Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Peter van der Does <peter@avirtualhome.com>\n\nBash's programmable completion provides the COMP_WORDS array variable,\nwhich holds the individual words in the current command line.  In bash\nversions prior to v4 \"words are split on shell metacharacters as the\nshell parser would separate them\" (quote from bash v3.2.48's man\npage).  This behavior has changed with bash v4, and the command line\n\"is split into words as readline would split it, using COMP_WORDBREAKS\nas\" \"the set of characters that the readline library treats as word\nseparators\" (quote from bash v4's man page).\n\nSince COMP_WORDBREAKS contains the characters : and = by default, this\nbehavior change in bash affects git's completion script.  For example,\nbefore bash 4, running\n\n\t$ git log --pretty=m <tab><tab>\n\nwould give a list of pretty-printing formats starting with 'm' but now\nit completes on branch names.\n\nIt would be possible to work around this by removing '=' and ':' from\nCOMP_WORDBREAKS, but as noticed in v1.5.6.4~9^2 (bash completion:\nResolve git show ref:path<tab> losing ref: portion, 2008-07-15), that\nwould break *other* completion scripts.  The bash-completion library\nincludes a better workaround: the _get_comp_words_by_ref function\nre-assembles a copy of COMP_WORDS, excluding a collection of word\nseparators of the caller's choice.  Use it.\n\nAs a bonus, this improves behavior when tab is pressed with the cursor\nin the middle of a word if the bash-completion lib is loaded.\n\nTo avoid breaking setups with the bash-completion library not already\nloaded, if the _get_comp_words_by_ref function is not defined then use\na shim that just reads COMP_WORDS instead (no change from the current\nbehavior in that case).\n\nSigned-off-by: Peter van der Does <peter@avirtualhome.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nExplained-by: SZEDER Gábor <szeder@ira.uka.de>\n---\n contrib/completion/git-completion.bash |  236 +++++++++++++++++++++----------\n 1 files changed, 160 insertions(+), 76 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 82e6609..68b68d0 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -321,11 +321,39 @@ __gitcomp_1 ()\n \tdone\n }\n \n+if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n+_get_comp_words_by_ref ()\n+{\n+\twhile [ $# -gt 0 ]; do\n+\t\tcase \"$1\" in\n+\t\tcur)\n+\t\t\tcur=${COMP_WORDS[COMP_CWORD]}\n+\t\t\t;;\n+\t\tprev)\n+\t\t\tprev=${COMP_WORDS[COMP_CWORD-1]}\n+\t\t\t;;\n+\t\twords)\n+\t\t\twords=(\"${COMP_WORDS[@]}\")\n+\t\t\t;;\n+\t\tcword)\n+\t\t\tcword=$COMP_CWORD\n+\t\t\t;;\n+\t\t-n)\n+\t\t\t# assume COMP_WORDBREAKS is already set sanely\n+\t\t\tshift\n+\t\t\t;;\n+\t\tesac\n+\t\tshift\n+\tdone\n+}\n+fi\n+\n # __gitcomp accepts 1, 2, 3, or 4 arguments\n # generates completion reply with compgen\n __gitcomp ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tif [ $# -gt 2 ]; then\n \t\tcur=\"$3\"\n \tfi\n@@ -384,7 +412,8 @@ __git_tags ()\n __git_refs ()\n {\n \tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" format refs\n+\tlocal cur format refs\n+\t_get_comp_words_by_ref -n =: cur\n \tif [ -d \"$dir\" ]; then\n \t\tcase \"$cur\" in\n \t\trefs|refs/*)\n@@ -482,7 +511,8 @@ __git_compute_merge_strategies ()\n \n __git_complete_file ()\n {\n-\tlocal pfx ls ref cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal pfx ls ref cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t?*:*)\n \t\tref=\"${cur%%:*}\"\n@@ -530,7 +560,8 @@ __git_complete_file ()\n \n __git_complete_revlist ()\n {\n-\tlocal pfx cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal pfx cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t*...*)\n \t\tpfx=\"${cur%...*}...\"\n@@ -550,11 +581,12 @@ __git_complete_revlist ()\n \n __git_complete_remote_or_refspec ()\n {\n-\tlocal cmd=\"${COMP_WORDS[1]}\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur words cword\n+\t_get_comp_words_by_ref -n =: cur words cword\n+\tlocal cmd=\"${words[1]}\"\n \tlocal i c=2 remote=\"\" pfx=\"\" lhs=1 no_complete_refspec=0\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t--mirror) [ \"$cmd\" = \"push\" ] && no_complete_refspec=1 ;;\n \t\t--all)\n@@ -622,13 +654,14 @@ __git_complete_remote_or_refspec ()\n \n __git_complete_strategy ()\n {\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n =: cur prev\n \t__git_compute_merge_strategies\n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"$prev\" in\n \t-s|--strategy)\n \t\t__gitcomp \"$__git_merge_strategies\"\n \t\treturn 0\n \tesac\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n \tcase \"$cur\" in\n \t--strategy=*)\n \t\t__gitcomp \"$__git_merge_strategies\" \"\" \"${cur##--strategy=}\"\n@@ -788,10 +821,10 @@ __git_aliased_command ()\n # __git_find_on_cmdline requires 1 argument\n __git_find_on_cmdline ()\n {\n-\tlocal word subcommand c=1\n-\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\tword=\"${COMP_WORDS[c]}\"\n+\tlocal word subcommand c=1 words cword\n+\t_get_comp_words_by_ref -n =: words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\tword=\"${words[c]}\"\n \t\tfor subcommand in $1; do\n \t\t\tif [ \"$subcommand\" = \"$word\" ]; then\n \t\t\t\techo \"$subcommand\"\n@@ -804,9 +837,10 @@ __git_find_on_cmdline ()\n \n __git_has_doubledash ()\n {\n-\tlocal c=1\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\tif [ \"--\" = \"${COMP_WORDS[c]}\" ]; then\n+\tlocal c=1 words cword\n+\t_get_comp_words_by_ref -n =: words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\tif [ \"--\" = \"${words[c]}\" ]; then\n \t\t\treturn 0\n \t\tfi\n \t\tc=$((++c))\n@@ -818,7 +852,8 @@ __git_whitespacelist=\"nowarn warn error error-all fix\"\n \n _git_am ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n+\tlocal cur dir=\"$(__gitdir)\"\n+\t_get_comp_words_by_ref -n =: cur\n \tif [ -d \"$dir\"/rebase-apply ]; then\n \t\t__gitcomp \"--skip --continue --resolved --abort\"\n \t\treturn\n@@ -842,7 +877,8 @@ _git_am ()\n \n _git_apply ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--whitespace=*)\n \t\t__gitcomp \"$__git_whitespacelist\" \"\" \"${cur##--whitespace=}\"\n@@ -865,7 +901,8 @@ _git_add ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -879,7 +916,8 @@ _git_add ()\n \n _git_archive ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--format=*)\n \t\t__gitcomp \"$(git archive --list)\" \"\" \"${cur##--format=}\"\n@@ -923,10 +961,11 @@ _git_bisect ()\n \n _git_branch ()\n {\n-\tlocal i c=1 only_local_ref=\"n\" has_r=\"n\"\n+\tlocal i c=1 only_local_ref=\"n\" has_r=\"n\" cur words cword\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\t_get_comp_words_by_ref -n =: cur words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t-d|-m)\tonly_local_ref=\"y\" ;;\n \t\t-r)\thas_r=\"y\" ;;\n@@ -934,7 +973,7 @@ _git_branch ()\n \t\tc=$((++c))\n \tdone\n \n-\tcase \"${COMP_WORDS[COMP_CWORD]}\" in\n+\tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n \t\t\t--color --no-color --verbose --abbrev= --no-abbrev\n@@ -954,8 +993,10 @@ _git_branch ()\n \n _git_bundle ()\n {\n-\tlocal cmd=\"${COMP_WORDS[2]}\"\n-\tcase \"$COMP_CWORD\" in\n+\tlocal words cword\n+\t_get_comp_words_by_ref -n =: words cword\n+\tlocal cmd=\"${words[2]}\"\n+\tcase \"$cword\" in\n \t2)\n \t\t__gitcomp \"create list-heads verify unbundle\"\n \t\t;;\n@@ -976,7 +1017,8 @@ _git_checkout ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--conflict=*)\n \t\t__gitcomp \"diff3 merge\" \"\" \"${cur##--conflict=}\"\n@@ -1000,7 +1042,8 @@ _git_cherry ()\n \n _git_cherry_pick ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--edit --no-commit\"\n@@ -1015,7 +1058,8 @@ _git_clean ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run --quiet\"\n@@ -1027,7 +1071,8 @@ _git_clean ()\n \n _git_clone ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1054,7 +1099,8 @@ _git_commit ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--cleanup=*)\n \t\t__gitcomp \"default strip verbatim whitespace\n@@ -1089,7 +1135,8 @@ _git_commit ()\n \n _git_describe ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1121,7 +1168,8 @@ _git_diff ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --staged --pickaxe-all --pickaxe-regex\n@@ -1142,7 +1190,8 @@ _git_difftool ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--tool=*)\n \t\t__gitcomp \"$__git_mergetools_common kompare\" \"\" \"${cur##--tool=}\"\n@@ -1167,7 +1216,8 @@ __git_fetch_options=\"\n \n _git_fetch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_fetch_options\"\n@@ -1179,7 +1229,8 @@ _git_fetch ()\n \n _git_format_patch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--thread=*)\n \t\t__gitcomp \"\n@@ -1211,7 +1262,8 @@ _git_format_patch ()\n \n _git_fsck ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1226,7 +1278,8 @@ _git_fsck ()\n \n _git_gc ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--prune --aggressive\"\n@@ -1245,7 +1298,8 @@ _git_grep ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1268,7 +1322,8 @@ _git_grep ()\n \n _git_help ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--all --info --man --web\"\n@@ -1286,7 +1341,8 @@ _git_help ()\n \n _git_init ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--shared=*)\n \t\t__gitcomp \"\n@@ -1306,7 +1362,8 @@ _git_ls_files ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --deleted --modified --others --ignored\n@@ -1360,12 +1417,13 @@ _git_log ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n \tlocal g=\"$(git rev-parse --git-dir 2>/dev/null)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n \t\tmerge=\"--merge\"\n \tfi\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--pretty=*)\n \t\t__gitcomp \"$__git_log_pretty_formats\n@@ -1419,7 +1477,8 @@ _git_merge ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_merge_options\"\n@@ -1430,7 +1489,8 @@ _git_merge ()\n \n _git_mergetool ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--tool=*)\n \t\t__gitcomp \"$__git_mergetools_common tortoisemerge\" \"\" \"${cur##--tool=}\"\n@@ -1451,7 +1511,8 @@ _git_merge_base ()\n \n _git_mv ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run\"\n@@ -1469,12 +1530,14 @@ _git_name_rev ()\n _git_notes ()\n {\n \tlocal subcommands=\"edit show\"\n+\tlocal words cword\n+\t_get_comp_words_by_ref -n =: words cword\n \tif [ -z \"$(__git_find_on_cmdline \"$subcommands\")\" ]; then\n \t\t__gitcomp \"$subcommands\"\n \t\treturn\n \tfi\n \n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"${words[cword-1]}\" in\n \t-m|-F)\n \t\tCOMPREPLY=()\n \t\t;;\n@@ -1488,7 +1551,8 @@ _git_pull ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -1504,8 +1568,9 @@ _git_pull ()\n \n _git_push ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n =: cur prev\n+\tcase \"$prev\" in\n \t--repo)\n \t\t__gitcomp \"$(__git_remotes)\"\n \t\treturn\n@@ -1528,7 +1593,9 @@ _git_push ()\n \n _git_rebase ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n+\tlocal dir=\"$(__gitdir)\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tif [ -d \"$dir\"/rebase-apply ] || [ -d \"$dir\"/rebase-merge ]; then\n \t\t__gitcomp \"--continue --skip --abort\"\n \t\treturn\n@@ -1558,7 +1625,8 @@ __git_send_email_suppresscc_options=\"author self cc bodycc sob cccmd body all\"\n \n _git_send_email ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--confirm=*)\n \t\t__gitcomp \"\n@@ -1600,9 +1668,11 @@ _git_stage ()\n \n __git_config_get_set_variables ()\n {\n-\tlocal prevword word config_file= c=$COMP_CWORD\n+\tlocal words cword\n+\t_get_comp_words_by_ref -n =: words cword\n+\tlocal prevword word config_file= c=$cword\n \twhile [ $c -gt 1 ]; do\n-\t\tword=\"${COMP_WORDS[c]}\"\n+\t\tword=\"${words[c]}\"\n \t\tcase \"$word\" in\n \t\t--global|--system|--file=*)\n \t\t\tconfig_file=\"$word\"\n@@ -1630,9 +1700,9 @@ __git_config_get_set_variables ()\n \n _git_config ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n-\tlocal prv=\"${COMP_WORDS[COMP_CWORD-1]}\"\n-\tcase \"$prv\" in\n+\tlocal cur prev\n+\t_get_comp_words_by_ref -n =: cur prev\n+\tcase \"$prev\" in\n \tbranch.*.remote)\n \t\t__gitcomp \"$(__git_remotes)\"\n \t\treturn\n@@ -1642,13 +1712,13 @@ _git_config ()\n \t\treturn\n \t\t;;\n \tremote.*.fetch)\n-\t\tlocal remote=\"${prv#remote.}\"\n+\t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.fetch}\"\n \t\t__gitcomp \"$(__git_refs_remotes \"$remote\")\"\n \t\treturn\n \t\t;;\n \tremote.*.push)\n-\t\tlocal remote=\"${prv#remote.}\"\n+\t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.push}\"\n \t\t__gitcomp \"$(git --git-dir=\"$(__gitdir)\" \\\n \t\t\tfor-each-ref --format='%(refname):%(refname)' \\\n@@ -2039,7 +2109,8 @@ _git_reset ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--merge --mixed --hard --soft --patch\"\n@@ -2051,7 +2122,8 @@ _git_reset ()\n \n _git_revert ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--edit --mainline --no-edit --no-commit --signoff\"\n@@ -2065,7 +2137,8 @@ _git_rm ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --dry-run --ignore-unmatch --quiet\"\n@@ -2079,7 +2152,8 @@ _git_shortlog ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2097,7 +2171,8 @@ _git_show ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--pretty=*)\n \t\t__gitcomp \"$__git_log_pretty_formats\n@@ -2121,7 +2196,8 @@ _git_show ()\n \n _git_show_branch ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -2138,7 +2214,8 @@ _git_show_branch ()\n \n _git_stash ()\n {\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n =: cur\n \tlocal save_opts='--keep-index --no-keep-index --quiet --patch'\n \tlocal subcommands='save list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n@@ -2183,7 +2260,8 @@ _git_submodule ()\n \n \tlocal subcommands=\"add status init update summary foreach sync\"\n \tif [ -z \"$(__git_find_on_cmdline \"$subcommands\")\" ]; then\n-\t\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\t\tlocal cur\n+\t\t_get_comp_words_by_ref -n =: cur\n \t\tcase \"$cur\" in\n \t\t--*)\n \t\t\t__gitcomp \"--quiet --cached\"\n@@ -2227,7 +2305,8 @@ _git_svn ()\n \t\t\t--edit --rmdir --find-copies-harder --copy-similarity=\n \t\t\t\"\n \n-\t\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\t\tlocal cur\n+\t\t_get_comp_words_by_ref -n =: cur\n \t\tcase \"$subcommand,$cur\" in\n \t\tfetch,--*)\n \t\t\t__gitcomp \"--revision= --fetch-all $fc_opts\"\n@@ -2299,8 +2378,10 @@ _git_svn ()\n _git_tag ()\n {\n \tlocal i c=1 f=0\n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\tlocal words cword prev\n+\t_get_comp_words_by_ref -n =: words cword prev\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t-d|-v)\n \t\t\t__gitcomp \"$(__git_tags)\"\n@@ -2313,7 +2394,7 @@ _git_tag ()\n \t\tc=$((++c))\n \tdone\n \n-\tcase \"${COMP_WORDS[COMP_CWORD-1]}\" in\n+\tcase \"$prev\" in\n \t-m|-F)\n \t\tCOMPREPLY=()\n \t\t;;\n@@ -2339,8 +2420,10 @@ _git ()\n {\n \tlocal i c=1 command __git_dir\n \n-\twhile [ $c -lt $COMP_CWORD ]; do\n-\t\ti=\"${COMP_WORDS[c]}\"\n+\tlocal cur words cword\n+\t_get_comp_words_by_ref -n =: cur words cword\n+\twhile [ $c -lt $cword ]; do\n+\t\ti=\"${words[c]}\"\n \t\tcase \"$i\" in\n \t\t--git-dir=*) __git_dir=\"${i#--git-dir=}\" ;;\n \t\t--bare)      __git_dir=\".\" ;;\n@@ -2352,7 +2435,7 @@ _git ()\n \tdone\n \n \tif [ -z \"$command\" ]; then\n-\t\tcase \"${COMP_WORDS[COMP_CWORD]}\" in\n+\t\tcase \"$cur\" in\n \t\t--*)   __gitcomp \"\n \t\t\t--paginate\n \t\t\t--no-pager\n@@ -2385,12 +2468,13 @@ _gitk ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n \tlocal g=\"$(__gitdir)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n \t\tmerge=\"--merge\"\n \tfi\n+\t_get_comp_words_by_ref -n =: cur\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n-- \n1.7.3.3.573.g0bcfc\n"},{"id":"158138","messageId":"20101215062751.GC20492@burratino","threadId":"25912","inReplyTo":"20101215062403.GA20492@burratino","subject":"[PATCH 2/3] bash: simple reimplementation of _get_comp_words_by_ref","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-15T06:27:51Z","receivedAt":"2010-12-15T06:27:51Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a minimal implementation of _get_comp_words_by_ref so\n\n\t$ git show head:g <tab><tab>\n\non bash 4 can complete paths within the head commit without requiring\nthe bash_completion functions to be loaded.  This is a follow-up to\nthe previous patch (bash: get --pretty=m<tab> completion to work with\nbash v4).\n\nBased on bash-completion 2.x (commit bf763033, 2010-10-26) but tweaked\nfor simplicity and to allow zsh to parse the code.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nImproved-by: SZEDER Gábor <szeder@ira.uka.de>\n---\n contrib/completion/git-completion.bash |  118 +++++++++++++++++++++++++++++--\n 1 files changed, 110 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 68b68d0..1747091 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -321,26 +321,128 @@ __gitcomp_1 ()\n \tdone\n }\n \n+# The following function is based on code from:\n+#\n+#   bash_completion - programmable completion functions for bash 3.2+\n+#\n+#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>\n+#             © 2009-2010, Bash Completion Maintainers\n+#                     <bash-completion-devel@lists.alioth.debian.org>\n+#\n+#   This program is free software; you can redistribute it and/or modify\n+#   it under the terms of the GNU General Public License as published by\n+#   the Free Software Foundation; either version 2, or (at your option)\n+#   any later version.\n+#\n+#   This program is distributed in the hope that it will be useful,\n+#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+#   GNU General Public License for more details.\n+#\n+#   You should have received a copy of the GNU General Public License\n+#   along with this program; if not, write to the Free Software Foundation,\n+#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n+#\n+#   The latest version of this software can be obtained here:\n+#\n+#   http://bash-completion.alioth.debian.org/\n+#\n+#   RELEASE: 2.x\n+\n+# This function can be used to access a tokenized list of words\n+# on the command line:\n+#\n+#\t__git_reassemble_comp_words_by_ref '=:'\n+#\tif test \"${words_[cword_-1]}\" = -w\n+#\tthen\n+#\t\t...\n+#\tfi\n+#\n+# The argument should be a collection of characters from the list of\n+# word completion separators (COMP_WORDBREAKS) to treat as ordinary\n+# characters.\n+#\n+# This is roughly equivalent to going back in time and setting\n+# COMP_WORDBREAKS to exclude those characters.  The intent is to\n+# make option types like --date=<type> and <rev>:<path> easy to\n+# recognize by treating each shell word as a single token.\n+#\n+# It is best not to set COMP_WORDBREAKS directly because the value is\n+# shared with other completion scripts.  By the time the completion\n+# function gets called, COMP_WORDS has already been populated so local\n+# changes to COMP_WORDBREAKS have no effect.\n+#\n+# Output: words_, cword_, cur_.\n+\n+__git_reassemble_comp_words_by_ref()\n+{\n+\tlocal exclude i j first\n+\t# Which word separators to exclude?\n+\texclude=\"${1//[^$COMP_WORDBREAKS]}\"\n+\tcword_=$COMP_CWORD\n+\tif [ -z \"$exclude\" ]; then\n+\t\twords_=(\"${COMP_WORDS[@]}\")\n+\t\treturn\n+\tfi\n+\t# List of word completion separators has shrunk;\n+\t# re-assemble words to complete.\n+\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n+\t\t# Append each nonempty word consisting of just\n+\t\t# word separator characters to the current word.\n+\t\tfirst=t\n+\t\twhile\n+\t\t\t[ $i -gt 0 ] &&\n+\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n+\t\t\t# word consists of excluded word separators\n+\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n+\t\tdo\n+\t\t\t# Attach to the previous token,\n+\t\t\t# unless the previous token is the command name.\n+\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n+\t\t\t\t((j--))\n+\t\t\tfi\n+\t\t\tfirst=\n+\t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n+\t\t\tif [ $i = $COMP_CWORD ]; then\n+\t\t\t\tcword_=$j\n+\t\t\tfi\n+\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n+\t\t\t\t((i++))\n+\t\t\telse\n+\t\t\t\t# Done.\n+\t\t\t\treturn\n+\t\t\tfi\n+\t\tdone\n+\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n+\t\tif [ $i = $COMP_CWORD ]; then\n+\t\t\tcword_=$j\n+\t\tfi\n+\tdone\n+}\n+\n if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n _get_comp_words_by_ref ()\n {\n+\tlocal exclude cur_ words_ cword_\n+\tif [ \"$1\" = \"-n\" ]; then\n+\t\texclude=$2\n+\t\tshift 2\n+\tfi\n+\t__git_reassemble_comp_words_by_ref \"$exclude\"\n+\tcur_=${words_[cword_]}\n \twhile [ $# -gt 0 ]; do\n \t\tcase \"$1\" in\n \t\tcur)\n-\t\t\tcur=${COMP_WORDS[COMP_CWORD]}\n+\t\t\tcur=$cur_\n \t\t\t;;\n \t\tprev)\n-\t\t\tprev=${COMP_WORDS[COMP_CWORD-1]}\n+\t\t\tprev=${words_[$cword_-1]}\n \t\t\t;;\n \t\twords)\n-\t\t\twords=(\"${COMP_WORDS[@]}\")\n+\t\t\twords=(\"${words_[@]}\")\n \t\t\t;;\n \t\tcword)\n-\t\t\tcword=$COMP_CWORD\n-\t\t\t;;\n-\t\t-n)\n-\t\t\t# assume COMP_WORDBREAKS is already set sanely\n-\t\t\tshift\n+\t\t\tcword=$cword_\n \t\t\t;;\n \t\tesac\n \t\tshift\n-- \n1.7.3.3.573.g0bcfc\n"},{"id":"158139","messageId":"20101215064235.GD20492@burratino","threadId":"25912","inReplyTo":"20101215062403.GA20492@burratino","subject":"[MERGE PATCH 3/3] Merge branch 'master' (early part) into pd/bash-4-completion","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-15T06:42:35Z","receivedAt":"2010-12-15T06:42:35Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"* 'master' (early part): (529 commits)\n  completion: fix zsh check under bash with 'set -u'\n  Fix copy-pasted comments related to tree diff handling.\n  Git 1.7.3.2\n  {cvs,svn}import: use the new 'git read-tree --empty'\n  t/t9001-send-email.sh: fix stderr redirection in 'Invalid In-Reply-To'\n  Clarify and extend the \"git diff\" format documentation\n  git-show-ref.txt: clarify the pattern matching\n  documentation: git-config minor cleanups\n  Update test script annotate-tests.sh to handle missing/extra authors\n  ...\n\nConflicts:\n\tGIT-VERSION-GEN\n\tRelNotes\n\tcontrib/completion/git-completion.bash\n---\nSuggestions for further work:\n\n - check edge cases:\n\n\tgit log --pretty m<tab><tab>\t\tshould complete formats\n\tgit log --pretty =<tab><tab>\t\tshould complain\n\tgit log --pretty= m<tab><tab>\t\tshould complete commits\n\n - use a custom function to avoid repeating\n\n\t_get_comp_words_by_ref -n =:\n\n   As an application, consider teaching git to complete\n\n\tgit show HEAD@{<tab><tab>\t\tcompletes to numbers and \"upstream\"\n\n   Would the argument to -n need an @ for that?\n\n - get the zsh completion to actually work. :)  Even without this\n   series, it seems it is willing to complete subcommand names and\n   switches for git but nothing more.\n\n - adopt the rest of bash_completion's _get_comp_words_by_ref logic,\n   so\n\n\tgit log --pretty=m<cursor>master <tab><tab>\n\n   completes formats starting with 'm', not formats starting with 'mmaster'.\n\nIf something turned out buggy, I'd be glad to fix it, but aside from\nthat I probably will not be working much more on this topic.  (Perhaps\nan actual tab completion user would have a better sense of which\naspects are worth working on.)  Please feel free to pick it up and run\nin whatever direction you please.\n\nGood night,\nJonathan\n\ndiff --cc contrib/completion/git-completion.bash\nindex 1747091,168669b..d117055\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@@ -321,135 -327,6 +327,162 @@@ __gitcomp_1 (\n  \tdone\n  }\n  \n +# The following function is based on code from:\n +#\n +#   bash_completion - programmable completion functions for bash 3.2+\n +#\n +#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>\n +#             © 2009-2010, Bash Completion Maintainers\n +#                     <bash-completion-devel@lists.alioth.debian.org>\n +#\n +#   This program is free software; you can redistribute it and/or modify\n +#   it under the terms of the GNU General Public License as published by\n +#   the Free Software Foundation; either version 2, or (at your option)\n +#   any later version.\n +#\n +#   This program is distributed in the hope that it will be useful,\n +#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n +#   GNU General Public License for more details.\n +#\n +#   You should have received a copy of the GNU General Public License\n +#   along with this program; if not, write to the Free Software Foundation,\n +#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n +#\n +#   The latest version of this software can be obtained here:\n +#\n +#   http://bash-completion.alioth.debian.org/\n +#\n +#   RELEASE: 2.x\n +\n +# This function can be used to access a tokenized list of words\n +# on the command line:\n +#\n +#\t__git_reassemble_comp_words_by_ref '=:'\n +#\tif test \"${words_[cword_-1]}\" = -w\n +#\tthen\n +#\t\t...\n +#\tfi\n +#\n +# The argument should be a collection of characters from the list of\n +# word completion separators (COMP_WORDBREAKS) to treat as ordinary\n +# characters.\n +#\n +# This is roughly equivalent to going back in time and setting\n +# COMP_WORDBREAKS to exclude those characters.  The intent is to\n +# make option types like --date=<type> and <rev>:<path> easy to\n +# recognize by treating each shell word as a single token.\n +#\n +# It is best not to set COMP_WORDBREAKS directly because the value is\n +# shared with other completion scripts.  By the time the completion\n +# function gets called, COMP_WORDS has already been populated so local\n +# changes to COMP_WORDBREAKS have no effect.\n +#\n +# Output: words_, cword_, cur_.\n +\n +__git_reassemble_comp_words_by_ref()\n +{\n +\tlocal exclude i j first\n +\t# Which word separators to exclude?\n +\texclude=\"${1//[^$COMP_WORDBREAKS]}\"\n +\tcword_=$COMP_CWORD\n +\tif [ -z \"$exclude\" ]; then\n +\t\twords_=(\"${COMP_WORDS[@]}\")\n +\t\treturn\n +\tfi\n +\t# List of word completion separators has shrunk;\n +\t# re-assemble words to complete.\n +\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n +\t\t# Append each nonempty word consisting of just\n +\t\t# word separator characters to the current word.\n +\t\tfirst=t\n +\t\twhile\n +\t\t\t[ $i -gt 0 ] &&\n +\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n +\t\t\t# word consists of excluded word separators\n +\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n +\t\tdo\n +\t\t\t# Attach to the previous token,\n +\t\t\t# unless the previous token is the command name.\n +\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n +\t\t\t\t((j--))\n +\t\t\tfi\n +\t\t\tfirst=\n +\t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n +\t\t\tif [ $i = $COMP_CWORD ]; then\n +\t\t\t\tcword_=$j\n +\t\t\tfi\n +\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n +\t\t\t\t((i++))\n +\t\t\telse\n +\t\t\t\t# Done.\n +\t\t\t\treturn\n +\t\t\tfi\n +\t\tdone\n +\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n +\t\tif [ $i = $COMP_CWORD ]; then\n +\t\t\tcword_=$j\n +\t\tfi\n +\tdone\n +}\n +\n +if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n++if [[ -z ${ZSH_VERSION:+set} ]]; then\n +_get_comp_words_by_ref ()\n +{\n +\tlocal exclude cur_ words_ cword_\n +\tif [ \"$1\" = \"-n\" ]; then\n +\t\texclude=$2\n +\t\tshift 2\n +\tfi\n +\t__git_reassemble_comp_words_by_ref \"$exclude\"\n +\tcur_=${words_[cword_]}\n +\twhile [ $# -gt 0 ]; do\n +\t\tcase \"$1\" in\n +\t\tcur)\n +\t\t\tcur=$cur_\n +\t\t\t;;\n +\t\tprev)\n +\t\t\tprev=${words_[$cword_-1]}\n +\t\t\t;;\n +\t\twords)\n +\t\t\twords=(\"${words_[@]}\")\n +\t\t\t;;\n +\t\tcword)\n +\t\t\tcword=$cword_\n +\t\t\t;;\n +\t\tesac\n +\t\tshift\n +\tdone\n +}\n++else\n++_get_comp_words_by_ref ()\n++{\n++\twhile [ $# -gt 0 ]; do\n++\t\tcase \"$1\" in\n++\t\tcur)\n++\t\t\tcur=${COMP_WORDS[COMP_CWORD]}\n++\t\t\t;;\n++\t\tprev)\n++\t\t\tprev=${COMP_WORDS[COMP_CWORD-1]}\n++\t\t\t;;\n++\t\twords)\n++\t\t\twords=(\"${COMP_WORDS[@]}\")\n++\t\t\t;;\n++\t\tcword)\n++\t\t\tcword=$COMP_CWORD\n++\t\t\t;;\n++\t\t-n)\n++\t\t\t# assume COMP_WORDBREAKS is already set sanely\n++\t\t\tshift\n++\t\t\t;;\n++\t\tesac\n++\t\tshift\n++\tdone\n++}\n++fi\n +fi\n +\n  # __gitcomp accepts 1, 2, 3, or 4 arguments\n  # generates completion reply with compgen\n  __gitcomp ()\n@@@ -2522,10 -2345,13 +2555,15 @@@ _git (\n  {\n  \tlocal i c=1 command __git_dir\n  \n+ \tif [[ -n ${ZSH_VERSION-} ]]; then\n+ \t\temulate -L bash\n+ \t\tsetopt KSH_TYPESET\n+ \tfi\n+ \n -\twhile [ $c -lt $COMP_CWORD ]; do\n -\t\ti=\"${COMP_WORDS[c]}\"\n +\tlocal cur words cword\n +\t_get_comp_words_by_ref -n =: cur words cword\n +\twhile [ $c -lt $cword ]; do\n +\t\ti=\"${words[c]}\"\n  \t\tcase \"$i\" in\n  \t\t--git-dir=*) __git_dir=\"${i#--git-dir=}\" ;;\n  \t\t--bare)      __git_dir=\".\" ;;\n@@@ -2568,9 -2394,14 +2606,14 @@@\n  \n  _gitk ()\n  {\n+ \tif [[ -n ${ZSH_VERSION-} ]]; then\n+ \t\temulate -L bash\n+ \t\tsetopt KSH_TYPESET\n+ \tfi\n+ \n  \t__git_has_doubledash && return\n  \n -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n +\tlocal cur\n  \tlocal g=\"$(__gitdir)\"\n  \tlocal merge=\"\"\n  \tif [ -f \"$g/MERGE_HEAD\" ]; then\n"}]}