completion: respect 'git -C <path>'
[gitweb.git] / contrib / completion / git-completion.bash
index f59755d0600336de48907a7dcf1064b601dc53c6..f2d939d358dff9820912e774b9f5c2eb17bd684b 100644 (file)
@@ -39,7 +39,11 @@ esac
 __gitdir ()
 {
        if [ -z "${1-}" ]; then
-               if [ -n "${__git_dir-}" ]; 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
@@ -286,10 +290,10 @@ __git_ls_files_helper ()
        local dir="$(__gitdir)"
 
        if [ "$2" == "--committable" ]; then
-               git --git-dir="$dir" -C "$1" diff-index --name-only --relative HEAD
+               git ${__git_C_args:+"${__git_C_args[@]}"} --git-dir="$dir" -C "$1" diff-index --name-only --relative HEAD
        else
                # NOTE: $2 is not quoted in order to support multiple options
-               git --git-dir="$dir" -C "$1" ls-files --exclude-standard $2
+               git ${__git_C_args:+"${__git_C_args[@]}"} --git-dir="$dir" -C "$1" ls-files --exclude-standard $2
        fi 2>/dev/null
 }
 
@@ -519,7 +523,7 @@ __git_complete_revlist_file ()
                *)   pfx="$ref:$pfx" ;;
                esac
 
-               __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \
+               __gitcomp_nl "$(git ${__git_C_args:+"${__git_C_args[@]}"} --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \
                                | sed '/^100... blob /{
                                           s,^.*        ,,
                                           s,$, ,
@@ -816,7 +820,7 @@ __git_aliases ()
 __git_aliased_command ()
 {
        local word cmdline=$(git --git-dir="$(__gitdir)" \
-               config --get "alias.$1")
+               config --get "alias.$1" 2>/dev/null)
        for word in $cmdline; do
                case "$word" in
                \!gitk|gitk)
@@ -2792,6 +2796,7 @@ _git_worktree ()
 __git_main ()
 {
        local i c=1 command __git_dir
+       local __git_C_args C_args_count=0
 
        while [ $c -lt $cword ]; do
                i="${words[c]}"
@@ -2801,6 +2806,10 @@ __git_main ()
                --bare)      __git_dir="." ;;
                --help) command="help"; break ;;
                -c|--work-tree|--namespace) ((c++)) ;;
+               -C)     __git_C_args[C_args_count++]=-C
+                       ((c++))
+                       __git_C_args[C_args_count++]="${words[c]}"
+                       ;;
                -*) ;;
                *) command="$i"; break ;;
                esac
@@ -2808,6 +2817,17 @@ __git_main ()
        done
 
        if [ -z "$command" ]; then
+               case "$prev" in
+               --git-dir|-C|--work-tree)
+                       # these need a path argument, let's fall back to
+                       # Bash filename completion
+                       return
+                       ;;
+               -c|--namespace)
+                       # we don't support completing these options' arguments
+                       return
+                       ;;
+               esac
                case "$cur" in
                --*)   __gitcomp "
                        --paginate
@@ -2833,13 +2853,13 @@ __git_main ()
        fi
 
        local completion_func="_git_${command//-/_}"
-       declare -f $completion_func >/dev/null && $completion_func && return
+       declare -f $completion_func >/dev/null 2>/dev/null && $completion_func && return
 
        local expansion=$(__git_aliased_command "$command")
        if [ -n "$expansion" ]; then
                words[1]=$expansion
                completion_func="_git_${expansion//-/_}"
-               declare -f $completion_func >/dev/null && $completion_func
+               declare -f $completion_func >/dev/null 2>/dev/null && $completion_func
        fi
 }