Imported Upstream version 2.9.3
[platform/upstream/git.git] / contrib / completion / git-completion.bash
index 019026e..bd25b0a 100644 (file)
 #    *) local and remote tag names
 #    *) .git/remotes file names
 #    *) git 'subcommands'
+#    *) git email aliases for git-send-email
 #    *) tree paths within 'ref:path/to/file' expressions
 #    *) file paths within current working directory and index
 #    *) common --long-options
 #
 # To use these routines:
 #
-#    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
+#    1) Copy this file to somewhere (e.g. ~/.git-completion.bash).
 #    2) Add the following line to your .bashrc/.zshrc:
-#        source ~/.git-completion.sh
+#        source ~/.git-completion.bash
 #    3) Consider changing your PS1 to also show the current branch,
 #       see git-prompt.sh for details.
+#
+# If you use complex aliases of form '!f() { ... }; f', you can use the null
+# command ':' as the first command in the function body to declare the desired
+# completion style.  For example '!f() { : git commit ; ... }; f' will
+# tell the completion to use commit completion.  This also works with aliases
+# of form "!sh -c '...'".  For example, "!sh -c ': git commit ; ... '".
 
 case "$COMP_WORDBREAKS" in
 *:*) : great ;;
@@ -180,7 +187,7 @@ fi
 
 __gitcompappend ()
 {
-       local i=${#COMPREPLY[@]}
+       local i=${#COMPREPLY[@]}
        for x in $1; do
                if [[ "$x" == "$3"* ]]; then
                        COMPREPLY[i++]="$2$x$4"
@@ -275,16 +282,12 @@ __gitcomp_file ()
 # argument, and using the options specified in the second argument.
 __git_ls_files_helper ()
 {
-       (
-               test -n "${CDPATH+set}" && unset CDPATH
-               cd "$1"
-               if [ "$2" == "--committable" ]; then
-                       git diff-index --name-only --relative HEAD
-               else
-                       # NOTE: $2 is not quoted in order to support multiple options
-                       git ls-files --exclude-standard $2
-               fi
-       ) 2>/dev/null
+       if [ "$2" == "--committable" ]; then
+               git -C "$1" diff-index --name-only --relative HEAD
+       else
+               # NOTE: $2 is not quoted in order to support multiple options
+               git -C "$1" ls-files --exclude-standard $2
+       fi 2>/dev/null
 }
 
 
@@ -382,7 +385,8 @@ __git_refs ()
                ;;
        *)
                echo "HEAD"
-               git for-each-ref --format="%(refname:short)" -- "refs/remotes/$dir/" | sed -e "s#^$dir/##"
+               git for-each-ref --format="%(refname:short)" -- \
+                       "refs/remotes/$dir/" 2>/dev/null | sed -e "s#^$dir/##"
                ;;
        esac
 }
@@ -408,12 +412,9 @@ __git_refs_remotes ()
 
 __git_remotes ()
 {
-       local i IFS=$'\n' d="$(__gitdir)"
+       local d="$(__gitdir)"
        test -d "$d/remotes" && ls -1 "$d/remotes"
-       for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
-               i="${i#remote.}"
-               echo "${i/.url*/}"
-       done
+       git --git-dir="$d" remote
 }
 
 __git_list_merge_strategies ()
@@ -516,7 +517,7 @@ __git_complete_index_file ()
                ;;
        esac
 
-       __gitcomp_file "$(__git_index_files "$1" "$pfx")" "$pfx" "$cur_"
+       __gitcomp_file "$(__git_index_files "$1" ${pfx:+"$pfx"})" "$pfx" "$cur_"
 }
 
 __git_complete_file ()
@@ -663,10 +664,11 @@ __git_list_porcelain_commands ()
                check-mailmap)    : plumbing;;
                check-ref-format) : plumbing;;
                checkout-index)   : plumbing;;
+               column)           : internal helper;;
                commit-tree)      : plumbing;;
                count-objects)    : infrequent;;
-               credential-cache) : credentials helper;;
-               credential-store) : credentials helper;;
+               credential)       : credentials;;
+               credential-*)     : credentials helper;;
                cvsexportcommit)  : export;;
                cvsimport)        : import;;
                cvsserver)        : daemon;;
@@ -735,35 +737,28 @@ __git_list_porcelain_commands ()
 __git_porcelain_commands=
 __git_compute_porcelain_commands ()
 {
-       __git_compute_all_commands
        test -n "$__git_porcelain_commands" ||
        __git_porcelain_commands=$(__git_list_porcelain_commands)
 }
 
-__git_pretty_aliases ()
+# Lists all set config variables starting with the given section prefix,
+# with the prefix removed.
+__git_get_config_variables ()
 {
-       local i IFS=$'\n'
-       for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do
-               case "$i" in
-               pretty.*)
-                       i="${i#pretty.}"
-                       echo "${i/ */}"
-                       ;;
-               esac
+       local section="$1" i IFS=$'\n'
+       for i in $(git --git-dir="$(__gitdir)" config --name-only --get-regexp "^$section\..*" 2>/dev/null); do
+               echo "${i#$section.}"
        done
 }
 
+__git_pretty_aliases ()
+{
+       __git_get_config_variables "pretty"
+}
+
 __git_aliases ()
 {
-       local i IFS=$'\n'
-       for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
-               case "$i" in
-               alias.*)
-                       i="${i#alias.}"
-                       echo "${i/ */}"
-                       ;;
-               esac
-       done
+       __git_get_config_variables "alias"
 }
 
 # __git_aliased_command requires 1 argument
@@ -781,6 +776,10 @@ __git_aliased_command ()
                -*)     : option ;;
                *=*)    : setting env ;;
                git)    : git itself ;;
+               \(\))   : skip parens of shell function definition ;;
+               {)      : skip start of shell helper function ;;
+               :)      : skip null command ;;
+               \'*)    : skip opening quote after sh -c ;;
                *)
                        echo "$word"
                        return
@@ -973,7 +972,7 @@ _git_branch ()
 
        case "$cur" in
        --set-upstream-to=*)
-               __gitcomp "$(__git_refs)" "" "${cur##--set-upstream-to=}"
+               __gitcomp_nl "$(__git_refs)" "" "${cur##--set-upstream-to=}"
                ;;
        --*)
                __gitcomp "
@@ -1041,7 +1040,7 @@ _git_checkout ()
 
 _git_cherry ()
 {
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_cherry_pick ()
@@ -1093,6 +1092,7 @@ _git_clone ()
                        --depth
                        --single-branch
                        --branch
+                       --recurse-submodules
                        "
                return
                ;;
@@ -1110,7 +1110,7 @@ _git_commit ()
 
        case "$cur" in
        --cleanup=*)
-               __gitcomp "default strip verbatim whitespace
+               __gitcomp "default scissors strip verbatim whitespace
                        " "" "${cur##--cleanup=}"
                return
                ;;
@@ -1165,12 +1165,12 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
                        --full-index --binary --abbrev --diff-filter=
                        --find-copies-harder
                        --text --ignore-space-at-eol --ignore-space-change
-                       --ignore-all-space --exit-code --quiet --ext-diff
-                       --no-ext-diff
+                       --ignore-all-space --ignore-blank-lines --exit-code
+                       --quiet --ext-diff --no-ext-diff
                        --no-prefix --src-prefix= --dst-prefix=
                        --inter-hunk-context=
                        --patience --histogram --minimal
-                       --raw --word-diff
+                       --raw --word-diff --word-diff-regex=
                        --dirstat --dirstat= --dirstat-by-file
                        --dirstat-by-file= --cumulative
                        --diff-algorithm=
@@ -1197,7 +1197,7 @@ _git_diff ()
 }
 
 __git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
-                       tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3 codecompare
+                       tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc codecompare
 "
 
 _git_difftool ()
@@ -1298,7 +1298,7 @@ _git_gitk ()
 }
 
 __git_match_ctag() {
-       awk "/^${1////\\/}/ { print \$1 }" "$2"
+       awk "/^${1//\//\\/}/ { print \$1 }" "$2"
 }
 
 _git_grep ()
@@ -1313,6 +1313,7 @@ _git_grep ()
                        --full-name --line-number
                        --extended-regexp --basic-regexp --fixed-strings
                        --perl-regexp
+                       --threads
                        --files-with-matches --name-only
                        --files-without-match
                        --max-depth
@@ -1339,15 +1340,15 @@ _git_help ()
 {
        case "$cur" in
        --*)
-               __gitcomp "--all --info --man --web"
+               __gitcomp "--all --guides --info --man --web"
                return
                ;;
        esac
        __git_compute_all_commands
        __gitcomp "$__git_all_commands $(__git_aliases)
                attributes cli core-tutorial cvs-migration
-               diffcore gitk glossary hooks ignore modules
-               namespaces repository-layout tutorial tutorial-2
+               diffcore everyday gitk glossary hooks ignore modules
+               namespaces repository-layout revisions tutorial tutorial-2
                workflows
                "
 }
@@ -1418,7 +1419,7 @@ __git_log_gitk_options="
 # Options that go well for log and shortlog (not gitk)
 __git_log_shortlog_options="
        --author= --committer= --grep=
-       --all-match
+       --all-match --invert-grep
 "
 
 __git_log_pretty_formats="oneline short medium full fuller email raw format:"
@@ -1444,7 +1445,7 @@ _git_log ()
                return
                ;;
        --decorate=*)
-               __gitcomp "long short" "" "${cur##--decorate=}"
+               __gitcomp "full short no" "" "${cur##--decorate=}"
                return
                ;;
        --*)
@@ -1457,6 +1458,8 @@ _git_log ()
                        --abbrev-commit --abbrev=
                        --relative-date --date=
                        --pretty= --format= --oneline
+                       --show-signature
+                       --cherry-mark
                        --cherry-pick
                        --graph
                        --decorate --decorate=
@@ -1611,12 +1614,33 @@ _git_pull ()
 
 __git_push_recurse_submodules="check on-demand"
 
+__git_complete_force_with_lease ()
+{
+       local cur_=$1
+
+       case "$cur_" in
+       --*=)
+               ;;
+       *:*)
+               __gitcomp_nl "$(__git_refs)" "" "${cur_#*:}"
+               ;;
+       *)
+               __gitcomp_nl "$(__git_refs)" "" "$cur_"
+               ;;
+       esac
+}
+
 _git_push ()
 {
        case "$prev" in
        --repo)
                __gitcomp_nl "$(__git_remotes)"
                return
+               ;;
+       --recurse-submodules)
+               __gitcomp "$__git_push_recurse_submodules"
+               return
+               ;;
        esac
        case "$cur" in
        --repo=*)
@@ -1627,11 +1651,16 @@ _git_push ()
                __gitcomp "$__git_push_recurse_submodules" "" "${cur##--recurse-submodules=}"
                return
                ;;
+       --force-with-lease=*)
+               __git_complete_force_with_lease "${cur##--force-with-lease=}"
+               return
+               ;;
        --*)
                __gitcomp "
                        --all --mirror --tags --dry-run --force --verbose
+                       --quiet --prune --delete --follow-tags
                        --receive-pack= --repo= --set-upstream
-                       --recurse-submodules=
+                       --force-with-lease --force-with-lease= --recurse-submodules=
                "
                return
                ;;
@@ -1642,7 +1671,10 @@ _git_push ()
 _git_rebase ()
 {
        local dir="$(__gitdir)"
-       if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
+       if [ -f "$dir"/rebase-merge/interactive ]; then
+               __gitcomp "--continue --skip --abort --edit-todo"
+               return
+       elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
                __gitcomp "--continue --skip --abort"
                return
        fi
@@ -1658,7 +1690,12 @@ _git_rebase ()
                        --preserve-merges --stat --no-stat
                        --committer-date-is-author-date --ignore-date
                        --ignore-whitespace --whitespace=
-                       --autosquash --fork-point --no-fork-point
+                       --autosquash --no-autosquash
+                       --fork-point --no-fork-point
+                       --autostash --no-autostash
+                       --verify --no-verify
+                       --keep-empty --root --force-rebase --no-ff
+                       --exec
                        "
 
                return
@@ -1683,6 +1720,15 @@ __git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
 
 _git_send_email ()
 {
+       case "$prev" in
+       --to|--cc|--bcc|--from)
+               __gitcomp "
+               $(git --git-dir="$(__gitdir)" send-email --dump-aliases 2>/dev/null)
+               "
+               return
+               ;;
+       esac
+
        case "$cur" in
        --confirm=*)
                __gitcomp "
@@ -1707,6 +1753,12 @@ _git_send_email ()
                        " "" "${cur##--thread=}"
                return
                ;;
+       --to=*|--cc=*|--bcc=*|--from=*)
+               __gitcomp "
+               $(git --git-dir="$(__gitdir)" send-email --dump-aliases 2>/dev/null)
+               " "" "${cur#--*=}"
+               return
+               ;;
        --*)
                __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
                        --compose --confirm= --dry-run --envelope-sender
@@ -1748,15 +1800,7 @@ __git_config_get_set_variables ()
                c=$((--c))
        done
 
-       git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
-       while read -r line
-       do
-               case "$line" in
-               *.*=*)
-                       echo "${line/=*/}"
-                       ;;
-               esac
-       done
+       git --git-dir="$(__gitdir)" config $config_file --name-only --list 2>/dev/null
 }
 
 _git_config ()
@@ -1771,7 +1815,7 @@ _git_config ()
                return
                ;;
        branch.*.rebase)
-               __gitcomp "false true"
+               __gitcomp "false true preserve interactive"
                return
                ;;
        remote.pushdefault)
@@ -1841,6 +1885,10 @@ _git_config ()
                __gitcomp "$__git_send_email_suppresscc_options"
                return
                ;;
+       sendemail.transferencoding)
+               __gitcomp "7bit 8bit quoted-printable base64"
+               return
+               ;;
        --get|--get-all|--unset|--unset-all)
                __gitcomp_nl "$(__git_config_get_set_variables)"
                return
@@ -1857,6 +1905,7 @@ _git_config ()
                        --get --get-all --get-regexp
                        --add --unset --unset-all
                        --remove-section --rename-section
+                       --name-only
                        "
                return
                ;;
@@ -1975,6 +2024,7 @@ _git_config ()
                color.status.changed
                color.status.header
                color.status.nobranch
+               color.status.unmerged
                color.status.untracked
                color.status.updated
                color.ui
@@ -2012,6 +2062,7 @@ _git_config ()
                core.sparseCheckout
                core.symlinks
                core.trustctime
+               core.untrackedCache
                core.warnAmbiguousRefs
                core.whitespace
                core.worktree
@@ -2086,6 +2137,8 @@ _git_config ()
                http.noEPSV
                http.postBuffer
                http.proxy
+               http.sslCipherList
+               http.sslVersion
                http.sslCAInfo
                http.sslCAPath
                http.sslCert
@@ -2149,6 +2202,7 @@ _git_config ()
                pull.octopus
                pull.twohead
                push.default
+               push.followTags
                rebase.autosquash
                rebase.stat
                receive.autogc
@@ -2222,12 +2276,7 @@ _git_remote ()
                __git_complete_remote_or_refspec
                ;;
        update)
-               local i c='' IFS=$'\n'
-               for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
-                       i="${i#remotes.}"
-                       c="$c ${i/ */}"
-               done
-               __gitcomp "$c"
+               __gitcomp "$(__git_get_config_variables "remotes")"
                ;;
        *)
                ;;
@@ -2254,6 +2303,11 @@ _git_reset ()
 
 _git_revert ()
 {
+       local dir="$(__gitdir)"
+       if [ -f "$dir"/REVERT_HEAD ]; then
+               __gitcomp "--continue --quit --abort"
+               return
+       fi
        case "$cur" in
        --*)
                __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
@@ -2308,6 +2362,7 @@ _git_show ()
                ;;
        --*)
                __gitcomp "--pretty= --format= --abbrev-commit --oneline
+                       --show-signature
                        $__git_diff_common_options
                        "
                return
@@ -2321,7 +2376,7 @@ _git_show_branch ()
        case "$cur" in
        --*)
                __gitcomp "
-                       --all --remotes --topo-order --current --more=
+                       --all --remotes --topo-order --date-order --current --more=
                        --list --independent --merge-base --no-name
                        --color --no-color
                        --sha1-name --sparse --topics --reflog
@@ -2334,7 +2389,7 @@ _git_show_branch ()
 
 _git_stash ()
 {
-       local save_opts='--keep-index --no-keep-index --quiet --patch'
+       local save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'
        local subcommands='save list show apply clear drop pop create branch'
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
        if [ -z "$subcommand" ]; then
@@ -2356,9 +2411,20 @@ _git_stash ()
                apply,--*|pop,--*)
                        __gitcomp "--index --quiet"
                        ;;
-               show,--*|drop,--*|branch,--*)
+               drop,--*)
+                       __gitcomp "--quiet"
+                       ;;
+               show,--*|branch,--*)
                        ;;
-               show,*|apply,*|drop,*|pop,*|branch,*)
+               branch,*)
+                       if [ $cword -eq 3 ]; then
+                               __gitcomp_nl "$(__git_refs)";
+                       else
+                               __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
+                                               | sed -n -e 's/:.*//p')"
+                       fi
+                       ;;
+               show,*|apply,*|drop,*|pop,*)
                        __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
                                        | sed -n -e 's/:.*//p')"
                        ;;
@@ -2513,6 +2579,16 @@ _git_tag ()
                __gitcomp_nl "$(__git_refs)"
                ;;
        esac
+
+       case "$cur" in
+       --*)
+               __gitcomp "
+                       --list --delete --verify --annotate --message --file
+                       --sign --cleanup --local-user --force --column --sort
+                       --contains --points-at
+                       "
+               ;;
+       esac
 }
 
 _git_whatchanged ()