diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2006-11-28 12:12:26 -0500 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-11-28 15:48:55 -0800 |
commit | 67ffa1142585742601011440a17528ef841bbf44 (patch) | |
tree | d4f261c4fc802e74feb237f814dae77932895cfa /contrib | |
parent | 4548e855e4600a0f76329cf4f0dd9e8d17d66b08 (diff) | |
download | git-67ffa1142585742601011440a17528ef841bbf44.tar.gz git-67ffa1142585742601011440a17528ef841bbf44.tar.xz |
Fix broken bash completion of local refs.
Commit 35e65ecc broke completion of local refs, e.g. "git pull . fo<tab>"
no longer would complete to "foo". Instead it printed out an internal
git error ("fatal: Not a git repository: '.'").
The break occurred when I tried to improve performance by switching from
git-peek-remote to git-for-each-ref. Apparently git-peek-remote will
drop into directory "$1/.git" (where $1 is its first parameter) if it
is given a repository with a working directory. This allowed the bash
completion code to work properly even though it was not handing over
the true repository directory.
So now we do a stat in bash to see if we need to add "/.git" to the
path string before running any command with --git-dir.
I also tried to optimize away two "git rev-parse --git-dir" invocations
in common cases like "git log fo<tab>" as typically the user is in the
top level directory of their project and therefore the .git subdirectory
is in the current working directory. This should make a difference on
systems where fork+exec might take a little while.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'contrib')
-rwxr-xr-x | contrib/completion/git-completion.bash | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index be978cf3d..447ec2046 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -34,7 +34,19 @@ __gitdir () { - echo "${__git_dir:-$(git rev-parse --git-dir 2>/dev/null)}" + if [ -z "$1" ]; then + if [ -n "$__git_dir" ]; then + echo "$__git_dir" + elif [ -d .git ]; then + echo .git + else + git rev-parse --git-dir 2>/dev/null + fi + elif [ -d "$1/.git" ]; then + echo "$1/.git" + else + echo "$1" + fi } __git_ps1 () @@ -51,7 +63,7 @@ __git_ps1 () __git_heads () { - local cmd i is_hash=y dir="${1:-$(__gitdir)}" + local cmd i is_hash=y dir="$(__gitdir "$1")" if [ -d "$dir" ]; then for i in $(git --git-dir="$dir" \ for-each-ref --format='%(refname)' \ @@ -60,7 +72,7 @@ __git_heads () done return fi - for i in $(git-ls-remote "$dir" 2>/dev/null); do + for i in $(git-ls-remote "$1" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; @@ -72,7 +84,7 @@ __git_heads () __git_refs () { - local cmd i is_hash=y dir="${1:-$(__gitdir)}" + local cmd i is_hash=y dir="$(__gitdir "$1")" if [ -d "$dir" ]; then if [ -e "$dir/HEAD" ]; then echo HEAD; fi for i in $(git --git-dir="$dir" \ @@ -101,20 +113,9 @@ __git_refs () __git_refs2 () { - local cmd i is_hash=y dir="${1:-$(__gitdir)}" - if [ -d "$dir" ]; then - cmd=git-peek-remote - else - cmd=git-ls-remote - fi - for i in $($cmd "$dir" 2>/dev/null); do - case "$is_hash,$i" in - y,*) is_hash=n ;; - n,*^{}) is_hash=y ;; - n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}:${i#refs/tags/}" ;; - n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}:${i#refs/heads/}" ;; - n,*) is_hash=y; echo "$i:$i" ;; - esac + local i + for i in $(__git_refs "$1"); do + echo "$i:$i" done } |