summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorSZEDER Gábor <szeder.dev@gmail.com>2017-02-03 02:48:24 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-02-04 06:18:41 (GMT)
commit80ac0744b180f815aca190059705c0aed80d16f9 (patch)
treed95456f028323a58f282c566abae09ce05c23d37 /contrib
parenta2f5a8762693d5af6dbbca714d882a21d7ba0b75 (diff)
downloadgit-80ac0744b180f815aca190059705c0aed80d16f9.zip
git-80ac0744b180f815aca190059705c0aed80d16f9.tar.gz
git-80ac0744b180f815aca190059705c0aed80d16f9.tar.bz2
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into account during completion, because - like '--git-dir=<path>', it can lead us to a different repository, - a few git commands executed in the completion script do care about in which directory they are executed, and - the command for which we are providing completion might care about in which directory it will be executed. However, unlike '--git-dir=<path>', the '-C <path>' option can be specified multiple times and their effect is cumulative, so we can't just store a single '<path>' in a variable. Nor can we simply concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in an arguably pathological corner case) a relative path might be followed by an absolute path. Instead, store all '-C <path>' options word by word in the $__git_C_args array in the main git completion function, and pass this array, if present, to 'git rev-parse --absolute-git-dir' when discovering the repository in __gitdir(), and let it take care of multiple options, relative paths, absolute paths and everything. Also pass all '-C <path> options via the $__git_C_args array to those git executions which require a worktree and for which it matters from which directory they are executed from. There are only three such cases: - 'git diff-index' and 'git ls-files' in __git_ls_files_helper() used for git-aware filename completion, and - the 'git ls-tree' used for completing the 'ref:path' notation. The other git commands executed in the completion script don't need these '-C <path>' options, because __gitdir() already took those options into account. It would not hurt them, either, but let's not induce unnecessary code churn. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'contrib')
-rw-r--r--contrib/completion/git-completion.bash19
1 files changed, 14 insertions, 5 deletions
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 262760f..f2d939d 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