Skip to content

Commit 3a43c4b

Browse files
committed
bash prompt: use bash builtins to find out current branch
__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 <[email protected]>
1 parent b91b935 commit 3a43c4b

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

contrib/completion/git-prompt.sh

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -355,25 +355,40 @@ __git_ps1 ()
355355
r="|BISECTING"
356356
fi
357357

358-
test -n "$b" ||
359-
b="$(git symbolic-ref HEAD 2>/dev/null)" || {
360-
detached=yes
361-
b="$(
362-
case "${GIT_PS1_DESCRIBE_STYLE-}" in
363-
(contains)
364-
git describe --contains HEAD ;;
365-
(branch)
366-
git describe --contains --all HEAD ;;
367-
(describe)
368-
git describe HEAD ;;
369-
(* | default)
370-
git describe --tags --exact-match HEAD ;;
371-
esac 2>/dev/null)" ||
358+
if [ -n "$b" ]; then
359+
:
360+
elif [ -h "$g/HEAD" ]; then
361+
# symlink symbolic ref
362+
b="$(git symbolic-ref HEAD 2>/dev/null)"
363+
else
364+
local head=""
365+
if ! read head 2>/dev/null <"$g/HEAD"; then
366+
if [ $pcmode = yes ]; then
367+
PS1="$ps1pc_start$ps1pc_end"
368+
fi
369+
return
370+
fi
371+
# is it a symbolic ref?
372+
b="${head#ref: }"
373+
if [ "$head" = "$b" ]; then
374+
detached=yes
375+
b="$(
376+
case "${GIT_PS1_DESCRIBE_STYLE-}" in
377+
(contains)
378+
git describe --contains HEAD ;;
379+
(branch)
380+
git describe --contains --all HEAD ;;
381+
(describe)
382+
git describe HEAD ;;
383+
(* | default)
384+
git describe --tags --exact-match HEAD ;;
385+
esac 2>/dev/null)" ||
372386

373-
b="$(git rev-parse --short HEAD 2>/dev/null)..." ||
374-
b="unknown"
375-
b="($b)"
376-
}
387+
b="$(git rev-parse --short HEAD 2>/dev/null)..." ||
388+
b="unknown"
389+
b="($b)"
390+
fi
391+
fi
377392
fi
378393

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

0 commit comments

Comments
 (0)