Merge branch 'tg/stash-push'
[gitweb.git] / contrib / completion / git-completion.bash
index 01fc743a7f7e4ae0c9ed590d07d5bda58aead576..fc32286a43cdece9ea468c4a07c2a8e3d585f1b5 100644 (file)
@@ -34,26 +34,41 @@ case "$COMP_WORDBREAKS" in
 *)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
 esac
 
+# Discovers the path to the git repository taking any '--git-dir=<path>' and
+# '-C <path>' options into account and stores it in the $__git_repo_path
+# variable.
+__git_find_repo_path ()
+{
+       if [ -n "$__git_repo_path" ]; then
+               # we already know where it is
+               return
+       fi
+
+       if [ -n "${__git_C_args-}" ]; then
+               __git_repo_path="$(git "${__git_C_args[@]}" \
+                       ${__git_dir:+--git-dir="$__git_dir"} \
+                       rev-parse --absolute-git-dir 2>/dev/null)"
+       elif [ -n "${__git_dir-}" ]; then
+               test -d "$__git_dir" &&
+               __git_repo_path="$__git_dir"
+       elif [ -n "${GIT_DIR-}" ]; then
+               test -d "${GIT_DIR-}" &&
+               __git_repo_path="$GIT_DIR"
+       elif [ -d .git ]; then
+               __git_repo_path=.git
+       else
+               __git_repo_path="$(git rev-parse --git-dir 2>/dev/null)"
+       fi
+}
+
+# Deprecated: use __git_find_repo_path() and $__git_repo_path instead
 # __gitdir accepts 0 or 1 arguments (i.e., location)
 # returns location of .git repo
 __gitdir ()
 {
        if [ -z "${1-}" ]; then
-               if [ -n "${__git_C_args-}" ]; then
-                       git "${__git_C_args[@]}" \
-                               ${__git_dir:+--git-dir="$__git_dir"} \
-                               rev-parse --absolute-git-dir 2>/dev/null
-               elif [ -n "${__git_dir-}" ]; then
-                       test -d "$__git_dir" || return 1
-                       echo "$__git_dir"
-               elif [ -n "${GIT_DIR-}" ]; then
-                       test -d "${GIT_DIR-}" || return 1
-                       echo "$GIT_DIR"
-               elif [ -d .git ]; then
-                       echo .git
-               else
-                       git rev-parse --git-dir 2>/dev/null
-               fi
+               __git_find_repo_path || return 1
+               echo "$__git_repo_path"
        elif [ -d "$1/.git" ]; then
                echo "$1/.git"
        else
@@ -312,35 +327,25 @@ __git_ls_files_helper ()
 #    slash.
 __git_index_files ()
 {
-       local dir="$(__gitdir)" root="${2-.}" file
+       local root="${2-.}" file
 
-       if [ -d "$dir" ]; then
-               __git_ls_files_helper "$root" "$1" |
-               while read -r file; do
-                       case "$file" in
-                       ?*/*) echo "${file%%/*}" ;;
-                       *) echo "$file" ;;
-                       esac
-               done | sort | uniq
-       fi
+       __git_ls_files_helper "$root" "$1" |
+       while read -r file; do
+               case "$file" in
+               ?*/*) echo "${file%%/*}" ;;
+               *) echo "$file" ;;
+               esac
+       done | sort | uniq
 }
 
 __git_heads ()
 {
-       local dir="$(__gitdir)"
-       if [ -d "$dir" ]; then
-               __git for-each-ref --format='%(refname:short)' refs/heads
-               return
-       fi
+       __git for-each-ref --format='%(refname:short)' refs/heads
 }
 
 __git_tags ()
 {
-       local dir="$(__gitdir)"
-       if [ -d "$dir" ]; then
-               __git for-each-ref --format='%(refname:short)' refs/tags
-               return
-       fi
+       __git for-each-ref --format='%(refname:short)' refs/tags
 }
 
 # Lists refs from the local (by default) or from a remote repository.
@@ -351,10 +356,13 @@ __git_tags ()
 #    'git checkout's tracking DWIMery (optional; ignored, if set but empty).
 __git_refs ()
 {
-       local i hash dir="$(__gitdir)" track="${2-}"
+       local i hash dir track="${2-}"
        local list_refs_from=path remote="${1-}"
        local format refs pfx
 
+       __git_find_repo_path
+       dir="$__git_repo_path"
+
        if [ -z "$remote" ]; then
                if [ -z "$dir" ]; then
                        return
@@ -459,8 +467,8 @@ __git_refs_remotes ()
 
 __git_remotes ()
 {
-       local d="$(__gitdir)"
-       test -d "$d/remotes" && ls -1 "$d/remotes"
+       __git_find_repo_path
+       test -d "$__git_repo_path/remotes" && ls -1 "$__git_repo_path/remotes"
        __git remote
 }
 
@@ -958,8 +966,8 @@ __git_whitespacelist="nowarn warn error error-all fix"
 
 _git_am ()
 {
-       local dir="$(__gitdir)"
-       if [ -d "$dir"/rebase-apply ]; then
+       __git_find_repo_path
+       if [ -d "$__git_repo_path"/rebase-apply ]; then
                __gitcomp "--skip --continue --resolved --abort"
                return
        fi
@@ -993,6 +1001,7 @@ _git_apply ()
                        --apply --no-add --exclude=
                        --ignore-whitespace --ignore-space-change
                        --whitespace= --inaccurate-eof --verbose
+                       --recount --directory=
                        "
                return
        esac
@@ -1004,13 +1013,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 ()
@@ -1027,7 +1040,7 @@ _git_archive ()
        --*)
                __gitcomp "
                        --format= --list --verbose
-                       --prefix= --remote= --exec=
+                       --prefix= --remote= --exec= --output
                        "
                return
                ;;
@@ -1042,7 +1055,8 @@ _git_bisect ()
        local subcommands="start bad good skip reset visualize replay log run"
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
        if [ -z "$subcommand" ]; then
-               if [ -f "$(__gitdir)"/BISECT_START ]; then
+               __git_find_repo_path
+               if [ -f "$__git_repo_path"/BISECT_START ]; then
                        __gitcomp "$subcommands"
                else
                        __gitcomp "replay start"
@@ -1082,6 +1096,7 @@ _git_branch ()
                        --track --no-track --contains --merged --no-merged
                        --set-upstream-to= --edit-description --list
                        --unset-upstream --delete --move --remotes
+                       --column --no-column --sort= --points-at
                        "
                ;;
        *)
@@ -1147,8 +1162,8 @@ _git_cherry ()
 
 _git_cherry_pick ()
 {
-       local dir="$(__gitdir)"
-       if [ -f "$dir"/CHERRY_PICK_HEAD ]; then
+       __git_find_repo_path
+       if [ -f "$__git_repo_path"/CHERRY_PICK_HEAD ]; then
                __gitcomp "--continue --quit --abort"
                return
        fi
@@ -1195,6 +1210,8 @@ _git_clone ()
                        --single-branch
                        --branch
                        --recurse-submodules
+                       --no-single-branch
+                       --shallow-submodules
                        "
                return
                ;;
@@ -1236,6 +1253,7 @@ _git_commit ()
                        --reset-author --file= --message= --template=
                        --cleanup= --untracked-files --untracked-files=
                        --verbose --quiet --fixup= --squash=
+                       --patch --short --date --allow-empty
                        "
                return
        esac
@@ -1254,7 +1272,8 @@ _git_describe ()
        --*)
                __gitcomp "
                        --all --tags --contains --abbrev= --candidates=
-                       --exact-match --debug --long --match --always
+                       --exact-match --debug --long --match --always --first-parent
+                       --exclude
                        "
                return
        esac
@@ -1337,6 +1356,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 ()
@@ -1386,7 +1406,7 @@ _git_fsck ()
        --*)
                __gitcomp "
                        --tags --root --unreachable --cache --no-reflogs --full
-                       --strict --verbose --lost-found
+                       --strict --verbose --lost-found --name-objects
                        "
                return
                ;;
@@ -1430,6 +1450,8 @@ _git_grep ()
                        --max-depth
                        --count
                        --and --or --not --all-match
+                       --break --heading --show-function --function-context
+                       --untracked --no-index
                        "
                return
                ;;
@@ -1502,6 +1524,12 @@ _git_ls_files ()
 
 _git_ls_remote ()
 {
+       case "$cur" in
+       --*)
+               __gitcomp "--heads --tags --refs --get-url --symref"
+               return
+               ;;
+       esac
        __gitcomp_nl "$(__git_remotes)"
 }
 
@@ -1539,10 +1567,10 @@ __git_log_date_formats="relative iso8601 rfc2822 short local default raw"
 _git_log ()
 {
        __git_has_doubledash && return
+       __git_find_repo_path
 
-       local g="$(__gitdir)"
        local merge=""
-       if [ -f "$g/MERGE_HEAD" ]; then
+       if [ -f "$__git_repo_path/MERGE_HEAD" ]; then
                merge="--merge"
        fi
        case "$cur" in
@@ -1623,7 +1651,7 @@ _git_mergetool ()
                return
                ;;
        --*)
-               __gitcomp "--tool="
+               __gitcomp "--tool= --prompt --no-prompt"
                return
                ;;
        esac
@@ -1731,7 +1759,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 ()
 {
@@ -1789,11 +1817,12 @@ _git_push ()
 
 _git_rebase ()
 {
-       local dir="$(__gitdir)"
-       if [ -f "$dir"/rebase-merge/interactive ]; then
+       __git_find_repo_path
+       if [ -f "$__git_repo_path"/rebase-merge/interactive ]; then
                __gitcomp "--continue --skip --abort --quit --edit-todo"
                return
-       elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
+       elif [ -d "$__git_repo_path"/rebase-apply ] || \
+            [ -d "$__git_repo_path"/rebase-merge ]; then
                __gitcomp "--continue --skip --abort --quit"
                return
        fi
@@ -2000,7 +2029,7 @@ _git_config ()
        remote.*.push)
                local remote="${prev#remote.}"
                remote="${remote%.push}"
-               __gitcomp_nl "$(__git for-each-ref
+               __gitcomp_nl "$(__git for-each-ref \
                        --format='%(refname):%(refname)' refs/heads)"
                return
                ;;
@@ -2426,40 +2455,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
@@ -2468,14 +2545,17 @@ _git_reset ()
 
 _git_revert ()
 {
-       local dir="$(__gitdir)"
-       if [ -f "$dir"/REVERT_HEAD ]; then
+       __git_find_repo_path
+       if [ -f "$__git_repo_path"/REVERT_HEAD ]; then
                __gitcomp "--continue --quit --abort"
                return
        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
@@ -2503,7 +2583,7 @@ _git_shortlog ()
                __gitcomp "
                        $__git_log_common_options
                        $__git_log_shortlog_options
-                       --numbered --summary
+                       --numbered --summary --email
                        "
                return
                ;;
@@ -2608,10 +2688,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"
@@ -2619,6 +2700,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 ()
@@ -2639,14 +2747,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=
@@ -2753,8 +2861,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
@@ -2793,7 +2901,7 @@ _git_worktree ()
 
 __git_main ()
 {
-       local i c=1 command __git_dir
+       local i c=1 command __git_dir __git_repo_path
        local __git_C_args C_args_count=0
 
        while [ $c -lt $cword ]; do
@@ -2865,9 +2973,11 @@ __gitk_main ()
 {
        __git_has_doubledash && return
 
-       local g="$(__gitdir)"
+       local __git_repo_path
+       __git_find_repo_path
+
        local merge=""
-       if [ -f "$g/MERGE_HEAD" ]; then
+       if [ -f "$__git_repo_path/MERGE_HEAD" ]; then
                merge="--merge"
        fi
        case "$cur" in