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
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