Fourth batch
[gitweb.git] / contrib / completion / git-completion.bash
index dd3e925843acf53c439e504101d46d8606ea5d69..59cd3e8e90a382e647c3564bf8943e7de76e8a58 100644 (file)
@@ -37,7 +37,8 @@
 #   GIT_COMPLETION_CHECKOUT_NO_GUESS
 #
 #     When set to "1", do not include "DWIM" suggestions in git-checkout
-#     completion (e.g., completing "foo" when "origin/foo" exists).
+#     and git-switch completion (e.g., completing "foo" when "origin/foo"
+#     exists).
 
 case "$COMP_WORDBREAKS" in
 *:*) : great ;;
@@ -330,13 +331,36 @@ __gitcomp ()
        case "$cur_" in
        --*=)
                ;;
+       --no-*)
+               local c i=0 IFS=$' \t\n'
+               for c in $1; do
+                       if [[ $c == "--" ]]; then
+                               continue
+                       fi
+                       c="$c${4-}"
+                       if [[ $c == "$cur_"* ]]; then
+                               case $c in
+                               --*=|*.) ;;
+                               *) c="$c " ;;
+                               esac
+                               COMPREPLY[i++]="${2-}$c"
+                       fi
+               done
+               ;;
        *)
                local c i=0 IFS=$' \t\n'
                for c in $1; do
+                       if [[ $c == "--" ]]; then
+                               c="--no-...${4-}"
+                               if [[ $c == "$cur_"* ]]; then
+                                       COMPREPLY[i++]="${2-}$c "
+                               fi
+                               break
+                       fi
                        c="$c${4-}"
                        if [[ $c == "$cur_"* ]]; then
                                case $c in
-                               --*=*|*.) ;;
+                               *=|*.) ;;
                                *) c="$c " ;;
                                esac
                                COMPREPLY[i++]="${2-}$c"
@@ -377,7 +401,8 @@ __gitcomp_builtin ()
        if [ -z "$options" ]; then
                # leading and trailing spaces are significant to make
                # option removal work correctly.
-               options=" $(__git ${cmd/_/ } --git-completion-helper) $incl "
+               options=" $incl $(__git ${cmd/_/ } --git-completion-helper) " || return
+
                for i in $excl; do
                        options="${options/ $i / }"
                done
@@ -415,7 +440,7 @@ __gitcomp_nl ()
 # Callers must take care of providing only paths that match the current path
 # to be completed and adding any prefix path components, if necessary.
 # 1: List of newline-separated matching paths, complete with all prefix
-#    path componens.
+#    path components.
 __gitcomp_file_direct ()
 {
        local IFS=$'\n'
@@ -499,7 +524,7 @@ __git_index_files ()
                        # Even when a directory name itself does not contain
                        # any special characters, it will still be quoted if
                        # any of its (stripped) trailing path components do.
-                       # Because of this we may have seen the same direcory
+                       # Because of this we may have seen the same directory
                        # both quoted and unquoted.
                        if (p in paths)
                                # We have seen the same directory unquoted,
@@ -830,9 +855,14 @@ __git_compute_merge_strategies ()
        __git_merge_strategies=$(__git_list_merge_strategies)
 }
 
+__git_merge_strategy_options="ours theirs subtree subtree= patience
+       histogram diff-algorithm= ignore-space-change ignore-all-space
+       ignore-space-at-eol renormalize no-renormalize no-renames
+       find-renames find-renames= rename-threshold="
+
 __git_complete_revlist_file ()
 {
-       local pfx ls ref cur_="$cur"
+       local dequoted_word pfx ls ref cur_="$cur"
        case "$cur_" in
        *..?*:*)
                return
@@ -840,14 +870,18 @@ __git_complete_revlist_file ()
        ?*:*)
                ref="${cur_%%:*}"
                cur_="${cur_#*:}"
-               case "$cur_" in
+
+               __git_dequote "$cur_"
+
+               case "$dequoted_word" in
                ?*/*)
-                       pfx="${cur_%/*}"
-                       cur_="${cur_##*/}"
+                       pfx="${dequoted_word%/*}"
+                       cur_="${dequoted_word##*/}"
                        ls="$ref:$pfx"
                        pfx="$pfx/"
                        ;;
                *)
+                       cur_="$dequoted_word"
                        ls="$ref"
                        ;;
                esac
@@ -857,21 +891,10 @@ __git_complete_revlist_file ()
                *)   pfx="$ref:$pfx" ;;
                esac
 
-               __gitcomp_nl "$(__git ls-tree "$ls" \
-                               | sed '/^100... blob /{
-                                          s,^.*        ,,
-                                          s,$, ,
-                                      }
-                                      /^120000 blob /{
-                                          s,^.*        ,,
-                                          s,$, ,
-                                      }
-                                      /^040000 tree /{
-                                          s,^.*        ,,
-                                          s,$,/,
-                                      }
-                                      s/^.*    //')" \
-                       "$pfx" "$cur_" ""
+               __gitcomp_file "$(__git ls-tree "$ls" \
+                               | sed 's/^.*    //
+                                      s/$//')" \
+                       "$pfx" "$cur_"
                ;;
        *...*)
                pfx="${cur_%...*}..."
@@ -920,6 +943,7 @@ __git_complete_remote_or_refspec ()
                        *) ;;
                        esac
                        ;;
+               --multiple) no_complete_refspec=1; break ;;
                -*) ;;
                *) remote="$i"; break ;;
                esac
@@ -979,12 +1003,21 @@ __git_complete_strategy ()
        -s|--strategy)
                __gitcomp "$__git_merge_strategies"
                return 0
+               ;;
+       -X)
+               __gitcomp "$__git_merge_strategy_options"
+               return 0
+               ;;
        esac
        case "$cur" in
        --strategy=*)
                __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
                return 0
                ;;
+       --strategy-option=*)
+               __gitcomp "$__git_merge_strategy_options" "" "${cur##--strategy-option=}"
+               return 0
+               ;;
        esac
        return 1
 }
@@ -993,7 +1026,7 @@ __git_all_commands=
 __git_compute_all_commands ()
 {
        test -n "$__git_all_commands" ||
-       __git_all_commands=$(git --list-cmds=main,others,alias,nohelpers)
+       __git_all_commands=$(__git --list-cmds=main,others,alias,nohelpers)
 }
 
 # Lists all set config variables starting with the given section prefix,
@@ -1146,6 +1179,7 @@ __git_count_arguments ()
 }
 
 __git_whitespacelist="nowarn warn error error-all fix"
+__git_patchformat="mbox stgit stgit-series hg mboxrd"
 __git_am_inprogress_options="--skip --continue --resolved --abort --quit --show-current-patch"
 
 _git_am ()
@@ -1160,8 +1194,12 @@ _git_am ()
                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
                return
                ;;
+       --patch-format=*)
+               __gitcomp "$__git_patchformat" "" "${cur##--patch-format=}"
+               return
+               ;;
        --*)
-               __gitcomp_builtin am "--no-utf8" \
+               __gitcomp_builtin am "" \
                        "$__git_am_inprogress_options"
                return
        esac
@@ -1183,6 +1221,10 @@ _git_apply ()
 _git_add ()
 {
        case "$cur" in
+       --chmod=*)
+               __gitcomp "+x -x" "" "${cur##--chmod=}"
+               return
+               ;;
        --*)
                __gitcomp_builtin add
                return
@@ -1243,6 +1285,8 @@ _git_bisect ()
        esac
 }
 
+__git_ref_fieldlist="refname objecttype objectsize objectname upstream push HEAD symref"
+
 _git_branch ()
 {
        local i c=1 only_local_ref="n" has_r="n"
@@ -1261,9 +1305,7 @@ _git_branch ()
                __git_complete_refs --cur="${cur##--set-upstream-to=}"
                ;;
        --*)
-               __gitcomp_builtin branch "--no-color --no-abbrev
-                       --no-track --no-column
-                       "
+               __gitcomp_builtin branch
                ;;
        *)
                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
@@ -1304,7 +1346,7 @@ _git_checkout ()
                __gitcomp "diff3 merge" "" "${cur##--conflict=}"
                ;;
        --*)
-               __gitcomp_builtin checkout "--no-track --no-recurse-submodules"
+               __gitcomp_builtin checkout
                ;;
        *)
                # check if --track, --no-track, or --no-guess was specified
@@ -1319,18 +1361,9 @@ _git_checkout ()
        esac
 }
 
-_git_cherry ()
-{
-       case "$cur" in
-       --*)
-               __gitcomp_builtin cherry
-               return
-       esac
-
-       __git_complete_refs
-}
+__git_sequencer_inprogress_options="--continue --quit --abort --skip"
 
-__git_cherry_pick_inprogress_options="--continue --quit --abort"
+__git_cherry_pick_inprogress_options=$__git_sequencer_inprogress_options
 
 _git_cherry_pick ()
 {
@@ -1339,6 +1372,9 @@ _git_cherry_pick ()
                __gitcomp "$__git_cherry_pick_inprogress_options"
                return
        fi
+
+       __git_complete_strategy && return
+
        case "$cur" in
        --*)
                __gitcomp_builtin cherry-pick "" \
@@ -1365,9 +1401,20 @@ _git_clean ()
 
 _git_clone ()
 {
+       case "$prev" in
+       -c|--config)
+               __git_complete_config_variable_name_and_value
+               return
+               ;;
+       esac
        case "$cur" in
+       --config=*)
+               __git_complete_config_variable_name_and_value \
+                       --cur="${cur##--config=}"
+               return
+               ;;
        --*)
-               __gitcomp_builtin clone "--no-single-branch"
+               __gitcomp_builtin clone
                return
                ;;
        esac
@@ -1400,7 +1447,7 @@ _git_commit ()
                return
                ;;
        --*)
-               __gitcomp_builtin commit "--no-edit --verify"
+               __gitcomp_builtin commit
                return
        esac
 
@@ -1469,7 +1516,8 @@ _git_diff ()
 }
 
 __git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
-                       tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc codecompare
+                       tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc
+                       codecompare smerge
 "
 
 _git_difftool ()
@@ -1502,21 +1550,21 @@ _git_fetch ()
                __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
                return
                ;;
+       --filter=*)
+               __gitcomp "blob:none blob:limit= sparse:oid=" "" "${cur##--filter=}"
+               return
+               ;;
        --*)
-               __gitcomp_builtin fetch "--no-tags"
+               __gitcomp_builtin fetch
                return
                ;;
        esac
        __git_complete_remote_or_refspec
 }
 
-__git_format_patch_options="
-       --stdout --attach --no-attach --thread --thread= --no-thread
-       --numbered --start-number --numbered-files --keep-subject --signoff
-       --signature --no-signature --in-reply-to= --cc= --full-index --binary
-       --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix=
-       --inline --suffix= --ignore-if-in-upstream --subject-prefix=
-       --output-directory --reroll-count --to= --quiet --notes
+__git_format_patch_extra_options="
+       --full-index --not --all --no-prefix --src-prefix=
+       --dst-prefix= --notes
 "
 
 _git_format_patch ()
@@ -1529,7 +1577,7 @@ _git_format_patch ()
                return
                ;;
        --*)
-               __gitcomp "$__git_format_patch_options"
+               __gitcomp_builtin format-patch "$__git_format_patch_extra_options"
                return
                ;;
        esac
@@ -1540,7 +1588,7 @@ _git_fsck ()
 {
        case "$cur" in
        --*)
-               __gitcomp_builtin fsck "--no-reflogs"
+               __gitcomp_builtin fsck
                return
                ;;
        esac
@@ -1620,9 +1668,9 @@ _git_help ()
        esac
        if test -n "$GIT_TESTING_ALL_COMMAND_LIST"
        then
-               __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(git --list-cmds=alias,list-guide) gitk"
+               __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(__git --list-cmds=alias,list-guide) gitk"
        else
-               __gitcomp "$(git --list-cmds=main,nohelpers,alias,list-guide) gitk"
+               __gitcomp "$(__git --list-cmds=main,nohelpers,alias,list-guide) gitk"
        fi
 }
 
@@ -1646,7 +1694,7 @@ _git_ls_files ()
 {
        case "$cur" in
        --*)
-               __gitcomp_builtin ls-files "--no-empty-directory"
+               __gitcomp_builtin ls-files
                return
                ;;
        esac
@@ -1702,8 +1750,8 @@ __git_log_shortlog_options="
        --all-match --invert-grep
 "
 
-__git_log_pretty_formats="oneline short medium full fuller email raw format:"
-__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
+__git_log_pretty_formats="oneline short medium full fuller email raw format: mboxrd"
+__git_log_date_formats="relative iso8601 iso8601-strict rfc2822 short local default raw unix format:"
 
 _git_log ()
 {
@@ -1797,12 +1845,7 @@ _git_merge ()
 
        case "$cur" in
        --*)
-               __gitcomp_builtin merge "--no-rerere-autoupdate
-                               --no-commit --no-edit --no-ff
-                               --no-log --no-progress
-                               --no-squash --no-stat
-                               --no-verify-signatures
-                               "
+               __gitcomp_builtin merge
                return
        esac
        __git_complete_refs
@@ -1816,7 +1859,7 @@ _git_mergetool ()
                return
                ;;
        --*)
-               __gitcomp "--tool= --prompt --no-prompt"
+               __gitcomp "--tool= --prompt --no-prompt --gui --no-gui"
                return
                ;;
        esac
@@ -1901,10 +1944,7 @@ _git_pull ()
                return
                ;;
        --*)
-               __gitcomp_builtin pull "--no-autostash --no-commit --no-edit
-                                       --no-ff --no-log --no-progress --no-rebase
-                                       --no-squash --no-stat --no-tags
-                                       --no-verify-signatures"
+               __gitcomp_builtin pull
 
                return
                ;;
@@ -1963,6 +2003,20 @@ _git_push ()
        __git_complete_remote_or_refspec
 }
 
+_git_range_diff ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp "
+                       --creation-factor= --no-dual-color
+                       $__git_diff_common_options
+               "
+               return
+               ;;
+       esac
+       __git_complete_revlist
+}
+
 _git_rebase ()
 {
        __git_find_repo_path
@@ -1989,7 +2043,7 @@ _git_rebase ()
                        --autosquash --no-autosquash
                        --fork-point --no-fork-point
                        --autostash --no-autostash
-                       --verify --no-verify
+                       --verify --no-verify --keep-base
                        --keep-empty --root --force-rebase --no-ff
                        --rerere-autoupdate
                        --exec
@@ -2053,7 +2107,7 @@ _git_send_email ()
                return
                ;;
        --*)
-               __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
+               __gitcomp_builtin send-email "--annotate --bcc --cc --cc-cmd --chain-reply-to
                        --compose --confirm= --dry-run --envelope-sender
                        --from --identity
                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
@@ -2062,7 +2116,7 @@ _git_send_email ()
                        --smtp-server-port --smtp-encryption= --smtp-user
                        --subject --suppress-cc= --suppress-from --thread --to
                        --validate --no-validate
-                       $__git_format_patch_options"
+                       $__git_format_patch_extra_options"
                return
                ;;
        esac
@@ -2095,7 +2149,7 @@ _git_status ()
                return
                ;;
        --*)
-               __gitcomp_builtin status "--no-column"
+               __gitcomp_builtin status
                return
                ;;
        esac
@@ -2120,6 +2174,44 @@ _git_status ()
        __git_complete_index_file "$complete_opt"
 }
 
+_git_switch ()
+{
+       case "$cur" in
+       --conflict=*)
+               __gitcomp "diff3 merge" "" "${cur##--conflict=}"
+               ;;
+       --*)
+               __gitcomp_builtin switch
+               ;;
+       *)
+               # check if --track, --no-track, or --no-guess was specified
+               # if so, disable DWIM mode
+               local track_opt="--track" only_local_ref=n
+               if [ "$GIT_COMPLETION_CHECKOUT_NO_GUESS" = "1" ] ||
+                  [ -n "$(__git_find_on_cmdline "--track --no-track --no-guess")" ]; then
+                       track_opt=''
+               fi
+               # explicit --guess enables DWIM mode regardless of
+               # $GIT_COMPLETION_CHECKOUT_NO_GUESS
+               if [ -n "$(__git_find_on_cmdline "--guess")" ]; then
+                       track_opt='--track'
+               fi
+               if [ -z "$(__git_find_on_cmdline "-d --detach")" ]; then
+                       only_local_ref=y
+               else
+                       # --guess --detach is invalid combination, no
+                       # dwim will be done when --detach is specified
+                       track_opt=
+               fi
+               if [ $only_local_ref = y -a -z "$track_opt" ]; then
+                       __gitcomp_direct "$(__git_heads "" "$cur" " ")"
+               else
+                       __git_complete_refs $track_opt
+               fi
+               ;;
+       esac
+}
+
 __git_config_get_set_variables ()
 {
        local prevword word config_file= c=$cword
@@ -2142,490 +2234,287 @@ __git_config_get_set_variables ()
        __git config $config_file --name-only --list
 }
 
-_git_config ()
+__git_config_vars=
+__git_compute_config_vars ()
 {
-       case "$prev" in
+       test -n "$__git_config_vars" ||
+       __git_config_vars="$(git help --config-for-completion | sort -u)"
+}
+
+# Completes possible values of various configuration variables.
+#
+# Usage: __git_complete_config_variable_value [<option>]...
+# --varname=<word>: The name of the configuration variable whose value is
+#                   to be completed.  Defaults to the previous word on the
+#                   command line.
+# --cur=<word>: The current value to be completed.  Defaults to the current
+#               word to be completed.
+__git_complete_config_variable_value ()
+{
+       local varname="$prev" cur_="$cur"
+
+       while test $# != 0; do
+               case "$1" in
+               --varname=*)    varname="${1##--varname=}" ;;
+               --cur=*)        cur_="${1##--cur=}" ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+
+       if [ "${BASH_VERSINFO[0]:-0}" -ge 4 ]; then
+               varname="${varname,,}"
+       else
+               varname="$(echo "$varname" |tr A-Z a-z)"
+       fi
+
+       case "$varname" in
        branch.*.remote|branch.*.pushremote)
-               __gitcomp_nl "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)" "" "$cur_"
                return
                ;;
        branch.*.merge)
-               __git_complete_refs
+               __git_complete_refs --cur="$cur_"
                return
                ;;
        branch.*.rebase)
-               __gitcomp "false true merges preserve interactive"
+               __gitcomp "false true merges preserve interactive" "" "$cur_"
                return
                ;;
        remote.pushdefault)
-               __gitcomp_nl "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)" "" "$cur_"
                return
                ;;
        remote.*.fetch)
-               local remote="${prev#remote.}"
+               local remote="${varname#remote.}"
                remote="${remote%.fetch}"
-               if [ -z "$cur" ]; then
+               if [ -z "$cur_" ]; then
                        __gitcomp_nl "refs/heads/" "" "" ""
                        return
                fi
-               __gitcomp_nl "$(__git_refs_remotes "$remote")"
+               __gitcomp_nl "$(__git_refs_remotes "$remote")" "" "$cur_"
                return
                ;;
        remote.*.push)
-               local remote="${prev#remote.}"
+               local remote="${varname#remote.}"
                remote="${remote%.push}"
                __gitcomp_nl "$(__git for-each-ref \
-                       --format='%(refname):%(refname)' refs/heads)"
+                       --format='%(refname):%(refname)' refs/heads)" "" "$cur_"
                return
                ;;
        pull.twohead|pull.octopus)
                __git_compute_merge_strategies
-               __gitcomp "$__git_merge_strategies"
-               return
-               ;;
-       color.branch|color.diff|color.interactive|\
-       color.showbranch|color.status|color.ui)
-               __gitcomp "always never auto"
+               __gitcomp "$__git_merge_strategies" "" "$cur_"
                return
                ;;
        color.pager)
-               __gitcomp "false true"
+               __gitcomp "false true" "" "$cur_"
                return
                ;;
        color.*.*)
                __gitcomp "
                        normal black red green yellow blue magenta cyan white
                        bold dim ul blink reverse
-                       "
+                       " "" "$cur_"
+               return
+               ;;
+       color.*)
+               __gitcomp "false true always never auto" "" "$cur_"
                return
                ;;
        diff.submodule)
-               __gitcomp "log short"
+               __gitcomp "$__git_diff_submodule_formats" "" "$cur_"
                return
                ;;
        help.format)
-               __gitcomp "man info web html"
+               __gitcomp "man info web html" "" "$cur_"
                return
                ;;
        log.date)
-               __gitcomp "$__git_log_date_formats"
+               __gitcomp "$__git_log_date_formats" "" "$cur_"
                return
                ;;
        sendemail.aliasfiletype)
-               __gitcomp "mutt mailrc pine elm gnus"
+               __gitcomp "mutt mailrc pine elm gnus" "" "$cur_"
                return
                ;;
        sendemail.confirm)
-               __gitcomp "$__git_send_email_confirm_options"
+               __gitcomp "$__git_send_email_confirm_options" "" "$cur_"
                return
                ;;
        sendemail.suppresscc)
-               __gitcomp "$__git_send_email_suppresscc_options"
+               __gitcomp "$__git_send_email_suppresscc_options" "" "$cur_"
                return
                ;;
        sendemail.transferencoding)
-               __gitcomp "7bit 8bit quoted-printable base64"
-               return
-               ;;
-       --get|--get-all|--unset|--unset-all)
-               __gitcomp_nl "$(__git_config_get_set_variables)"
+               __gitcomp "7bit 8bit quoted-printable base64" "" "$cur_"
                return
                ;;
        *.*)
                return
                ;;
        esac
-       case "$cur" in
-       --*)
-               __gitcomp_builtin config
-               return
-               ;;
+}
+
+# Completes configuration sections, subsections, variable names.
+#
+# Usage: __git_complete_config_variable_name [<option>]...
+# --cur=<word>: The current configuration section/variable name to be
+#               completed.  Defaults to the current word to be completed.
+# --sfx=<suffix>: A suffix to be appended to each fully completed
+#                 configuration variable name (but not to sections or
+#                 subsections) instead of the default space.
+__git_complete_config_variable_name ()
+{
+       local cur_="$cur" sfx
+
+       while test $# != 0; do
+               case "$1" in
+               --cur=*)        cur_="${1##--cur=}" ;;
+               --sfx=*)        sfx="${1##--sfx=}" ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+
+       case "$cur_" in
        branch.*.*)
-               local pfx="${cur%.*}." cur_="${cur##*.}"
-               __gitcomp "remote pushremote merge mergeoptions rebase" "$pfx" "$cur_"
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx"
                return
                ;;
        branch.*)
-               local pfx="${cur%.*}." cur_="${cur#*.}"
+               local pfx="${cur%.*}."
+               cur_="${cur#*.}"
                __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
-               __gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_"
+               __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "$sfx"
                return
                ;;
        guitool.*.*)
-               local pfx="${cur%.*}." cur_="${cur##*.}"
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
                __gitcomp "
-                       argprompt cmd confirm needsfile noconsole norescan
-                       prompt revprompt revunmerged title
-                       " "$pfx" "$cur_"
+                       argPrompt cmd confirm needsFile noConsole noRescan
+                       prompt revPrompt revUnmerged title
+                       " "$pfx" "$cur_" "$sfx"
                return
                ;;
        difftool.*.*)
-               local pfx="${cur%.*}." cur_="${cur##*.}"
-               __gitcomp "cmd path" "$pfx" "$cur_"
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
                return
                ;;
        man.*.*)
-               local pfx="${cur%.*}." cur_="${cur##*.}"
-               __gitcomp "cmd path" "$pfx" "$cur_"
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
                return
                ;;
        mergetool.*.*)
-               local pfx="${cur%.*}." cur_="${cur##*.}"
-               __gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx"
                return
                ;;
        pager.*)
-               local pfx="${cur%.*}." cur_="${cur#*.}"
+               local pfx="${cur_%.*}."
+               cur_="${cur_#*.}"
                __git_compute_all_commands
-               __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
+               __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "$sfx"
                return
                ;;
        remote.*.*)
-               local pfx="${cur%.*}." cur_="${cur##*.}"
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
                __gitcomp "
                        url proxy fetch push mirror skipDefaultUpdate
-                       receivepack uploadpack tagopt pushurl
-                       " "$pfx" "$cur_"
+                       receivepack uploadpack tagOpt pushurl
+                       " "$pfx" "$cur_" "$sfx"
                return
                ;;
        remote.*)
-               local pfx="${cur%.*}." cur_="${cur#*.}"
+               local pfx="${cur_%.*}."
+               cur_="${cur_#*.}"
                __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
-               __gitcomp_nl_append "pushdefault" "$pfx" "$cur_"
+               __gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "$sfx"
                return
                ;;
        url.*.*)
-               local pfx="${cur%.*}." cur_="${cur##*.}"
-               __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
-               return
-               ;;
-       esac
-       __gitcomp "
-               add.ignoreErrors
-               advice.amWorkDir
-               advice.commitBeforeMerge
-               advice.detachedHead
-               advice.implicitIdentity
-               advice.pushAlreadyExists
-               advice.pushFetchFirst
-               advice.pushNeedsForce
-               advice.pushNonFFCurrent
-               advice.pushNonFFMatching
-               advice.pushUpdateRejected
-               advice.resolveConflict
-               advice.rmHints
-               advice.statusHints
-               advice.statusUoption
-               advice.ignoredHook
-               alias.
-               am.keepcr
-               am.threeWay
-               apply.ignorewhitespace
-               apply.whitespace
-               branch.autosetupmerge
-               branch.autosetuprebase
-               browser.
-               clean.requireForce
-               color.branch
-               color.branch.current
-               color.branch.local
-               color.branch.plain
-               color.branch.remote
-               color.decorate.HEAD
-               color.decorate.branch
-               color.decorate.remoteBranch
-               color.decorate.stash
-               color.decorate.tag
-               color.diff
-               color.diff.commit
-               color.diff.frag
-               color.diff.func
-               color.diff.meta
-               color.diff.new
-               color.diff.old
-               color.diff.plain
-               color.diff.whitespace
-               color.grep
-               color.grep.context
-               color.grep.filename
-               color.grep.function
-               color.grep.linenumber
-               color.grep.match
-               color.grep.selected
-               color.grep.separator
-               color.interactive
-               color.interactive.error
-               color.interactive.header
-               color.interactive.help
-               color.interactive.prompt
-               color.pager
-               color.showbranch
-               color.status
-               color.status.added
-               color.status.changed
-               color.status.header
-               color.status.localBranch
-               color.status.nobranch
-               color.status.remoteBranch
-               color.status.unmerged
-               color.status.untracked
-               color.status.updated
-               color.ui
-               commit.cleanup
-               commit.gpgSign
-               commit.status
-               commit.template
-               commit.verbose
-               core.abbrev
-               core.askpass
-               core.attributesfile
-               core.autocrlf
-               core.bare
-               core.bigFileThreshold
-               core.checkStat
-               core.commentChar
-               core.commitGraph
-               core.compression
-               core.createObject
-               core.deltaBaseCacheLimit
-               core.editor
-               core.eol
-               core.excludesfile
-               core.fileMode
-               core.fsyncobjectfiles
-               core.gitProxy
-               core.hideDotFiles
-               core.hooksPath
-               core.ignoreStat
-               core.ignorecase
-               core.logAllRefUpdates
-               core.loosecompression
-               core.notesRef
-               core.packedGitLimit
-               core.packedGitWindowSize
-               core.packedRefsTimeout
-               core.pager
-               core.precomposeUnicode
-               core.preferSymlinkRefs
-               core.preloadindex
-               core.protectHFS
-               core.protectNTFS
-               core.quotepath
-               core.repositoryFormatVersion
-               core.safecrlf
-               core.sharedRepository
-               core.sparseCheckout
-               core.splitIndex
-               core.sshCommand
-               core.symlinks
-               core.trustctime
-               core.untrackedCache
-               core.warnAmbiguousRefs
-               core.whitespace
-               core.worktree
-               credential.helper
-               credential.useHttpPath
-               credential.username
-               credentialCache.ignoreSIGHUP
-               diff.autorefreshindex
-               diff.external
-               diff.ignoreSubmodules
-               diff.mnemonicprefix
-               diff.noprefix
-               diff.renameLimit
-               diff.renames
-               diff.statGraphWidth
-               diff.submodule
-               diff.suppressBlankEmpty
-               diff.tool
-               diff.wordRegex
-               diff.algorithm
-               difftool.
-               difftool.prompt
-               fetch.recurseSubmodules
-               fetch.unpackLimit
-               format.attach
-               format.cc
-               format.coverLetter
-               format.from
-               format.headers
-               format.numbered
-               format.pretty
-               format.signature
-               format.signoff
-               format.subjectprefix
-               format.suffix
-               format.thread
-               format.to
-               gc.
-               gc.aggressiveDepth
-               gc.aggressiveWindow
-               gc.auto
-               gc.autoDetach
-               gc.autopacklimit
-               gc.logExpiry
-               gc.packrefs
-               gc.pruneexpire
-               gc.reflogexpire
-               gc.reflogexpireunreachable
-               gc.rerereresolved
-               gc.rerereunresolved
-               gc.worktreePruneExpire
-               gitcvs.allbinary
-               gitcvs.commitmsgannotation
-               gitcvs.dbTableNamePrefix
-               gitcvs.dbdriver
-               gitcvs.dbname
-               gitcvs.dbpass
-               gitcvs.dbuser
-               gitcvs.enabled
-               gitcvs.logfile
-               gitcvs.usecrlfattr
-               guitool.
-               gui.blamehistoryctx
-               gui.commitmsgwidth
-               gui.copyblamethreshold
-               gui.diffcontext
-               gui.encoding
-               gui.fastcopyblame
-               gui.matchtrackingbranch
-               gui.newbranchtemplate
-               gui.pruneduringfetch
-               gui.spellingdictionary
-               gui.trustmtime
-               help.autocorrect
-               help.browser
-               help.format
-               http.lowSpeedLimit
-               http.lowSpeedTime
-               http.maxRequests
-               http.minSessions
-               http.noEPSV
-               http.postBuffer
-               http.proxy
-               http.sslCipherList
-               http.sslVersion
-               http.sslCAInfo
-               http.sslCAPath
-               http.sslCert
-               http.sslCertPasswordProtected
-               http.sslKey
-               http.sslVerify
-               http.useragent
-               i18n.commitEncoding
-               i18n.logOutputEncoding
-               imap.authMethod
-               imap.folder
-               imap.host
-               imap.pass
-               imap.port
-               imap.preformattedHTML
-               imap.sslverify
-               imap.tunnel
-               imap.user
-               init.templatedir
-               instaweb.browser
-               instaweb.httpd
-               instaweb.local
-               instaweb.modulepath
-               instaweb.port
-               interactive.singlekey
-               log.date
-               log.decorate
-               log.showroot
-               mailmap.file
-               man.
-               man.viewer
-               merge.
-               merge.conflictstyle
-               merge.log
-               merge.renameLimit
-               merge.renormalize
-               merge.stat
-               merge.tool
-               merge.verbosity
-               mergetool.
-               mergetool.keepBackup
-               mergetool.keepTemporaries
-               mergetool.prompt
-               notes.displayRef
-               notes.rewrite.
-               notes.rewrite.amend
-               notes.rewrite.rebase
-               notes.rewriteMode
-               notes.rewriteRef
-               pack.compression
-               pack.deltaCacheLimit
-               pack.deltaCacheSize
-               pack.depth
-               pack.indexVersion
-               pack.packSizeLimit
-               pack.threads
-               pack.window
-               pack.windowMemory
-               pager.
-               pretty.
-               pull.octopus
-               pull.twohead
-               push.default
-               push.followTags
-               rebase.autosquash
-               rebase.stat
-               receive.autogc
-               receive.denyCurrentBranch
-               receive.denyDeleteCurrent
-               receive.denyDeletes
-               receive.denyNonFastForwards
-               receive.fsckObjects
-               receive.unpackLimit
-               receive.updateserverinfo
-               remote.pushdefault
-               remotes.
-               repack.usedeltabaseoffset
-               rerere.autoupdate
-               rerere.enabled
-               sendemail.
-               sendemail.aliasesfile
-               sendemail.aliasfiletype
-               sendemail.bcc
-               sendemail.cc
-               sendemail.cccmd
-               sendemail.chainreplyto
-               sendemail.confirm
-               sendemail.envelopesender
-               sendemail.from
-               sendemail.identity
-               sendemail.multiedit
-               sendemail.signedoffbycc
-               sendemail.smtpdomain
-               sendemail.smtpencryption
-               sendemail.smtppass
-               sendemail.smtpserver
-               sendemail.smtpserveroption
-               sendemail.smtpserverport
-               sendemail.smtpuser
-               sendemail.suppresscc
-               sendemail.suppressfrom
-               sendemail.thread
-               sendemail.to
-               sendemail.tocmd
-               sendemail.validate
-               sendemail.smtpbatchsize
-               sendemail.smtprelogindelay
-               showbranch.default
-               status.relativePaths
-               status.showUntrackedFiles
-               status.submodulesummary
-               submodule.
-               tar.umask
-               transfer.unpackLimit
-               url.
-               user.email
-               user.name
-               user.signingkey
-               web.browser
-               branch. remote.
-       "
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       *.*)
+               __git_compute_config_vars
+               __gitcomp "$__git_config_vars" "" "$cur_" "$sfx"
+               ;;
+       *)
+               __git_compute_config_vars
+               __gitcomp "$(echo "$__git_config_vars" |
+                               awk -F . '{
+                                       sections[$1] = 1
+                               }
+                               END {
+                                       for (s in sections)
+                                               print s "."
+                               }
+                               ')" "" "$cur_"
+               ;;
+       esac
+}
+
+# Completes '='-separated configuration sections/variable names and values
+# for 'git -c section.name=value'.
+#
+# Usage: __git_complete_config_variable_name_and_value [<option>]...
+# --cur=<word>: The current configuration section/variable name/value to be
+#               completed. Defaults to the current word to be completed.
+__git_complete_config_variable_name_and_value ()
+{
+       local cur_="$cur"
+
+       while test $# != 0; do
+               case "$1" in
+               --cur=*)        cur_="${1##--cur=}" ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+
+       case "$cur_" in
+       *=*)
+               __git_complete_config_variable_value \
+                       --varname="${cur_%%=*}" --cur="${cur_#*=}"
+               ;;
+       *)
+               __git_complete_config_variable_name --cur="$cur_" --sfx='='
+               ;;
+       esac
+}
+
+_git_config ()
+{
+       case "$prev" in
+       --get|--get-all|--unset|--unset-all)
+               __gitcomp_nl "$(__git_config_get_set_variables)"
+               return
+               ;;
+       *.*)
+               __git_complete_config_variable_value
+               return
+               ;;
+       esac
+       case "$cur" in
+       --*)
+               __gitcomp_builtin config
+               ;;
+       *)
+               __git_complete_config_variable_name
+               ;;
+       esac
 }
 
 _git_remote ()
@@ -2649,7 +2538,7 @@ _git_remote ()
 
        case "$subcommand,$cur" in
        add,--*)
-               __gitcomp_builtin remote_add "--no-tags"
+               __gitcomp_builtin remote_add
                ;;
        add,*)
                ;;
@@ -2666,7 +2555,7 @@ _git_remote ()
                __gitcomp_builtin remote_update
                ;;
        update,*)
-               __gitcomp "$(__git_get_config_variables "remotes")"
+               __gitcomp "$(__git_remotes) $(__git_get_config_variables "remotes")"
                ;;
        set-url,--*)
                __gitcomp_builtin remote_set-url
@@ -2686,6 +2575,10 @@ _git_remote ()
 _git_replace ()
 {
        case "$cur" in
+       --format=*)
+               __gitcomp "short medium long" "" "${cur##--format=}"
+               return
+               ;;
        --*)
                __gitcomp_builtin replace
                return
@@ -2718,7 +2611,22 @@ _git_reset ()
        __git_complete_refs
 }
 
-__git_revert_inprogress_options="--continue --quit --abort"
+_git_restore ()
+{
+       case "$cur" in
+       --conflict=*)
+               __gitcomp "diff3 merge" "" "${cur##--conflict=}"
+               ;;
+       --source=*)
+               __git_complete_refs --cur="${cur##--source=}"
+               ;;
+       --*)
+               __gitcomp_builtin restore
+               ;;
+       esac
+}
+
+__git_revert_inprogress_options=$__git_sequencer_inprogress_options
 
 _git_revert ()
 {
@@ -2727,9 +2635,10 @@ _git_revert ()
                __gitcomp "$__git_revert_inprogress_options"
                return
        fi
+       __git_complete_strategy && return
        case "$cur" in
        --*)
-               __gitcomp_builtin revert "--no-edit" \
+               __gitcomp_builtin revert "" \
                        "$__git_revert_inprogress_options"
                return
                ;;
@@ -2799,7 +2708,7 @@ _git_show_branch ()
 {
        case "$cur" in
        --*)
-               __gitcomp_builtin show-branch "--no-color"
+               __gitcomp_builtin show-branch
                return
                ;;
        esac
@@ -2844,6 +2753,9 @@ _git_stash ()
                drop,--*)
                        __gitcomp "--quiet"
                        ;;
+               list,--*)
+                       __gitcomp "--name-status --oneline --patch-with-stat"
+                       ;;
                show,--*|branch,--*)
                        ;;
                branch,*)
@@ -2868,7 +2780,7 @@ _git_submodule ()
 {
        __git_has_doubledash && return
 
-       local subcommands="add status init deinit update summary foreach sync"
+       local subcommands="add status init deinit update set-branch summary foreach sync absorbgitdirs"
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
        if [ -z "$subcommand" ]; then
                case "$cur" in
@@ -2899,6 +2811,9 @@ _git_submodule ()
                        --force --rebase --merge --reference --depth --recursive --jobs
                "
                ;;
+       set-branch,--*)
+               __gitcomp "--default --branch"
+               ;;
        summary,--*)
                __gitcomp "--cached --files --summary-limit"
                ;;
@@ -3155,7 +3070,11 @@ __git_main ()
                        # Bash filename completion
                        return
                        ;;
-               -c|--namespace)
+               -c)
+                       __git_complete_config_variable_name_and_value
+                       return
+                       ;;
+               --namespace)
                        # we don't support completing these options' arguments
                        return
                        ;;
@@ -3183,7 +3102,7 @@ __git_main ()
                        then
                                __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
                        else
-                               __gitcomp "$(git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)"
+                               __gitcomp "$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)"
                        fi
                        ;;
                esac
@@ -3281,7 +3200,7 @@ if [[ -n ${ZSH_VERSION-} ]] &&
 
                local IFS=$'\n'
                compset -P '*[=:]'
-               compadd -Q -f -- ${=1} && _ret=0
+               compadd -f -- ${=1} && _ret=0
        }
 
        __gitcomp_file ()
@@ -3290,7 +3209,7 @@ if [[ -n ${ZSH_VERSION-} ]] &&
 
                local IFS=$'\n'
                compset -P '*[=:]'
-               compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
+               compadd -p "${2-}" -f -- ${=1} && _ret=0
        }
 
        _git ()