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>
This commit is contained in:
parent
4548e855e4
commit
67ffa11425
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user