completion: extract repository discovery from __gitdir()

To prepare for caching the path to the repository in the following commit, extract the repository discovering part of __gitdir() into the __git_find_repo_path() helper function, which stores the found path in the $__git_repo_path variable instead of printing it. Make __gitdir() a wrapper around this new function. Declare $__git_repo_path local in the toplevel completion functions __git_main() and __gitk_main() to ensure that it never leaks into the environment and influences subsequent completions (though this isn't necessary right now, as __gitdir() is still only executed in subshells, but will matter for the following commit). Adjust tests checking __gitdir() or any other completion function calling __gitdir() to perform those checks in a subshell to prevent $__git_repo_path from leaking into the test environment. Otherwise leave the tests unchanged to demonstrate that this change doesn't alter __gitdir()'s behavior. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

SZEDER Gábor committed Feb 3, 2017 at 03:48 UTC beb6ee71639ffe96f676ba4268cb85e4a933ab7e
2 files changed +42 -22
contrib/completion/git-completion.bash
+26 -16
@@ -34,26 +34,35 @@ case "$COMP_WORDBREAKS" in
34 *) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
35 esac
36
37 +# Discovers the path to the git repository taking any '--git-dir=<path>' and
38 +# '-C <path>' options into account and stores it in the $__git_repo_path
39 +# variable.
40 +__git_find_repo_path ()
41 +{
42 + if [ -n "${__git_C_args-}" ]; then
43 + __git_repo_path="$(git "${__git_C_args[@]}" \
44 + ${__git_dir:+--git-dir="$__git_dir"} \
45 + rev-parse --absolute-git-dir 2>/dev/null)"
46 + elif [ -n "${__git_dir-}" ]; then
47 + test -d "$__git_dir" &&
48 + __git_repo_path="$__git_dir"
49 + elif [ -n "${GIT_DIR-}" ]; then
50 + test -d "${GIT_DIR-}" &&
51 + __git_repo_path="$GIT_DIR"
52 + elif [ -d .git ]; then
53 + __git_repo_path=.git
54 + else
55 + __git_repo_path="$(git rev-parse --git-dir 2>/dev/null)"
56 + fi
57 +}
58 +
59 # __gitdir accepts 0 or 1 arguments (i.e., location)
60 # returns location of .git repo
61 __gitdir ()
62 {
63 if [ -z "${1-}" ]; then
42 - if [ -n "${__git_C_args-}" ]; then
43 - git "${__git_C_args[@]}" \
44 - ${__git_dir:+--git-dir="$__git_dir"} \
45 - rev-parse --absolute-git-dir 2>/dev/null
46 - elif [ -n "${__git_dir-}" ]; then
47 - test -d "$__git_dir" || return 1
48 - echo "$__git_dir"
49 - elif [ -n "${GIT_DIR-}" ]; then
50 - test -d "${GIT_DIR-}" || return 1
51 - echo "$GIT_DIR"
52 - elif [ -d .git ]; then
53 - echo .git
54 - else
55 - git rev-parse --git-dir 2>/dev/null
56 - fi
64 + __git_find_repo_path || return 1
65 + echo "$__git_repo_path"
66 elif [ -d "$1/.git" ]; then
67 echo "$1/.git"
68 else
@@ -2783,7 +2792,7 @@ _git_worktree ()
2792
2793 __git_main ()
2794 {
2786 - local i c=1 command __git_dir
2795 + local i c=1 command __git_dir __git_repo_path
2796 local __git_C_args C_args_count=0
2797
2798 while [ $c -lt $cword ]; do
@@ -2855,6 +2864,7 @@ __gitk_main ()
2864 {
2865 __git_has_doubledash && return
2866
2867 + local __git_repo_path
2868 local g="$(__gitdir)"
2869 local merge=""
2870 if [ -f "$g/MERGE_HEAD" ]; then
t/t9902-completion.sh
+16 -6
@@ -147,19 +147,25 @@ test_expect_success '__gitdir - from command line (through $__git_dir)' '
147
148 test_expect_success '__gitdir - repo as argument' '
149 echo "otherrepo/.git" >expected &&
150 - __gitdir "otherrepo" >"$actual" &&
150 + (
151 + __gitdir "otherrepo" >"$actual"
152 + ) &&
153 test_cmp expected "$actual"
154 '
155
156 test_expect_success '__gitdir - remote as argument' '
157 echo "remote" >expected &&
156 - __gitdir "remote" >"$actual" &&
158 + (
159 + __gitdir "remote" >"$actual"
160 + ) &&
161 test_cmp expected "$actual"
162 '
163
164 test_expect_success '__gitdir - .git directory in cwd' '
165 echo ".git" >expected &&
162 - __gitdir >"$actual" &&
166 + (
167 + __gitdir >"$actual"
168 + ) &&
169 test_cmp expected "$actual"
170 '
171
@@ -450,7 +456,9 @@ test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from
456 git remote add remote_in_config_1 git://remote_1 &&
457 test_when_finished "git remote remove remote_in_config_2" &&
458 git remote add remote_in_config_2 git://remote_2 &&
453 - __git_remotes >actual &&
459 + (
460 + __git_remotes >actual
461 + ) &&
462 test_cmp expect actual
463 '
464
@@ -459,8 +467,10 @@ test_expect_success '__git_is_configured_remote' '
467 git remote add remote_1 git://remote_1 &&
468 test_when_finished "git remote remove remote_2" &&
469 git remote add remote_2 git://remote_2 &&
462 - verbose __git_is_configured_remote remote_2 &&
463 - test_must_fail __git_is_configured_remote non-existent
470 + (
471 + verbose __git_is_configured_remote remote_2 &&
472 + test_must_fail __git_is_configured_remote non-existent
473 + )
474 '
475
476 test_expect_success 'setup for ref completion' '