diff options
author | SZEDER Gábor <szeder.dev@gmail.com> | 2017-02-03 03:48:24 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-02-03 22:18:41 -0800 |
commit | 80ac0744b180f815aca190059705c0aed80d16f9 (patch) | |
tree | d95456f028323a58f282c566abae09ce05c23d37 /contrib/completion | |
parent | rev-parse: add '--absolute-git-dir' option (diff) | |
download | tgif-80ac0744b180f815aca190059705c0aed80d16f9.tar.xz |
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/completion')
-rw-r--r-- | contrib/completion/git-completion.bash | 19 |
1 files changed, 14 insertions, 5 deletions
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 |