Code

Merge branch 'master' (early part) into pd/bash-4-completion
authorJonathan Nieder <jrnieder@gmail.com>
Wed, 15 Dec 2010 06:05:33 +0000 (00:05 -0600)
committerJonathan Nieder <jrnieder@gmail.com>
Wed, 15 Dec 2010 06:05:33 +0000 (00:05 -0600)
* 'master' (early part): (529 commits)
  completion: fix zsh check under bash with 'set -u'
  Fix copy-pasted comments related to tree diff handling.
  Git 1.7.3.2
  {cvs,svn}import: use the new 'git read-tree --empty'
  t/t9001-send-email.sh: fix stderr redirection in 'Invalid In-Reply-To'
  Clarify and extend the "git diff" format documentation
  git-show-ref.txt: clarify the pattern matching
  documentation: git-config minor cleanups
  Update test script annotate-tests.sh to handle missing/extra authors
  Better advice on using topic branches for kernel development
  Documentation: update implicit "--no-index" behavior in "git diff"
  Documentation: expand 'git diff' SEE ALSO section
  Documentation: diff can compare blobs
  Documentation: gitrevisions is in section 7
  fast-import: Allow filemodify to set the root
  shell portability: no "export VAR=VAL"
  CodingGuidelines: reword parameter expansion section
  Documentation: update-index: -z applies also to --index-info
  gitweb: Improve behavior for actionless path_info gitweb URLs
  gitweb: Fix bug in evaluate_path_info
  ...

Conflicts:
GIT-VERSION-GEN
RelNotes
contrib/completion/git-completion.bash

1  2 
Documentation/config.txt
contrib/completion/git-completion.bash

diff --combined Documentation/config.txt
index 5506e31318517831c6f2143d7a8b01e46763da1a,538ebb5e2ecc58f1ddcb7adb44ded3b027555ec2..e15b40d910ee31e4da49b4caeea5da221ed49d2b
@@@ -450,6 -450,21 +450,21 @@@ core.excludesfile:
        to the value of `$HOME` and "{tilde}user/" to the specified user's
        home directory.  See linkgit:gitignore[5].
  
+ core.askpass::
+       Some commands (e.g. svn and http interfaces) that interactively
+       ask for a password can be told to use an external program given
+       via the value of this variable. Can be overridden by the 'GIT_ASKPASS'
+       environment variable. If not set, fall back to the value of the
+       'SSH_ASKPASS' environment variable or, failing that, a simple password
+       prompt. The external program shall be given a suitable prompt as
+       command line argument and write the password on its STDOUT.
+ core.attributesfile::
+       In addition to '.gitattributes' (per-directory) and
+       '.git/info/attributes', git looks into this file for attributes
+       (see linkgit:gitattributes[5]). Path expansions are made the same
+       way as for `core.excludesfile`.
  core.editor::
        Commands such as `commit` and `tag` that lets you edit
        messages by launching an editor uses the value of this
@@@ -539,13 -554,9 +554,13 @@@ core.sparseCheckout:
        linkgit:git-read-tree[1] for more information.
  
  add.ignore-errors::
 +add.ignoreErrors::
        Tells 'git add' to continue adding files when some files cannot be
        added due to indexing errors. Equivalent to the '--ignore-errors'
 -      option of linkgit:git-add[1].
 +      option of linkgit:git-add[1].  Older versions of git accept only
 +      `add.ignore-errors`, which does not follow the usual naming
 +      convention for configuration variables.  Newer versions of git
 +      honor `add.ignoreErrors` as well.
  
  alias.*::
        Command aliases for the linkgit:git[1] command wrapper - e.g.
@@@ -831,6 -842,12 +846,12 @@@ diff.renames:
        will enable basic rename detection.  If set to "copies" or
        "copy", it will detect copies, as well.
  
+ diff.ignoreSubmodules::
+       Sets the default value of --ignore-submodules. Note that this
+       affects only 'git diff' Porcelain, and not lower level 'diff'
+       commands such as 'git diff-files'. 'git checkout' also honors
+       this setting when reporting uncommitted changes.
  diff.suppressBlankEmpty::
        A boolean to inhibit the standard behavior of printing a space
        before each empty output line. Defaults to false.
@@@ -1248,6 -1265,15 +1269,15 @@@ http.noEPSV:
        support EPSV mode. Can be overridden by the 'GIT_CURL_FTP_NO_EPSV'
        environment variable. Default is false (curl will use EPSV).
  
+ http.useragent::
+       The HTTP USER_AGENT string presented to an HTTP server.  The default
+       value represents the version of the client git such as git/1.7.1.
+       This option allows you to override this value to a more common value
+       such as Mozilla/4.0.  This may be necessary, for instance, if
+       connecting through a firewall that restricts HTTP connections to a set
+       of common USER_AGENT strings (but not including those like git/1.7.1).
+       Can be overridden by the 'GIT_HTTP_USER_AGENT' environment variable.
  i18n.commitEncoding::
        Character encoding the commit messages are stored in; git itself
        does not care per se, but this information is necessary e.g. when
@@@ -1296,10 -1322,11 +1326,11 @@@ interactive.singlekey:
        ignored if portable keystroke input is not available.
  
  log.date::
-       Set default date-time mode for the log command. Setting log.date
-       value is similar to using 'git log'\'s --date option. The value is one of the
-       following alternatives: {relative,local,default,iso,rfc,short}.
-       See linkgit:git-log[1].
+       Set the default date-time mode for the 'log' command.
+       Setting a value for log.date is similar to using 'git log''s
+       `\--date` option.  Possible values are `relative`, `local`,
+       `default`, `iso`, `rfc`, and `short`; see linkgit:git-log[1]
+       for details.
  
  log.decorate::
        Print out the ref names of any commits that are shown by the log
@@@ -1445,6 -1472,10 +1476,10 @@@ pack.compression:
        not set,  defaults to -1, the zlib default, which is "a default
        compromise between speed and compression (currently equivalent
        to level 6)."
+ +
+ Note that changing the compression level will not automatically recompress
+ all existing objects. You can force recompression by passing the -F option
+ to linkgit:git-repack[1].
  
  pack.deltaCacheSize::
        The maximum memory in bytes used for caching deltas in
@@@ -1529,17 -1560,20 +1564,20 @@@ push.default:
        no refspec is implied by any of the options given on the command
        line. Possible values are:
  +
- * `nothing` do not push anything.
- * `matching` push all matching branches.
+ * `nothing` do not push anything.
+ * `matching` push all matching branches.
    All branches having the same name in both ends are considered to be
    matching. This is the default.
- * `tracking` push the current branch to its upstream branch.
- * `current` push the current branch to a branch of the same name.
+ * `tracking` push the current branch to its upstream branch.
+ * `current` push the current branch to a branch of the same name.
  
  rebase.stat::
        Whether to show a diffstat of what changed upstream since the last
        rebase. False by default.
  
+ rebase.autosquash::
+       If set to true enable '--autosquash' option by default.
  receive.autogc::
        By default, git-receive-pack will run "git-gc --auto" after
        receiving data from git-push and updating refs.  You can stop
@@@ -1703,6 -1737,7 +1741,7 @@@ sendemail.to:
  sendemail.smtpdomain::
  sendemail.smtpserver::
  sendemail.smtpserverport::
+ sendemail.smtpserveroption::
  sendemail.smtpuser::
  sendemail.thread::
  sendemail.validate::
@@@ -1731,9 -1766,9 +1770,9 @@@ status.showUntrackedFiles:
        the untracked files. Possible values are:
  +
  --
-       - 'no'     - Show no untracked files
-       - 'normal' - Shows untracked files and directories
      - 'all'    - Shows also individual files in untracked directories.
+ * `no` - Show no untracked files.
+ * `normal` - Show untracked files and directories.
* `all` - Show also individual files in untracked directories.
  --
  +
  If this variable is not specified, it defaults to 'normal'.
@@@ -1756,6 -1791,19 +1795,19 @@@ submodule.<name>.update:
        URL and other values found in the `.gitmodules` file.  See
        linkgit:git-submodule[1] and linkgit:gitmodules[5] for details.
  
+ submodule.<name>.ignore::
+       Defines under what circumstances "git status" and the diff family show
+       a submodule as modified. When set to "all", it will never be considered
+       modified, "dirty" will ignore all changes to the submodules work tree and
+       takes only differences between the HEAD of the submodule and the commit
+       recorded in the superproject into account. "untracked" will additionally
+       let submodules with modified tracked files in their work tree show up.
+       Using "none" (the default when this option is not set) also shows
+       submodules that have untracked files in their work tree as changed.
+       This setting overrides any setting made in .gitmodules for this submodule,
+       both settings can be overridden on the command line by using the
+       "--ignore-submodules" option.
  tar.umask::
        This variable can be used to restrict the permission bits of
        tar archive entries.  The default is 0002, which turns off the
index 1747091287a1cabacbcd16ea7274b7ba295d4932,168669bbf79cb33c527a688fb906e276beadaf79..d117055f56ea2200ebe6d23a558c7b654b1035cf
  #    2) Added the following line to your .bashrc:
  #        source ~/.git-completion.sh
  #
+ #       Or, add the following lines to your .zshrc:
+ #        autoload bashcompinit
+ #        bashcompinit
+ #        source ~/.git-completion.sh
+ #
  #    3) Consider changing your PS1 to also show the current branch:
  #        PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
  #
@@@ -138,11 -143,12 +143,12 @@@ __git_ps1_show_upstream (
                # get the upstream from the "git-svn-id: ..." in a commit message
                # (git-svn uses essentially the same procedure internally)
                local svn_upstream=($(git log --first-parent -1 \
-                                       --grep="^git-svn-id: \(${svn_url_pattern:2}\)" 2>/dev/null))
+                                       --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
                if [[ 0 -ne ${#svn_upstream[@]} ]]; then
                        svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
                        svn_upstream=${svn_upstream%@*}
-                       for ((n=1; "$n" <= "${#svn_remote[@]}"; ++n)); do
+                       local n_stop="${#svn_remote[@]}"
+                       for ((n=1; n <= n_stop; ++n)); do
                                svn_upstream=${svn_upstream#${svn_remote[$n]}}
                        done
  
@@@ -255,7 -261,7 +261,7 @@@ __git_ps1 (
                                (describe)
                                        git describe HEAD ;;
                                (* | default)
 -                                      git describe --exact-match HEAD ;;
 +                                      git describe --tags --exact-match HEAD ;;
                                esac 2>/dev/null)" ||
  
                                b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
@@@ -321,141 -327,11 +327,168 @@@ __gitcomp_1 (
        done
  }
  
 +# The following function is based on code from:
 +#
 +#   bash_completion - programmable completion functions for bash 3.2+
 +#
 +#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
 +#             © 2009-2010, Bash Completion Maintainers
 +#                     <bash-completion-devel@lists.alioth.debian.org>
 +#
 +#   This program is free software; you can redistribute it and/or modify
 +#   it under the terms of the GNU General Public License as published by
 +#   the Free Software Foundation; either version 2, or (at your option)
 +#   any later version.
 +#
 +#   This program is distributed in the hope that it will be useful,
 +#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +#   GNU General Public License for more details.
 +#
 +#   You should have received a copy of the GNU General Public License
 +#   along with this program; if not, write to the Free Software Foundation,
 +#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 +#
 +#   The latest version of this software can be obtained here:
 +#
 +#   http://bash-completion.alioth.debian.org/
 +#
 +#   RELEASE: 2.x
 +
 +# This function can be used to access a tokenized list of words
 +# on the command line:
 +#
 +#     __git_reassemble_comp_words_by_ref '=:'
 +#     if test "${words_[cword_-1]}" = -w
 +#     then
 +#             ...
 +#     fi
 +#
 +# The argument should be a collection of characters from the list of
 +# word completion separators (COMP_WORDBREAKS) to treat as ordinary
 +# characters.
 +#
 +# This is roughly equivalent to going back in time and setting
 +# COMP_WORDBREAKS to exclude those characters.  The intent is to
 +# make option types like --date=<type> and <rev>:<path> easy to
 +# recognize by treating each shell word as a single token.
 +#
 +# It is best not to set COMP_WORDBREAKS directly because the value is
 +# shared with other completion scripts.  By the time the completion
 +# function gets called, COMP_WORDS has already been populated so local
 +# changes to COMP_WORDBREAKS have no effect.
 +#
 +# Output: words_, cword_, cur_.
 +
 +__git_reassemble_comp_words_by_ref()
 +{
 +      local exclude i j first
 +      # Which word separators to exclude?
 +      exclude="${1//[^$COMP_WORDBREAKS]}"
 +      cword_=$COMP_CWORD
 +      if [ -z "$exclude" ]; then
 +              words_=("${COMP_WORDS[@]}")
 +              return
 +      fi
 +      # List of word completion separators has shrunk;
 +      # re-assemble words to complete.
 +      for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
 +              # Append each nonempty word consisting of just
 +              # word separator characters to the current word.
 +              first=t
 +              while
 +                      [ $i -gt 0 ] &&
 +                      [ -n "${COMP_WORDS[$i]}" ] &&
 +                      # word consists of excluded word separators
 +                      [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
 +              do
 +                      # Attach to the previous token,
 +                      # unless the previous token is the command name.
 +                      if [ $j -ge 2 ] && [ -n "$first" ]; then
 +                              ((j--))
 +                      fi
 +                      first=
 +                      words_[$j]=${words_[j]}${COMP_WORDS[i]}
 +                      if [ $i = $COMP_CWORD ]; then
 +                              cword_=$j
 +                      fi
 +                      if (($i < ${#COMP_WORDS[@]} - 1)); then
 +                              ((i++))
 +                      else
 +                              # Done.
 +                              return
 +                      fi
 +              done
 +              words_[$j]=${words_[j]}${COMP_WORDS[i]}
 +              if [ $i = $COMP_CWORD ]; then
 +                      cword_=$j
 +              fi
 +      done
 +}
 +
 +if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
++if [[ -z ${ZSH_VERSION:+set} ]]; then
 +_get_comp_words_by_ref ()
 +{
 +      local exclude cur_ words_ cword_
 +      if [ "$1" = "-n" ]; then
 +              exclude=$2
 +              shift 2
 +      fi
 +      __git_reassemble_comp_words_by_ref "$exclude"
 +      cur_=${words_[cword_]}
 +      while [ $# -gt 0 ]; do
 +              case "$1" in
 +              cur)
 +                      cur=$cur_
 +                      ;;
 +              prev)
 +                      prev=${words_[$cword_-1]}
 +                      ;;
 +              words)
 +                      words=("${words_[@]}")
 +                      ;;
 +              cword)
 +                      cword=$cword_
 +                      ;;
 +              esac
 +              shift
 +      done
 +}
++else
++_get_comp_words_by_ref ()
++{
++      while [ $# -gt 0 ]; do
++              case "$1" in
++              cur)
++                      cur=${COMP_WORDS[COMP_CWORD]}
++                      ;;
++              prev)
++                      prev=${COMP_WORDS[COMP_CWORD-1]}
++                      ;;
++              words)
++                      words=("${COMP_WORDS[@]}")
++                      ;;
++              cword)
++                      cword=$COMP_CWORD
++                      ;;
++              -n)
++                      # assume COMP_WORDBREAKS is already set sanely
++                      shift
++                      ;;
++              esac
++              shift
++      done
++}
++fi
 +fi
 +
  # __gitcomp accepts 1, 2, 3, or 4 arguments
  # generates completion reply with compgen
  __gitcomp ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        if [ $# -gt 2 ]; then
                cur="$3"
        fi
@@@ -514,8 -390,7 +547,8 @@@ __git_tags (
  __git_refs ()
  {
        local i is_hash=y dir="$(__gitdir "${1-}")"
 -      local cur="${COMP_WORDS[COMP_CWORD]}" format refs
 +      local cur format refs
 +      _get_comp_words_by_ref -n =: cur
        if [ -d "$dir" ]; then
                case "$cur" in
                refs|refs/*)
@@@ -613,8 -488,7 +646,8 @@@ __git_compute_merge_strategies (
  
  __git_complete_file ()
  {
 -      local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
 +      local pfx ls ref cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        ?*:*)
                ref="${cur%%:*}"
  
  __git_complete_revlist ()
  {
 -      local pfx cur="${COMP_WORDS[COMP_CWORD]}"
 +      local pfx cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        *...*)
                pfx="${cur%...*}..."
  
  __git_complete_remote_or_refspec ()
  {
 -      local cmd="${COMP_WORDS[1]}"
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur words cword
 +      _get_comp_words_by_ref -n =: cur words cword
 +      local cmd="${words[1]}"
        local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
 -      while [ $c -lt $COMP_CWORD ]; do
 -              i="${COMP_WORDS[c]}"
 +      while [ $c -lt $cword ]; do
 +              i="${words[c]}"
                case "$i" in
                --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
                --all)
  
  __git_complete_strategy ()
  {
 +      local cur prev
 +      _get_comp_words_by_ref -n =: cur prev
        __git_compute_merge_strategies
 -      case "${COMP_WORDS[COMP_CWORD-1]}" in
 +      case "$prev" in
        -s|--strategy)
                __gitcomp "$__git_merge_strategies"
                return 0
        esac
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
        case "$cur" in
        --strategy=*)
                __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
@@@ -923,10 -794,10 +956,10 @@@ __git_aliased_command (
  # __git_find_on_cmdline requires 1 argument
  __git_find_on_cmdline ()
  {
 -      local word subcommand c=1
 -
 -      while [ $c -lt $COMP_CWORD ]; do
 -              word="${COMP_WORDS[c]}"
 +      local word subcommand c=1 words cword
 +      _get_comp_words_by_ref -n =: words cword
 +      while [ $c -lt $cword ]; do
 +              word="${words[c]}"
                for subcommand in $1; do
                        if [ "$subcommand" = "$word" ]; then
                                echo "$subcommand"
  
  __git_has_doubledash ()
  {
 -      local c=1
 -      while [ $c -lt $COMP_CWORD ]; do
 -              if [ "--" = "${COMP_WORDS[c]}" ]; then
 +      local c=1 words cword
 +      _get_comp_words_by_ref -n =: words cword
 +      while [ $c -lt $cword ]; do
 +              if [ "--" = "${words[c]}" ]; then
                        return 0
                fi
                c=$((++c))
@@@ -954,8 -824,7 +987,8 @@@ __git_whitespacelist="nowarn warn erro
  
  _git_am ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
 +      local cur dir="$(__gitdir)"
 +      _get_comp_words_by_ref -n =: cur
        if [ -d "$dir"/rebase-apply ]; then
                __gitcomp "--skip --continue --resolved --abort"
                return
  
  _git_apply ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --whitespace=*)
                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
@@@ -1003,8 -871,7 +1036,8 @@@ _git_add (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
  
  _git_archive ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --format=*)
                __gitcomp "$(git archive --list)" "" "${cur##--format=}"
@@@ -1063,11 -929,10 +1096,11 @@@ _git_bisect (
  
  _git_branch ()
  {
 -      local i c=1 only_local_ref="n" has_r="n"
 +      local i c=1 only_local_ref="n" has_r="n" cur words cword
  
 -      while [ $c -lt $COMP_CWORD ]; do
 -              i="${COMP_WORDS[c]}"
 +      _get_comp_words_by_ref -n =: cur words cword
 +      while [ $c -lt $cword ]; do
 +              i="${words[c]}"
                case "$i" in
                -d|-m)  only_local_ref="y" ;;
                -r)     has_r="y" ;;
                c=$((++c))
        done
  
 -      case "${COMP_WORDS[COMP_CWORD]}" in
 +      case "$cur" in
        --*)
                __gitcomp "
                        --color --no-color --verbose --abbrev= --no-abbrev
  
  _git_bundle ()
  {
 -      local cmd="${COMP_WORDS[2]}"
 -      case "$COMP_CWORD" in
 +      local words cword
 +      _get_comp_words_by_ref -n =: words cword
 +      local cmd="${words[2]}"
 +      case "$cword" in
        2)
                __gitcomp "create list-heads verify unbundle"
                ;;
@@@ -1119,8 -982,7 +1152,8 @@@ _git_checkout (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --conflict=*)
                __gitcomp "diff3 merge" "" "${cur##--conflict=}"
@@@ -1144,8 -1006,7 +1177,8 @@@ _git_cherry (
  
  _git_cherry_pick ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--edit --no-commit"
@@@ -1160,8 -1021,7 +1193,8 @@@ _git_clean (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--dry-run --quiet"
  
  _git_clone ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@@ -1201,8 -1060,7 +1234,8 @@@ _git_commit (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --cleanup=*)
                __gitcomp "default strip verbatim whitespace
  
  _git_describe ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@@ -1270,12 -1127,11 +1303,12 @@@ _git_diff (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
-                       --base --ours --theirs
+                       --base --ours --theirs --no-index
                        $__git_diff_common_options
                        "
                return
@@@ -1292,8 -1148,7 +1325,8 @@@ _git_difftool (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --tool=*)
                __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
@@@ -1318,8 -1173,7 +1351,8 @@@ __git_fetch_options=
  
  _git_fetch ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "$__git_fetch_options"
  
  _git_format_patch ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --thread=*)
                __gitcomp "
  
  _git_fsck ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
  
  _git_gc ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--prune --aggressive"
@@@ -1400,8 -1251,7 +1433,8 @@@ _git_grep (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
  
  _git_help ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--all --info --man --web"
  
  _git_init ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --shared=*)
                __gitcomp "
@@@ -1464,8 -1312,7 +1497,8 @@@ _git_ls_files (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--cached --deleted --modified --others --ignored
@@@ -1519,13 -1366,12 +1552,13 @@@ _git_log (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
        local g="$(git rev-parse --git-dir 2>/dev/null)"
        local merge=""
        if [ -f "$g/MERGE_HEAD" ]; then
                merge="--merge"
        fi
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --pretty=*)
                __gitcomp "$__git_log_pretty_formats
@@@ -1579,8 -1425,7 +1612,8 @@@ _git_merge (
  {
        __git_complete_strategy && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "$__git_merge_options"
  
  _git_mergetool ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --tool=*)
                __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
@@@ -1613,8 -1457,7 +1646,8 @@@ _git_merge_base (
  
  _git_mv ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--dry-run"
@@@ -1632,14 -1475,12 +1665,14 @@@ _git_name_rev (
  _git_notes ()
  {
        local subcommands="edit show"
 +      local words cword
 +      _get_comp_words_by_ref -n =: words cword
        if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
                __gitcomp "$subcommands"
                return
        fi
  
 -      case "${COMP_WORDS[COMP_CWORD-1]}" in
 +      case "${words[cword-1]}" in
        -m|-F)
                COMPREPLY=()
                ;;
@@@ -1653,8 -1494,7 +1686,8 @@@ _git_pull (
  {
        __git_complete_strategy && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
  
  _git_push ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 -      case "${COMP_WORDS[COMP_CWORD-1]}" in
 +      local cur prev
 +      _get_comp_words_by_ref -n =: cur prev
 +      case "$prev" in
        --repo)
                __gitcomp "$(__git_remotes)"
                return
  
  _git_rebase ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
 +      local dir="$(__gitdir)"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
                __gitcomp "--continue --skip --abort"
                return
@@@ -1727,8 -1564,7 +1760,8 @@@ __git_send_email_suppresscc_options="au
  
  _git_send_email ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --confirm=*)
                __gitcomp "
@@@ -1770,11 -1606,9 +1803,11 @@@ _git_stage (
  
  __git_config_get_set_variables ()
  {
 -      local prevword word config_file= c=$COMP_CWORD
 +      local words cword
 +      _get_comp_words_by_ref -n =: words cword
 +      local prevword word config_file= c=$cword
        while [ $c -gt 1 ]; do
 -              word="${COMP_WORDS[c]}"
 +              word="${words[c]}"
                case "$word" in
                --global|--system|--file=*)
                        config_file="$word"
  
  _git_config ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 -      local prv="${COMP_WORDS[COMP_CWORD-1]}"
 -      case "$prv" in
 +      local cur prev
 +      _get_comp_words_by_ref -n =: cur prev
 +      case "$prev" in
        branch.*.remote)
                __gitcomp "$(__git_remotes)"
                return
                return
                ;;
        remote.*.fetch)
 -              local remote="${prv#remote.}"
 +              local remote="${prev#remote.}"
                remote="${remote%.fetch}"
                __gitcomp "$(__git_refs_remotes "$remote")"
                return
                ;;
        remote.*.push)
 -              local remote="${prv#remote.}"
 +              local remote="${prev#remote.}"
                remote="${remote%.push}"
                __gitcomp "$(git --git-dir="$(__gitdir)" \
                        for-each-ref --format='%(refname):%(refname)' \
@@@ -2211,8 -2045,7 +2244,8 @@@ _git_reset (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--merge --mixed --hard --soft --patch"
  
  _git_revert ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
@@@ -2239,8 -2071,7 +2272,8 @@@ _git_rm (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
@@@ -2254,8 -2085,7 +2287,8 @@@ _git_shortlog (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@@ -2273,8 -2103,7 +2306,8 @@@ _git_show (
  {
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --pretty=*)
                __gitcomp "$__git_log_pretty_formats
  
  _git_show_branch ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
  
  _git_stash ()
  {
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
 +      _get_comp_words_by_ref -n =: cur
        local save_opts='--keep-index --no-keep-index --quiet --patch'
        local subcommands='save list show apply clear drop pop create branch'
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
@@@ -2362,8 -2189,7 +2395,8 @@@ _git_submodule (
  
        local subcommands="add status init update summary foreach sync"
        if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
 -              local cur="${COMP_WORDS[COMP_CWORD]}"
 +              local cur
 +              _get_comp_words_by_ref -n =: cur
                case "$cur" in
                --*)
                        __gitcomp "--quiet --cached"
@@@ -2407,8 -2233,7 +2440,8 @@@ _git_svn (
                        --edit --rmdir --find-copies-harder --copy-similarity=
                        "
  
 -              local cur="${COMP_WORDS[COMP_CWORD]}"
 +              local cur
 +              _get_comp_words_by_ref -n =: cur
                case "$subcommand,$cur" in
                fetch,--*)
                        __gitcomp "--revision= --fetch-all $fc_opts"
  _git_tag ()
  {
        local i c=1 f=0
 -      while [ $c -lt $COMP_CWORD ]; do
 -              i="${COMP_WORDS[c]}"
 +      local words cword prev
 +      _get_comp_words_by_ref -n =: words cword prev
 +      while [ $c -lt $cword ]; do
 +              i="${words[c]}"
                case "$i" in
                -d|-v)
                        __gitcomp "$(__git_tags)"
                c=$((++c))
        done
  
 -      case "${COMP_WORDS[COMP_CWORD-1]}" in
 +      case "$prev" in
        -m|-F)
                COMPREPLY=()
                ;;
@@@ -2522,10 -2345,13 +2555,15 @@@ _git (
  {
        local i c=1 command __git_dir
  
 -      while [ $c -lt $COMP_CWORD ]; do
 -              i="${COMP_WORDS[c]}"
+       if [[ -n ${ZSH_VERSION-} ]]; then
+               emulate -L bash
+               setopt KSH_TYPESET
+       fi
 +      local cur words cword
 +      _get_comp_words_by_ref -n =: cur words cword
 +      while [ $c -lt $cword ]; do
 +              i="${words[c]}"
                case "$i" in
                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
                --bare)      __git_dir="." ;;
        done
  
        if [ -z "$command" ]; then
 -              case "${COMP_WORDS[COMP_CWORD]}" in
 +              case "$cur" in
                --*)   __gitcomp "
                        --paginate
                        --no-pager
        fi
  
        local completion_func="_git_${command//-/_}"
-       declare -F $completion_func >/dev/null && $completion_func && return
+       declare -f $completion_func >/dev/null && $completion_func && return
  
        local expansion=$(__git_aliased_command "$command")
        if [ -n "$expansion" ]; then
                completion_func="_git_${expansion//-/_}"
-               declare -F $completion_func >/dev/null && $completion_func
+               declare -f $completion_func >/dev/null && $completion_func
        fi
  }
  
  _gitk ()
  {
+       if [[ -n ${ZSH_VERSION-} ]]; then
+               emulate -L bash
+               setopt KSH_TYPESET
+       fi
        __git_has_doubledash && return
  
 -      local cur="${COMP_WORDS[COMP_CWORD]}"
 +      local cur
        local g="$(__gitdir)"
        local merge=""
        if [ -f "$g/MERGE_HEAD" ]; then
                merge="--merge"
        fi
 +      _get_comp_words_by_ref -n =: cur
        case "$cur" in
        --*)
                __gitcomp "
@@@ -2603,3 -2433,29 +2646,29 @@@ if [ Cygwin = "$(uname -o 2>/dev/null)
  complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
        || complete -o default -o nospace -F _git git.exe
  fi
+ if [[ -n ${ZSH_VERSION-} ]]; then
+       shopt () {
+               local option
+               if [ $# -ne 2 ]; then
+                       echo "USAGE: $0 (-q|-s|-u) <option>" >&2
+                       return 1
+               fi
+               case "$2" in
+               nullglob)
+                       option="$2"
+                       ;;
+               *)
+                       echo "$0: invalid option: $2" >&2
+                       return 1
+               esac
+               case "$1" in
+               -q)     setopt | grep -q "$option" ;;
+               -u)     unsetopt "$option" ;;
+               -s)     setopt "$option" ;;
+               *)
+                       echo "$0: invalid flag: $1" >&2
+                       return 1
+               esac
+       }
+ fi