Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 46b0459

Browse files
committed
Merge branch 'ed/color-prompt'
Code clean-up for in-prompt status script (in contrib/). * ed/color-prompt: git-prompt.sh: add missing information in comments git-prompt.sh: do not print duplicate clean color code t9903: remove redundant tests git-prompt.sh: refactor colored prompt code t9903: add tests for git-prompt pcmode
2 parents eb3a4fc + cf4cac4 commit 46b0459

File tree

2 files changed

+182
-70
lines changed

2 files changed

+182
-70
lines changed

contrib/completion/git-prompt.sh

Lines changed: 41 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Copyright (C) 2006,2007 Shawn O. Pearce <[email protected]>
44
# Distributed under the GNU General Public License, version 2.0.
55
#
6-
# This script allows you to see the current branch in your prompt.
6+
# This script allows you to see repository status in your prompt.
77
#
88
# To enable:
99
#
@@ -13,24 +13,27 @@
1313
# 3a) Change your PS1 to call __git_ps1 as
1414
# command-substitution:
1515
# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
16-
# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
16+
# ZSH: setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
1717
# the optional argument will be used as format string.
18-
# 3b) Alternatively, for a slighly faster prompt, if you are
19-
# using bash, __git_ps1 can be used for PROMPT_COMMAND
18+
# 3b) Alternatively, for a slightly faster prompt, __git_ps1 can
19+
# be used for PROMPT_COMMAND in Bash or for precmd() in Zsh
2020
# with two parameters, <pre> and <post>, which are strings
2121
# you would put in $PS1 before and after the status string
2222
# generated by the git-prompt machinery. e.g.
2323
# Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
24+
# will show username, at-sign, host, colon, cwd, then
25+
# various status string, followed by dollar and SP, as
26+
# your prompt.
2427
# ZSH: precmd () { __git_ps1 "%n" ":%~$ " "|%s" }
25-
# will show username, at-sign, host, colon, cwd, then
26-
# various status string, followed by dollar and SP, as
27-
# your prompt.
28+
# will show username, pipe, then various status string,
29+
# followed by colon, cwd, dollar and SP, as your prompt.
2830
# Optionally, you can supply a third argument with a printf
2931
# format string to finetune the output of the branch status
3032
#
31-
# The argument to __git_ps1 will be displayed only if you are currently
32-
# in a git repository. The %s token will be the name of the current
33-
# branch.
33+
# The repository status will be displayed only if you are currently in a
34+
# git repository. The %s token is the placeholder for the shown status.
35+
#
36+
# The prompt status always includes the current branch name.
3437
#
3538
# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty value,
3639
# unstaged (*) and staged (+) changes will be shown next to the branch
@@ -78,7 +81,8 @@
7881
#
7982
# If you would like a colored hint about the current dirty state, set
8083
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
81-
# the colored output of "git status -sb".
84+
# the colored output of "git status -sb" and are available only when
85+
# using __git_ps1 for PROMPT_COMMAND or precmd.
8286

8387
# stores the divergence from upstream in $p
8488
# used by GIT_PS1_SHOWUPSTREAM
@@ -201,83 +205,49 @@ __git_ps1_show_upstream ()
201205
}
202206

203207
# Helper function that is meant to be called from __git_ps1. It
204-
# builds up a gitstring injecting color codes into the appropriate
205-
# places.
208+
# injects color codes into the appropriate gitstring variables used
209+
# to build a gitstring.
206210
__git_ps1_colorize_gitstring ()
207211
{
208212
if [[ -n ${ZSH_VERSION-} ]]; then
209213
local c_red='%F{red}'
210214
local c_green='%F{green}'
211215
local c_lblue='%F{blue}'
212216
local c_clear='%f'
213-
local bad_color=$c_red
214-
local ok_color=$c_green
215-
local branch_color="$c_clear"
216-
local flags_color="$c_lblue"
217-
local branchstring="$c${b##refs/heads/}"
218-
219-
if [ $detached = no ]; then
220-
branch_color="$ok_color"
221-
else
222-
branch_color="$bad_color"
223-
fi
224-
225-
gitstring="$branch_color$branchstring$c_clear"
226-
227-
if [ -n "$w$i$s$u$r$p" ]; then
228-
gitstring="$gitstring$z"
229-
fi
230-
if [ "$w" = "*" ]; then
231-
gitstring="$gitstring$bad_color$w"
232-
fi
233-
if [ -n "$i" ]; then
234-
gitstring="$gitstring$ok_color$i"
235-
fi
236-
if [ -n "$s" ]; then
237-
gitstring="$gitstring$flags_color$s"
238-
fi
239-
if [ -n "$u" ]; then
240-
gitstring="$gitstring$bad_color$u"
241-
fi
242-
gitstring="$gitstring$c_clear$r$p"
243-
return
217+
else
218+
# Using \[ and \] around colors is necessary to prevent
219+
# issues with command line editing/browsing/completion!
220+
local c_red='\[\e[31m\]'
221+
local c_green='\[\e[32m\]'
222+
local c_lblue='\[\e[1;34m\]'
223+
local c_clear='\[\e[0m\]'
244224
fi
245-
local c_red='\e[31m'
246-
local c_green='\e[32m'
247-
local c_lblue='\e[1;34m'
248-
local c_clear='\e[0m'
249225
local bad_color=$c_red
250226
local ok_color=$c_green
251-
local branch_color="$c_clear"
252227
local flags_color="$c_lblue"
253-
local branchstring="$c${b##refs/heads/}"
254228

229+
local branch_color=""
255230
if [ $detached = no ]; then
256231
branch_color="$ok_color"
257232
else
258233
branch_color="$bad_color"
259234
fi
235+
c="$branch_color$c"
260236

261-
# Setting gitstring directly with \[ and \] around colors
262-
# is necessary to prevent wrapping issues!
263-
gitstring="\[$branch_color\]$branchstring\[$c_clear\]"
264-
265-
if [ -n "$w$i$s$u$r$p" ]; then
266-
gitstring="$gitstring$z"
267-
fi
237+
z="$c_clear$z"
268238
if [ "$w" = "*" ]; then
269-
gitstring="$gitstring\[$bad_color\]$w"
239+
w="$bad_color$w"
270240
fi
271241
if [ -n "$i" ]; then
272-
gitstring="$gitstring\[$ok_color\]$i"
242+
i="$ok_color$i"
273243
fi
274244
if [ -n "$s" ]; then
275-
gitstring="$gitstring\[$flags_color\]$s"
245+
s="$flags_color$s"
276246
fi
277247
if [ -n "$u" ]; then
278-
gitstring="$gitstring\[$bad_color\]$u"
248+
u="$bad_color$u"
279249
fi
280-
gitstring="$gitstring\[$c_clear\]$r$p"
250+
r="$c_clear$r"
281251
}
282252

283253
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
@@ -453,22 +423,23 @@ __git_ps1 ()
453423
fi
454424

455425
local z="${GIT_PS1_STATESEPARATOR-" "}"
426+
427+
# NO color option unless in PROMPT_COMMAND mode
428+
if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
429+
__git_ps1_colorize_gitstring
430+
fi
431+
456432
local f="$w$i$s$u"
433+
local gitstring="$c${b##refs/heads/}${f:+$z$f}$r$p"
434+
457435
if [ $pcmode = yes ]; then
458-
local gitstring=
459-
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
460-
__git_ps1_colorize_gitstring
461-
else
462-
gitstring="$c${b##refs/heads/}${f:+$z$f}$r$p"
463-
fi
464436
if [[ -n ${ZSH_VERSION-} ]]; then
465437
gitstring=$(printf -- "$printf_format" "$gitstring")
466438
else
467439
printf -v gitstring -- "$printf_format" "$gitstring"
468440
fi
469441
PS1="$ps1pc_start$gitstring$ps1pc_end"
470442
else
471-
# NO color option unless in PROMPT_COMMAND mode
472-
printf -- "$printf_format" "$c${b##refs/heads/}${f:+$z$f}$r$p"
443+
printf -- "$printf_format" "$gitstring"
473444
fi
474445
}

t/t9903-bash-prompt.sh

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ test_description='test git-specific bash prompt functions'
1010
. "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh"
1111

1212
actual="$TRASH_DIRECTORY/actual"
13+
c_red='\\[\\e[31m\\]'
14+
c_green='\\[\\e[32m\\]'
15+
c_lblue='\\[\\e[1;34m\\]'
16+
c_clear='\\[\\e[0m\\]'
1317

1418
test_expect_success 'setup for prompt tests' '
1519
git init otherrepo &&
@@ -424,4 +428,141 @@ test_expect_success 'prompt - format string starting with dash' '
424428
test_cmp expected "$actual"
425429
'
426430

431+
test_expect_success 'prompt - pc mode' '
432+
printf "BEFORE: (master):AFTER" >expected &&
433+
printf "" >expected_output &&
434+
(
435+
__git_ps1 "BEFORE:" ":AFTER" >"$actual" &&
436+
test_cmp expected_output "$actual" &&
437+
printf "%s" "$PS1" >"$actual"
438+
) &&
439+
test_cmp expected "$actual"
440+
'
441+
442+
test_expect_success 'prompt - bash color pc mode - branch name' '
443+
printf "BEFORE: (${c_green}master${c_clear}):AFTER" >expected &&
444+
(
445+
GIT_PS1_SHOWCOLORHINTS=y &&
446+
__git_ps1 "BEFORE:" ":AFTER" >"$actual"
447+
printf "%s" "$PS1" >"$actual"
448+
) &&
449+
test_cmp expected "$actual"
450+
'
451+
452+
test_expect_success 'prompt - bash color pc mode - detached head' '
453+
printf "BEFORE: (${c_red}(%s...)${c_clear}):AFTER" $(git log -1 --format="%h" b1^) >expected &&
454+
git checkout b1^ &&
455+
test_when_finished "git checkout master" &&
456+
(
457+
GIT_PS1_SHOWCOLORHINTS=y &&
458+
__git_ps1 "BEFORE:" ":AFTER" &&
459+
printf "%s" "$PS1" >"$actual"
460+
) &&
461+
test_cmp expected "$actual"
462+
'
463+
464+
test_expect_success 'prompt - bash color pc mode - dirty status indicator - dirty worktree' '
465+
printf "BEFORE: (${c_green}master${c_clear} ${c_red}*${c_clear}):AFTER" >expected &&
466+
echo "dirty" >file &&
467+
test_when_finished "git reset --hard" &&
468+
(
469+
GIT_PS1_SHOWDIRTYSTATE=y &&
470+
GIT_PS1_SHOWCOLORHINTS=y &&
471+
__git_ps1 "BEFORE:" ":AFTER" &&
472+
printf "%s" "$PS1" >"$actual"
473+
) &&
474+
test_cmp expected "$actual"
475+
'
476+
477+
test_expect_success 'prompt - bash color pc mode - dirty status indicator - dirty index' '
478+
printf "BEFORE: (${c_green}master${c_clear} ${c_green}+${c_clear}):AFTER" >expected &&
479+
echo "dirty" >file &&
480+
test_when_finished "git reset --hard" &&
481+
git add -u &&
482+
(
483+
GIT_PS1_SHOWDIRTYSTATE=y &&
484+
GIT_PS1_SHOWCOLORHINTS=y &&
485+
__git_ps1 "BEFORE:" ":AFTER" &&
486+
printf "%s" "$PS1" >"$actual"
487+
) &&
488+
test_cmp expected "$actual"
489+
'
490+
491+
test_expect_success 'prompt - bash color pc mode - dirty status indicator - dirty index and worktree' '
492+
printf "BEFORE: (${c_green}master${c_clear} ${c_red}*${c_green}+${c_clear}):AFTER" >expected &&
493+
echo "dirty index" >file &&
494+
test_when_finished "git reset --hard" &&
495+
git add -u &&
496+
echo "dirty worktree" >file &&
497+
(
498+
GIT_PS1_SHOWCOLORHINTS=y &&
499+
GIT_PS1_SHOWDIRTYSTATE=y &&
500+
__git_ps1 "BEFORE:" ":AFTER" &&
501+
printf "%s" "$PS1" >"$actual"
502+
) &&
503+
test_cmp expected "$actual"
504+
'
505+
506+
test_expect_success 'prompt - bash color pc mode - dirty status indicator - before root commit' '
507+
printf "BEFORE: (${c_green}master${c_clear} ${c_green}#${c_clear}):AFTER" >expected &&
508+
(
509+
GIT_PS1_SHOWDIRTYSTATE=y &&
510+
GIT_PS1_SHOWCOLORHINTS=y &&
511+
cd otherrepo &&
512+
__git_ps1 "BEFORE:" ":AFTER" &&
513+
printf "%s" "$PS1" >"$actual"
514+
) &&
515+
test_cmp expected "$actual"
516+
'
517+
518+
test_expect_success 'prompt - bash color pc mode - inside .git directory' '
519+
printf "BEFORE: (${c_green}GIT_DIR!${c_clear}):AFTER" >expected &&
520+
echo "dirty" >file &&
521+
test_when_finished "git reset --hard" &&
522+
(
523+
GIT_PS1_SHOWDIRTYSTATE=y &&
524+
GIT_PS1_SHOWCOLORHINTS=y &&
525+
cd .git &&
526+
__git_ps1 "BEFORE:" ":AFTER" &&
527+
printf "%s" "$PS1" >"$actual"
528+
) &&
529+
test_cmp expected "$actual"
530+
'
531+
532+
test_expect_success 'prompt - bash color pc mode - stash status indicator' '
533+
printf "BEFORE: (${c_green}master${c_clear} ${c_lblue}\$${c_clear}):AFTER" >expected &&
534+
echo 2 >file &&
535+
git stash &&
536+
test_when_finished "git stash drop" &&
537+
(
538+
GIT_PS1_SHOWSTASHSTATE=y &&
539+
GIT_PS1_SHOWCOLORHINTS=y &&
540+
__git_ps1 "BEFORE:" ":AFTER" &&
541+
printf "%s" "$PS1" >"$actual"
542+
) &&
543+
test_cmp expected "$actual"
544+
'
545+
546+
test_expect_success 'prompt - bash color pc mode - untracked files status indicator' '
547+
printf "BEFORE: (${c_green}master${c_clear} ${c_red}%%${c_clear}):AFTER" >expected &&
548+
(
549+
GIT_PS1_SHOWUNTRACKEDFILES=y &&
550+
GIT_PS1_SHOWCOLORHINTS=y &&
551+
__git_ps1 "BEFORE:" ":AFTER" &&
552+
printf "%s" "$PS1" >"$actual"
553+
) &&
554+
test_cmp expected "$actual"
555+
'
556+
557+
test_expect_success 'prompt - zsh color pc mode' '
558+
printf "BEFORE: (%%F{green}master%%f):AFTER" >expected &&
559+
(
560+
ZSH_VERSION=5.0.0 &&
561+
GIT_PS1_SHOWCOLORHINTS=y &&
562+
__git_ps1 "BEFORE:" ":AFTER" >"$actual"
563+
printf "%s" "$PS1" >"$actual"
564+
) &&
565+
test_cmp expected "$actual"
566+
'
567+
427568
test_done

0 commit comments

Comments
 (0)