From 1bfc51ac814125de03ddf1900245e42d6ce0d250 Mon Sep 17 00:00:00 2001 From: Simon Oosthoek Date: Wed, 10 Oct 2012 21:31:58 +0200 Subject: Allow __git_ps1 to be used in PROMPT_COMMAND Changes __git_ps1 to allow its use as PROMPT_COMMAND in bash in addition to setting PS1 with __git_ps1 in a command substitution. PROMPT_COMMAND has advantages for using color without running into prompt-wrapping issues. Only by assigning \[ and \] to PS1 directly can bash know that these and the enclosed zero-width codes in between don't count in the length of the prompt. Signed-off-by: Simon Oosthoek Signed-off-by: Junio C Hamano --- contrib/completion/git-prompt.sh | 51 +++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index bf20491ec3..ce67eb75a4 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -10,9 +10,14 @@ # 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh). # 2) Add the following line to your .bashrc/.zshrc: # source ~/.git-prompt.sh -# 3) Change your PS1 to also show the current branch: -# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' -# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' +# 3a) In ~/.bashrc set PROMPT_COMMAND=__git_ps1 +# To customize the prompt, provide start/end arguments +# PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "' +# 3b) Alternatively change your PS1 to call __git_ps1 as +# command-substitution: +# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' +# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' +# the optional argument will be used as format string # # The argument to __git_ps1 will be displayed only if you are currently # in a git repository. The %s token will be the name of the current @@ -195,11 +200,39 @@ __git_ps1_show_upstream () # __git_ps1 accepts 0 or 1 arguments (i.e., format string) -# returns text to add to bash PS1 prompt (includes branch name) +# when called from PS1 using command substitution +# in this mode it prints text to add to bash PS1 prompt (includes branch name) +# +# __git_ps1 requires 2 arguments when called from PROMPT_COMMAND (pc) +# in that case it _sets_ PS1. The arguments are parts of a PS1 string. +# when both arguments are given, the first is prepended and the second appended +# to the state string when assigned to PS1. __git_ps1 () { + local pcmode=no + #defaults/examples: + local ps1pc_start='\u@\h:\w ' + local ps1pc_end='\$ ' + local printf_format=' (%s)' + + case "$#" in + 2) pcmode=yes + ps1pc_start="$1" + ps1pc_end="$2" + ;; + 0|1) printf_format="${1:-$printf_format}" + ;; + *) return + ;; + esac + local g="$(__gitdir)" - if [ -n "$g" ]; then + if [ -z "$g" ]; then + if [ $pcmode = yes ]; then + #In PC mode PS1 always needs to be set + PS1="$ps1pc_start$ps1pc_end" + fi + else local r="" local b="" if [ -f "$g/rebase-merge/interactive" ]; then @@ -285,6 +318,12 @@ __git_ps1 () fi local f="$w$i$s$u" - printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" + if [ $pcmode = yes ]; then + PS1="$ps1pc_start(" + PS1="$PS1$c${b##refs/heads/}${f:+ $f}$r$p" + PS1="$PS1)$ps1pc_end" + else + printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p" + fi fi } -- cgit v1.2.3 From 9b7e776c0a5e6e90601badf175ad034ada5a230e Mon Sep 17 00:00:00 2001 From: Simon Oosthoek Date: Wed, 10 Oct 2012 21:32:24 +0200 Subject: show color hints based on state of the git tree By setting GIT_PS1_SHOW_COLORHINTS when using __git_ps1 as PROMPT_COMMAND, you will get color hints in addition to a different character (*+% etc.) to indicate the state of the tree. Signed-off-by: Simon Oosthoek Signed-off-by: Junio C Hamano --- contrib/completion/git-prompt.sh | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index ce67eb75a4..ae68182687 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -54,6 +54,12 @@ # find one, or @{upstream} otherwise. Once you have set # GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by # setting the bash.showUpstream config variable. +# +# If you would like a colored hint about the current dirty state, set +# GIT_PS1_SHOWCOLORHINTS to a nonempty value. When tracked files are +# modified, the branch name turns red, when all modifications are staged +# the branch name turns yellow and when all changes are checked in, the +# color changes to green. The colors are currently hardcoded in the function. # __gitdir accepts 0 or 1 arguments (i.e., location) # returns location of .git repo @@ -207,6 +213,7 @@ __git_ps1_show_upstream () # in that case it _sets_ PS1. The arguments are parts of a PS1 string. # when both arguments are given, the first is prepended and the second appended # to the state string when assigned to PS1. +# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true __git_ps1 () { local pcmode=no @@ -320,9 +327,36 @@ __git_ps1 () local f="$w$i$s$u" if [ $pcmode = yes ]; then PS1="$ps1pc_start(" - PS1="$PS1$c${b##refs/heads/}${f:+ $f}$r$p" + if [ -n "${GIT_PS1_SHOWCOLORHINT-}" ]; then + local c_red='\e[31m' + local c_green='\e[32m' + local c_yellow='\e[33m' + local c_lblue='\e[1;34m' + local c_purple='\e[35m' + local c_cyan='\e[36m' + local c_clear='\e[0m' + local branchstring="$c${b##refs/heads/}" + local branch_color="$c_green" + local flags_color="$c_cyan" + + if [ "$w" = "*" ]; then + branch_color="$c_red" + elif [ -n "$i" ]; then + branch_color="$c_yellow" + fi + + # Setting PS1 directly with \[ and \] around colors + # is necessary to prevent wrapping issues! + PS1="$PS1\[$branch_color\]$branchstring\[$c_clear\]" + if [ -n "$f" ]; then + PS1="$PS1 \[$flags_color\]$f\[$c_clear\]" + fi + else + PS1="$PS1$c${b##refs/heads/}${f:+ $f}$r$p" + fi PS1="$PS1)$ps1pc_end" else + # NO color option unless in PROMPT_COMMAND mode printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p" fi fi -- cgit v1.2.3 From 9b3aaf8bf19ce2bf5e73b972dce31430e43df8dc Mon Sep 17 00:00:00 2001 From: Simon Oosthoek Date: Tue, 16 Oct 2012 21:34:05 +0200 Subject: Fix up colored git-prompt The main point is to match the colors to be more close to the color output of "git status -sb". - the branchname is green, or in red when the HEAD is detached; - the flags are either red or green for unstaged/staged and the remaining flags get a different color or none at all. Signed-off-by: Simon Oosthoek Signed-off-by: Junio C Hamano --- contrib/completion/git-prompt.sh | 55 +++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index ae68182687..9f0b6bbc12 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -56,11 +56,9 @@ # setting the bash.showUpstream config variable. # # If you would like a colored hint about the current dirty state, set -# GIT_PS1_SHOWCOLORHINTS to a nonempty value. When tracked files are -# modified, the branch name turns red, when all modifications are staged -# the branch name turns yellow and when all changes are checked in, the -# color changes to green. The colors are currently hardcoded in the function. - +# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on +# the colored output of "git status -sb". +# # __gitdir accepts 0 or 1 arguments (i.e., location) # returns location of .git repo __gitdir () @@ -217,7 +215,7 @@ __git_ps1_show_upstream () __git_ps1 () { local pcmode=no - #defaults/examples: + local detached=no local ps1pc_start='\u@\h:\w ' local ps1pc_end='\$ ' local printf_format=' (%s)' @@ -266,7 +264,7 @@ __git_ps1 () fi b="$(git symbolic-ref HEAD 2>/dev/null)" || { - + detached=yes b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in (contains) @@ -326,35 +324,46 @@ __git_ps1 () local f="$w$i$s$u" if [ $pcmode = yes ]; then - PS1="$ps1pc_start(" - if [ -n "${GIT_PS1_SHOWCOLORHINT-}" ]; then + if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then local c_red='\e[31m' local c_green='\e[32m' - local c_yellow='\e[33m' local c_lblue='\e[1;34m' - local c_purple='\e[35m' - local c_cyan='\e[36m' local c_clear='\e[0m' + local bad_color=$c_red + local ok_color=$c_green + local branch_color="$c_clear" + local flags_color="$c_lblue" local branchstring="$c${b##refs/heads/}" - local branch_color="$c_green" - local flags_color="$c_cyan" - if [ "$w" = "*" ]; then - branch_color="$c_red" - elif [ -n "$i" ]; then - branch_color="$c_yellow" + if [ $detached = yes ]; then + branch_color="$ok_color" + else + branch_color="$bad_color" fi # Setting PS1 directly with \[ and \] around colors # is necessary to prevent wrapping issues! - PS1="$PS1\[$branch_color\]$branchstring\[$c_clear\]" - if [ -n "$f" ]; then - PS1="$PS1 \[$flags_color\]$f\[$c_clear\]" + PS1="$ps1pc_start (\[$branch_color\]$branchstring\[$c_clear\]" + + if [ -n "$w$i$s$u$r$p" ]; then + PS1="$PS1 " + fi + if [ "$w" = "*" ]; then + PS1="$PS1\[$bad_color\]$w" + fi + if [ -n "$i" ]; then + PS1="$PS1\[$ok_color\]$i" + fi + if [ -n "$s" ]; then + PS1="$PS1\[$flags_color\]$s" + fi + if [ -n "$u" ]; then + PS1="$PS1\[$bad_color\]$u" fi + PS1="$PS1\[$c_clear\]$r$p)$ps1pc_end" else - PS1="$PS1$c${b##refs/heads/}${f:+ $f}$r$p" + PS1="$ps1pc_start ($c${b##refs/heads/}${f:+ $f}$r$p)$ps1pc_end" fi - PS1="$PS1)$ps1pc_end" else # NO color option unless in PROMPT_COMMAND mode printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p" -- cgit v1.2.3 From 76c36c02ff3fe1571051ce9278248bd269f8341b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 17 Oct 2012 00:44:25 -0700 Subject: coloured git-prompt: paint detached HEAD marker in red Paint the marker for normal state in green and detached state in red, instead of the other way around. Signed-off-by: Junio C Hamano --- contrib/completion/git-prompt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 9f0b6bbc12..00fc099b8d 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -335,7 +335,7 @@ __git_ps1 () local flags_color="$c_lblue" local branchstring="$c${b##refs/heads/}" - if [ $detached = yes ]; then + if [ $detached = no ]; then branch_color="$ok_color" else branch_color="$bad_color" -- cgit v1.2.3