Skip to content

Commit

Permalink
bash prompt: use bash builtins to find out current branch
Browse files Browse the repository at this point in the history
__git_ps1() runs the '$(git symbolic-ref HEAD)' command substitution
to find out whether we are on a branch and to find out the name of
that branch.  This imposes the overhead of fork()ing a subshell and
fork()+exec()ing a git process.

Since HEAD is in most cases a single-line file and the symbolic ref
format is quite simple to recognize and parse, read and parse it using
only bash builtins, thereby sparing all that fork()+exec() overhead.
Don't display the git prompt if reading HEAD fails, because a readable
HEAD is required for a git repository.  HEAD can also be a symlink
symbolic ref (due to 'core.preferSymlinkRefs'), so use bash builtins
for reading HEAD only when HEAD is not a symlink.

Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
  • Loading branch information
SZEDER Gábor committed Jun 24, 2013
1 parent b91b935 commit 3a43c4b
Showing 1 changed file with 33 additions and 18 deletions.
51 changes: 33 additions & 18 deletions contrib/completion/git-prompt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -355,25 +355,40 @@ __git_ps1 ()
r="|BISECTING"
fi

test -n "$b" ||
b="$(git symbolic-ref HEAD 2>/dev/null)" || {
detached=yes
b="$(
case "${GIT_PS1_DESCRIBE_STYLE-}" in
(contains)
git describe --contains HEAD ;;
(branch)
git describe --contains --all HEAD ;;
(describe)
git describe HEAD ;;
(* | default)
git describe --tags --exact-match HEAD ;;
esac 2>/dev/null)" ||
if [ -n "$b" ]; then
:
elif [ -h "$g/HEAD" ]; then
# symlink symbolic ref
b="$(git symbolic-ref HEAD 2>/dev/null)"
else
local head=""
if ! read head 2>/dev/null <"$g/HEAD"; then
if [ $pcmode = yes ]; then
PS1="$ps1pc_start$ps1pc_end"
fi
return
fi
# is it a symbolic ref?
b="${head#ref: }"
if [ "$head" = "$b" ]; then
detached=yes
b="$(
case "${GIT_PS1_DESCRIBE_STYLE-}" in
(contains)
git describe --contains HEAD ;;
(branch)
git describe --contains --all HEAD ;;
(describe)
git describe HEAD ;;
(* | default)
git describe --tags --exact-match HEAD ;;
esac 2>/dev/null)" ||

b="$(git rev-parse --short HEAD 2>/dev/null)..." ||
b="unknown"
b="($b)"
}
b="$(git rev-parse --short HEAD 2>/dev/null)..." ||
b="unknown"
b="($b)"
fi
fi
fi

if [ -n "$step" ] && [ -n "$total" ]; then
Expand Down

0 comments on commit 3a43c4b

Please sign in to comment.