completion: respect $GIT_DIR

The __gitdir() helper function finds out the path of the git repository by running 'git rev-parse --git-dir'. However, it has a shortcut first to avoid the overhead of running a git command in a subshell when the current directory is at the top of the work tree, i.e. when it contains a '.git' subdirectory. If the 'GIT_DIR' environment variable is set then it specifies the path to the git repository, and the autodetection of the '.git' directory is not necessary. However, $GIT_DIR is only taken into acocunt by 'git rev-parse --git-dir', and the check for the '.git' subdirectory is performed first, so it wins over the path given in $GIT_DIR. There are several completion (helper) functions that depend on __gitdir(), and when the above case triggers the completion script will do weird things, like offering refs, aliases, or stashes from a different repository, or displaying wrong or broken prompt, etc. So check first whether $GIT_DIR is set, and only proceed with checking the '.git' directory in the current directory if it isn't. 'git rev-parse' would also check whether the path in $GIT_DIR is a proper '.git' directory, i.e. 'HEAD', 'refs/', and 'objects/' are present and accessible, but we don't have to be that thorough for the bash prompt. And we've lived with an equally permissive check for '.git' in the current working directory for years anyway. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

SZEDER Gábor committed May 9, 2012 at 02:44 UTC b7be4366ea9af9a6947a8be0ebe6a63ff5259b6a
2 files changed +12 -1
contrib/completion/git-completion.bash
+3
@@ -41,6 +41,9 @@ __gitdir ()
41 if [ -z "${1-}" ]; then
42 if [ -n "${__git_dir-}" ]; then
43 echo "$__git_dir"
44 + elif [ -n "${GIT_DIR-}" ]; then
45 + test -d "${GIT_DIR-}" || return 1
46 + echo "$GIT_DIR"
47 elif [ -d .git ]; then
48 echo .git
49 else
t/t9903-bash-prompt.sh
+9 -1
@@ -85,7 +85,7 @@ test_expect_success 'gitdir - parent is a .git directory' '
85 test_cmp expected "$actual"
86 '
87
88 -test_expect_failure 'gitdir - $GIT_DIR set while .git directory in cwd' '
88 +test_expect_success 'gitdir - $GIT_DIR set while .git directory in cwd' '
89 echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
90 (
91 GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" &&
@@ -106,6 +106,14 @@ test_expect_success 'gitdir - $GIT_DIR set while .git directory in parent' '
106 test_cmp expected "$actual"
107 '
108
109 +test_expect_success 'gitdir - non-existing $GIT_DIR' '
110 + (
111 + GIT_DIR="$TRASH_DIRECTORY/non-existing" &&
112 + export GIT_DIR &&
113 + test_must_fail __gitdir
114 + )
115 +'
116 +
117 test_expect_success 'gitdir - gitfile in cwd' '
118 echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
119 echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&