git_extract_argv0_path: do nothing without RUNTIME_PREFIX
[gitweb.git] / contrib / completion / git-completion.bash
index 00d729996fab5be89696bf4841205d45c49c7794..41ee52991d0c1b1fa2a6021133cffecd3ca9deb0 100644 (file)
@@ -338,7 +338,7 @@ __git_tags ()
 __git_refs ()
 {
        local i hash dir="$(__gitdir "${1-}")" track="${2-}"
-       local format refs
+       local format refs pfx
        if [ -d "$dir" ]; then
                case "$cur" in
                refs|refs/*)
@@ -347,14 +347,15 @@ __git_refs ()
                        track=""
                        ;;
                *)
+                       [[ "$cur" == ^* ]] && pfx="^"
                        for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
-                               if [ -e "$dir/$i" ]; then echo $i; fi
+                               if [ -e "$dir/$i" ]; then echo $pfx$i; fi
                        done
                        format="refname:short"
                        refs="refs/tags refs/heads refs/remotes"
                        ;;
                esac
-               git --git-dir="$dir" for-each-ref --format="%($format)" \
+               git --git-dir="$dir" for-each-ref --format="$pfx%($format)" \
                        $refs
                if [ -n "$track" ]; then
                        # employ the heuristic used by git checkout
@@ -803,6 +804,50 @@ __git_find_on_cmdline ()
        done
 }
 
+# Echo the value of an option set on the command line or config
+#
+# $1: short option name
+# $2: long option name including =
+# $3: list of possible values
+# $4: config string (optional)
+#
+# example:
+# result="$(__git_get_option_value "-d" "--do-something=" \
+#     "yes no" "core.doSomething")"
+#
+# result is then either empty (no option set) or "yes" or "no"
+#
+# __git_get_option_value requires 3 arguments
+__git_get_option_value ()
+{
+       local c short_opt long_opt val
+       local result= values config_key word
+
+       short_opt="$1"
+       long_opt="$2"
+       values="$3"
+       config_key="$4"
+
+       ((c = $cword - 1))
+       while [ $c -ge 0 ]; do
+               word="${words[c]}"
+               for val in $values; do
+                       if [ "$short_opt$val" = "$word" ] ||
+                          [ "$long_opt$val"  = "$word" ]; then
+                               result="$val"
+                               break 2
+                       fi
+               done
+               ((c--))
+       done
+
+       if [ -n "$config_key" ] && [ -z "$result" ]; then
+               result="$(git --git-dir="$(__gitdir)" config "$config_key")"
+       fi
+
+       echo "$result"
+}
+
 __git_has_doubledash ()
 {
        local c=1
@@ -891,6 +936,7 @@ _git_apply ()
                        --apply --no-add --exclude=
                        --ignore-whitespace --ignore-space-change
                        --whitespace= --inaccurate-eof --verbose
+                       --recount --directory=
                        "
                return
        esac
@@ -902,13 +948,17 @@ _git_add ()
        --*)
                __gitcomp "
                        --interactive --refresh --patch --update --dry-run
-                       --ignore-errors --intent-to-add
+                       --ignore-errors --intent-to-add --force --edit --chmod=
                        "
                return
        esac
 
-       # XXX should we check for --update and --all options ?
-       __git_complete_index_file "--others --modified --directory --no-empty-directory"
+       local complete_opt="--others --modified --directory --no-empty-directory"
+       if test -n "$(__git_find_on_cmdline "-u --update")"
+       then
+               complete_opt="--modified"
+       fi
+       __git_complete_index_file "$complete_opt"
 }
 
 _git_archive ()
@@ -925,7 +975,7 @@ _git_archive ()
        --*)
                __gitcomp "
                        --format= --list --verbose
-                       --prefix= --remote= --exec=
+                       --prefix= --remote= --exec= --output
                        "
                return
                ;;
@@ -964,8 +1014,8 @@ _git_branch ()
        while [ $c -lt $cword ]; do
                i="${words[c]}"
                case "$i" in
-               -d|-m)  only_local_ref="y" ;;
-               -r)     has_r="y" ;;
+               -d|--delete|-m|--move)  only_local_ref="y" ;;
+               -r|--remotes)           has_r="y" ;;
                esac
                ((c++))
        done
@@ -979,7 +1029,8 @@ _git_branch ()
                        --color --no-color --verbose --abbrev= --no-abbrev
                        --track --no-track --contains --merged --no-merged
                        --set-upstream-to= --edit-description --list
-                       --unset-upstream
+                       --unset-upstream --delete --move --remotes
+                       --column --no-column --sort= --points-at
                        "
                ;;
        *)
@@ -1092,12 +1143,17 @@ _git_clone ()
                        --depth
                        --single-branch
                        --branch
+                       --recurse-submodules
+                       --no-single-branch
+                       --shallow-submodules
                        "
                return
                ;;
        esac
 }
 
+__git_untracked_file_modes="all no normal"
+
 _git_commit ()
 {
        case "$prev" in
@@ -1119,7 +1175,7 @@ _git_commit ()
                return
                ;;
        --untracked-files=*)
-               __gitcomp "all no normal" "" "${cur##--untracked-files=}"
+               __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
                return
                ;;
        --*)
@@ -1131,6 +1187,7 @@ _git_commit ()
                        --reset-author --file= --message= --template=
                        --cleanup= --untracked-files --untracked-files=
                        --verbose --quiet --fixup= --squash=
+                       --patch --short --date --allow-empty
                        "
                return
        esac
@@ -1149,7 +1206,7 @@ _git_describe ()
        --*)
                __gitcomp "
                        --all --tags --contains --abbrev= --candidates=
-                       --exact-match --debug --long --match --always
+                       --exact-match --debug --long --match --always --first-parent
                        "
                return
        esac
@@ -1158,6 +1215,8 @@ _git_describe ()
 
 __git_diff_algorithms="myers minimal patience histogram"
 
+__git_diff_submodule_formats="diff log short"
+
 __git_diff_common_options="--stat --numstat --shortstat --summary
                        --patch-with-stat --name-only --name-status --color
                        --no-color --color-words --no-renames --check
@@ -1173,6 +1232,7 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
                        --dirstat --dirstat= --dirstat-by-file
                        --dirstat-by-file= --cumulative
                        --diff-algorithm=
+                       --submodule --submodule=
 "
 
 _git_diff ()
@@ -1184,6 +1244,10 @@ _git_diff ()
                __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
                return
                ;;
+       --submodule=*)
+               __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+               return
+               ;;
        --*)
                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
                        --base --ours --theirs --no-index
@@ -1225,6 +1289,7 @@ __git_fetch_recurse_submodules="yes on-demand no"
 __git_fetch_options="
        --quiet --verbose --append --upload-pack --force --keep --depth=
        --tags --no-tags --all --prune --dry-run --recurse-submodules=
+       --unshallow --update-shallow
 "
 
 _git_fetch ()
@@ -1274,7 +1339,7 @@ _git_fsck ()
        --*)
                __gitcomp "
                        --tags --root --unreachable --cache --no-reflogs --full
-                       --strict --verbose --lost-found
+                       --strict --verbose --lost-found --name-objects
                        "
                return
                ;;
@@ -1312,11 +1377,14 @@ _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
                        --count
                        --and --or --not --all-match
+                       --break --heading --show-function --function-context
+                       --untracked --no-index
                        "
                return
                ;;
@@ -1338,15 +1406,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
                "
 }
@@ -1389,6 +1457,12 @@ _git_ls_files ()
 
 _git_ls_remote ()
 {
+       case "$cur" in
+       --*)
+               __gitcomp "--heads --tags --refs --get-url --symref"
+               return
+               ;;
+       esac
        __gitcomp_nl "$(__git_remotes)"
 }
 
@@ -1446,6 +1520,14 @@ _git_log ()
                __gitcomp "full short no" "" "${cur##--decorate=}"
                return
                ;;
+       --diff-algorithm=*)
+               __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
+               return
+               ;;
+       --submodule=*)
+               __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+               return
+               ;;
        --*)
                __gitcomp "
                        $__git_log_common_options
@@ -1457,6 +1539,7 @@ _git_log ()
                        --relative-date --date=
                        --pretty= --format= --oneline
                        --show-signature
+                       --cherry-mark
                        --cherry-pick
                        --graph
                        --decorate --decorate=
@@ -1487,7 +1570,7 @@ _git_merge ()
        case "$cur" in
        --*)
                __gitcomp "$__git_merge_options
-                       --rerere-autoupdate --no-rerere-autoupdate --abort"
+                       --rerere-autoupdate --no-rerere-autoupdate --abort --continue"
                return
        esac
        __gitcomp_nl "$(__git_refs)"
@@ -1501,7 +1584,7 @@ _git_mergetool ()
                return
                ;;
        --*)
-               __gitcomp "--tool="
+               __gitcomp "--tool= --prompt --no-prompt"
                return
                ;;
        esac
@@ -1609,7 +1692,7 @@ _git_pull ()
        __git_complete_remote_or_refspec
 }
 
-__git_push_recurse_submodules="check on-demand"
+__git_push_recurse_submodules="check on-demand only"
 
 __git_complete_force_with_lease ()
 {
@@ -1669,10 +1752,10 @@ _git_rebase ()
 {
        local dir="$(__gitdir)"
        if [ -f "$dir"/rebase-merge/interactive ]; then
-               __gitcomp "--continue --skip --abort --edit-todo"
+               __gitcomp "--continue --skip --abort --quit --edit-todo"
                return
        elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
-               __gitcomp "--continue --skip --abort"
+               __gitcomp "--continue --skip --abort --quit"
                return
        fi
        __git_complete_strategy && return
@@ -1778,6 +1861,56 @@ _git_stage ()
        _git_add
 }
 
+_git_status ()
+{
+       local complete_opt
+       local untracked_state
+
+       case "$cur" in
+       --ignore-submodules=*)
+               __gitcomp "none untracked dirty all" "" "${cur##--ignore-submodules=}"
+               return
+               ;;
+       --untracked-files=*)
+               __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
+               return
+               ;;
+       --column=*)
+               __gitcomp "
+                       always never auto column row plain dense nodense
+                       " "" "${cur##--column=}"
+               return
+               ;;
+       --*)
+               __gitcomp "
+                       --short --branch --porcelain --long --verbose
+                       --untracked-files= --ignore-submodules= --ignored
+                       --column= --no-column
+                       "
+               return
+               ;;
+       esac
+
+       untracked_state="$(__git_get_option_value "-u" "--untracked-files=" \
+               "$__git_untracked_file_modes" "status.showUntrackedFiles")"
+
+       case "$untracked_state" in
+       no)
+               # --ignored option does not matter
+               complete_opt=
+               ;;
+       all|normal|*)
+               complete_opt="--cached --directory --no-empty-directory --others"
+
+               if [ -n "$(__git_find_on_cmdline "--ignored")" ]; then
+                       complete_opt="$complete_opt --ignored --exclude=*"
+               fi
+               ;;
+       esac
+
+       __git_complete_index_file "$complete_opt"
+}
+
 __git_config_get_set_variables ()
 {
        local prevword word config_file= c=$cword
@@ -1812,7 +1945,7 @@ _git_config ()
                return
                ;;
        branch.*.rebase)
-               __gitcomp "false true"
+               __gitcomp "false true preserve interactive"
                return
                ;;
        remote.pushdefault)
@@ -2059,6 +2192,7 @@ _git_config ()
                core.sparseCheckout
                core.symlinks
                core.trustctime
+               core.untrackedCache
                core.warnAmbiguousRefs
                core.whitespace
                core.worktree
@@ -2082,6 +2216,7 @@ _git_config ()
                format.attach
                format.cc
                format.coverLetter
+               format.from
                format.headers
                format.numbered
                format.pretty
@@ -2257,40 +2392,88 @@ _git_config ()
 
 _git_remote ()
 {
-       local subcommands="add rename remove set-head set-branches set-url show prune update"
+       local subcommands="
+               add rename remove set-head set-branches
+               get-url set-url show prune update
+               "
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
        if [ -z "$subcommand" ]; then
-               __gitcomp "$subcommands"
+               case "$cur" in
+               --*)
+                       __gitcomp "--verbose"
+                       ;;
+               *)
+                       __gitcomp "$subcommands"
+                       ;;
+               esac
                return
        fi
 
-       case "$subcommand" in
-       rename|remove|set-url|show|prune)
-               __gitcomp_nl "$(__git_remotes)"
+       case "$subcommand,$cur" in
+       add,--*)
+               __gitcomp "--track --master --fetch --tags --no-tags --mirror="
+               ;;
+       add,*)
+               ;;
+       set-head,--*)
+               __gitcomp "--auto --delete"
                ;;
-       set-head|set-branches)
+       set-branches,--*)
+               __gitcomp "--add"
+               ;;
+       set-head,*|set-branches,*)
                __git_complete_remote_or_refspec
                ;;
-       update)
+       update,--*)
+               __gitcomp "--prune"
+               ;;
+       update,*)
                __gitcomp "$(__git_get_config_variables "remotes")"
                ;;
+       set-url,--*)
+               __gitcomp "--push --add --delete"
+               ;;
+       get-url,--*)
+               __gitcomp "--push --all"
+               ;;
+       prune,--*)
+               __gitcomp "--dry-run"
+               ;;
        *)
+               __gitcomp_nl "$(__git_remotes)"
                ;;
        esac
 }
 
 _git_replace ()
 {
+       case "$cur" in
+       --*)
+               __gitcomp "--edit --graft --format= --list --delete"
+               return
+               ;;
+       esac
        __gitcomp_nl "$(__git_refs)"
 }
 
+_git_rerere ()
+{
+       local subcommands="clear forget diff remaining status gc"
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if test -z "$subcommand"
+       then
+               __gitcomp "$subcommands"
+               return
+       fi
+}
+
 _git_reset ()
 {
        __git_has_doubledash && return
 
        case "$cur" in
        --*)
-               __gitcomp "--merge --mixed --hard --soft --patch"
+               __gitcomp "--merge --mixed --hard --soft --patch --keep"
                return
                ;;
        esac
@@ -2306,7 +2489,10 @@ _git_revert ()
        fi
        case "$cur" in
        --*)
-               __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
+               __gitcomp "
+                       --edit --mainline --no-edit --no-commit --signoff
+                       --strategy= --strategy-option=
+                       "
                return
                ;;
        esac
@@ -2334,7 +2520,7 @@ _git_shortlog ()
                __gitcomp "
                        $__git_log_common_options
                        $__git_log_shortlog_options
-                       --numbered --summary
+                       --numbered --summary --email
                        "
                return
                ;;
@@ -2356,6 +2542,10 @@ _git_show ()
                __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
                return
                ;;
+       --submodule=*)
+               __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+               return
+               ;;
        --*)
                __gitcomp "--pretty= --format= --abbrev-commit --oneline
                        --show-signature
@@ -2435,10 +2625,11 @@ _git_submodule ()
        __git_has_doubledash && return
 
        local subcommands="add status init deinit update summary foreach sync"
-       if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if [ -z "$subcommand" ]; then
                case "$cur" in
                --*)
-                       __gitcomp "--quiet --cached"
+                       __gitcomp "--quiet"
                        ;;
                *)
                        __gitcomp "$subcommands"
@@ -2446,6 +2637,33 @@ _git_submodule ()
                esac
                return
        fi
+
+       case "$subcommand,$cur" in
+       add,--*)
+               __gitcomp "--branch --force --name --reference --depth"
+               ;;
+       status,--*)
+               __gitcomp "--cached --recursive"
+               ;;
+       deinit,--*)
+               __gitcomp "--force --all"
+               ;;
+       update,--*)
+               __gitcomp "
+                       --init --remote --no-fetch
+                       --recommend-shallow --no-recommend-shallow
+                       --force --rebase --merge --reference --depth --recursive --jobs
+               "
+               ;;
+       summary,--*)
+               __gitcomp "--cached --files --summary-limit"
+               ;;
+       foreach,--*|sync,--*)
+               __gitcomp "--recursive"
+               ;;
+       *)
+               ;;
+       esac
 }
 
 _git_svn ()
@@ -2466,14 +2684,14 @@ _git_svn ()
                        --no-metadata --use-svm-props --use-svnsync-props
                        --log-window-size= --no-checkout --quiet
                        --repack-flags --use-log-author --localtime
+                       --add-author-from
                        --ignore-paths= --include-paths= $remote_opts
                        "
                local init_opts="
                        --template= --shared= --trunk= --tags=
                        --branches= --stdlayout --minimize-url
                        --no-metadata --use-svm-props --use-svnsync-props
-                       --rewrite-root= --prefix= --use-log-author
-                       --add-author-from $remote_opts
+                       --rewrite-root= --prefix= $remote_opts
                        "
                local cmt_opts="
                        --edit --rmdir --find-copies-harder --copy-similarity=
@@ -2580,8 +2798,8 @@ _git_tag ()
        --*)
                __gitcomp "
                        --list --delete --verify --annotate --message --file
-                       --sign --cleanup --local-user --force --column --sort
-                       --contains --points-at
+                       --sign --cleanup --local-user --force --column --sort=
+                       --contains --points-at --merged --no-merged --create-reflog
                        "
                ;;
        esac
@@ -2592,6 +2810,32 @@ _git_whatchanged ()
        _git_log
 }
 
+_git_worktree ()
+{
+       local subcommands="add list lock prune unlock"
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if [ -z "$subcommand" ]; then
+               __gitcomp "$subcommands"
+       else
+               case "$subcommand,$cur" in
+               add,--*)
+                       __gitcomp "--detach"
+                       ;;
+               list,--*)
+                       __gitcomp "--porcelain"
+                       ;;
+               lock,--*)
+                       __gitcomp "--reason"
+                       ;;
+               prune,--*)
+                       __gitcomp "--dry-run --expire --verbose"
+                       ;;
+               *)
+                       ;;
+               esac
+       fi
+}
+
 __git_main ()
 {
        local i c=1 command __git_dir