Skip to content

Commit 5471fb1

Browse files
committed
Merge branch 'so/prompt-command'
Updates __git_ps1 so that it can be used as $PROMPT_COMMAND, instead of being used for command substitution in $PS1, to embed color escape sequences in its output. * so/prompt-command: coloured git-prompt: paint detached HEAD marker in red Fix up colored git-prompt show color hints based on state of the git tree Allow __git_ps1 to be used in PROMPT_COMMAND
2 parents 2739889 + 76c36c0 commit 5471fb1

File tree

1 file changed

+90
-8
lines changed

1 file changed

+90
-8
lines changed

contrib/completion/git-prompt.sh

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@
1010
# 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
1111
# 2) Add the following line to your .bashrc/.zshrc:
1212
# source ~/.git-prompt.sh
13-
# 3) Change your PS1 to also show the current branch:
14-
# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
15-
# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
13+
# 3a) In ~/.bashrc set PROMPT_COMMAND=__git_ps1
14+
# To customize the prompt, provide start/end arguments
15+
# PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
16+
# 3b) Alternatively change your PS1 to call __git_ps1 as
17+
# command-substitution:
18+
# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
19+
# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
20+
# the optional argument will be used as format string
1621
#
1722
# The argument to __git_ps1 will be displayed only if you are currently
1823
# in a git repository. The %s token will be the name of the current
@@ -49,7 +54,11 @@
4954
# find one, or @{upstream} otherwise. Once you have set
5055
# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
5156
# setting the bash.showUpstream config variable.
52-
57+
#
58+
# If you would like a colored hint about the current dirty state, set
59+
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
60+
# the colored output of "git status -sb".
61+
#
5362
# __gitdir accepts 0 or 1 arguments (i.e., location)
5463
# returns location of .git repo
5564
__gitdir ()
@@ -195,11 +204,40 @@ __git_ps1_show_upstream ()
195204

196205

197206
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
198-
# returns text to add to bash PS1 prompt (includes branch name)
207+
# when called from PS1 using command substitution
208+
# in this mode it prints text to add to bash PS1 prompt (includes branch name)
209+
#
210+
# __git_ps1 requires 2 arguments when called from PROMPT_COMMAND (pc)
211+
# in that case it _sets_ PS1. The arguments are parts of a PS1 string.
212+
# when both arguments are given, the first is prepended and the second appended
213+
# to the state string when assigned to PS1.
214+
# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
199215
__git_ps1 ()
200216
{
217+
local pcmode=no
218+
local detached=no
219+
local ps1pc_start='\u@\h:\w '
220+
local ps1pc_end='\$ '
221+
local printf_format=' (%s)'
222+
223+
case "$#" in
224+
2) pcmode=yes
225+
ps1pc_start="$1"
226+
ps1pc_end="$2"
227+
;;
228+
0|1) printf_format="${1:-$printf_format}"
229+
;;
230+
*) return
231+
;;
232+
esac
233+
201234
local g="$(__gitdir)"
202-
if [ -n "$g" ]; then
235+
if [ -z "$g" ]; then
236+
if [ $pcmode = yes ]; then
237+
#In PC mode PS1 always needs to be set
238+
PS1="$ps1pc_start$ps1pc_end"
239+
fi
240+
else
203241
local r=""
204242
local b=""
205243
if [ -f "$g/rebase-merge/interactive" ]; then
@@ -226,7 +264,7 @@ __git_ps1 ()
226264
fi
227265

228266
b="$(git symbolic-ref HEAD 2>/dev/null)" || {
229-
267+
detached=yes
230268
b="$(
231269
case "${GIT_PS1_DESCRIBE_STYLE-}" in
232270
(contains)
@@ -285,6 +323,50 @@ __git_ps1 ()
285323
fi
286324

287325
local f="$w$i$s$u"
288-
printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
326+
if [ $pcmode = yes ]; then
327+
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
328+
local c_red='\e[31m'
329+
local c_green='\e[32m'
330+
local c_lblue='\e[1;34m'
331+
local c_clear='\e[0m'
332+
local bad_color=$c_red
333+
local ok_color=$c_green
334+
local branch_color="$c_clear"
335+
local flags_color="$c_lblue"
336+
local branchstring="$c${b##refs/heads/}"
337+
338+
if [ $detached = no ]; then
339+
branch_color="$ok_color"
340+
else
341+
branch_color="$bad_color"
342+
fi
343+
344+
# Setting PS1 directly with \[ and \] around colors
345+
# is necessary to prevent wrapping issues!
346+
PS1="$ps1pc_start (\[$branch_color\]$branchstring\[$c_clear\]"
347+
348+
if [ -n "$w$i$s$u$r$p" ]; then
349+
PS1="$PS1 "
350+
fi
351+
if [ "$w" = "*" ]; then
352+
PS1="$PS1\[$bad_color\]$w"
353+
fi
354+
if [ -n "$i" ]; then
355+
PS1="$PS1\[$ok_color\]$i"
356+
fi
357+
if [ -n "$s" ]; then
358+
PS1="$PS1\[$flags_color\]$s"
359+
fi
360+
if [ -n "$u" ]; then
361+
PS1="$PS1\[$bad_color\]$u"
362+
fi
363+
PS1="$PS1\[$c_clear\]$r$p)$ps1pc_end"
364+
else
365+
PS1="$ps1pc_start ($c${b##refs/heads/}${f:+ $f}$r$p)$ps1pc_end"
366+
fi
367+
else
368+
# NO color option unless in PROMPT_COMMAND mode
369+
printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p"
370+
fi
289371
fi
290372
}

0 commit comments

Comments
 (0)