diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 262760f8c0..f2d939d358 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -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,$, , @@ -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]}" @@ -2800,7 +2805,11 @@ __git_main () --git-dir) ((c++)) ; __git_dir="${words[c]}" ;; --bare) __git_dir="." ;; --help) command="help"; break ;; - -c|-C|--work-tree|--namespace) ((c++)) ;; + -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 diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index be2ed87043..984df05b23 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -211,6 +211,87 @@ test_expect_success '__gitdir - $GIT_DIR set while .git directory in parent' ' test_cmp expected "$actual" ' +test_expect_success '__gitdir - from command line while "git -C"' ' + echo "$ROOT/.git" >expected && + ( + __git_dir="$ROOT/.git" && + __git_C_args=(-C otherrepo) && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - relative dir from command line and "git -C"' ' + echo "$ROOT/otherrepo/.git" >expected && + ( + cd subdir && + __git_dir="otherrepo/.git" && + __git_C_args=(-C ..) && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - $GIT_DIR set while "git -C"' ' + echo "$ROOT/.git" >expected && + ( + GIT_DIR="$ROOT/.git" && + export GIT_DIR && + __git_C_args=(-C otherrepo) && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - relative dir in $GIT_DIR and "git -C"' ' + echo "$ROOT/otherrepo/.git" >expected && + ( + cd subdir && + GIT_DIR="otherrepo/.git" && + export GIT_DIR && + __git_C_args=(-C ..) && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - "git -C" while .git directory in cwd' ' + echo "$ROOT/otherrepo/.git" >expected && + ( + __git_C_args=(-C otherrepo) && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - "git -C" while cwd is a .git directory' ' + echo "$ROOT/otherrepo/.git" >expected && + ( + cd .git && + __git_C_args=(-C .. -C otherrepo) && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - "git -C" while .git directory in parent' ' + echo "$ROOT/otherrepo/.git" >expected && + ( + cd subdir && + __git_C_args=(-C .. -C otherrepo) && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - non-existing path in "git -C"' ' + ( + __git_C_args=(-C non-existing) && + test_must_fail __gitdir >"$actual" + ) && + test_must_be_empty "$actual" +' + test_expect_success '__gitdir - non-existing path in $__git_dir' ' ( __git_dir="non-existing" && @@ -785,6 +866,12 @@ test_expect_success 'checkout completes ref names' ' EOF ' +test_expect_success 'git -C checkout uses the right repo' ' + test_completion "git -C subdir -C subsubdir -C .. -C ../otherrepo checkout b" <<-\EOF + branch-in-other Z + EOF +' + test_expect_success 'show completes all refs' ' test_completion "git show m" <<-\EOF master Z