Skip to content

Commit 29bcec8

Browse files
avihgitster
authored andcommitted
git-prompt: don't use shell $'...'
$'...' is new in POSIX (2024), and some shells support it in recent versions, while others have had it for decades (bash, zsh, ksh93). However, there are still enough shells which don't support it, and it's cheap to use an alternative form which works in all shells, so let's do that instead of dismissing it as "it's compliant". It was agreed to use one form rather than $'...' where supported and fallback otherwise. shells where $'...' works: - bash, zsh, ksh93, mksh, busybox-ash, dash master, free/net bsd sh. shells where it doesn't work, but the new fallback works: - all dash releases (up to 0.5.12), older versions of free/net bsd sh, openbsd sh, pdksh, all Schily Bourne sh variants, yash. Signed-off-by: Avi Halachmi (:avih) <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b732e08 commit 29bcec8

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

contrib/completion/git-prompt.sh

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,20 @@
111111
__git_printf_supports_v=
112112
printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1
113113

114+
# like __git_SOH=$'\001' etc but works also in shells without $'...'
115+
eval "$(printf '
116+
__git_SOH="\001" __git_STX="\002" __git_ESC="\033"
117+
__git_LF="\n" __git_CRLF="\r\n"
118+
')"
119+
114120
# stores the divergence from upstream in $p
115121
# used by GIT_PS1_SHOWUPSTREAM
116122
__git_ps1_show_upstream ()
117123
{
118124
local key value
119125
local svn_remotes="" svn_url_pattern="" count n
120126
local upstream_type=git legacy="" verbose="" name=""
121-
local LF=$'\n'
127+
local LF="$__git_LF"
122128

123129
# get some config options from git-config
124130
local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
@@ -271,12 +277,16 @@ __git_ps1_colorize_gitstring ()
271277
local c_lblue='%F{blue}'
272278
local c_clear='%f'
273279
else
274-
# Using \001 and \002 around colors is necessary to prevent
275-
# issues with command line editing/browsing/completion!
276-
local c_red=$'\001\e[31m\002'
277-
local c_green=$'\001\e[32m\002'
278-
local c_lblue=$'\001\e[1;34m\002'
279-
local c_clear=$'\001\e[0m\002'
280+
# \001 (SOH) and \002 (STX) are 0-width substring markers
281+
# which bash/readline identify while calculating the prompt
282+
# on-screen width - to exclude 0-screen-width esc sequences.
283+
local c_pre="${__git_SOH}${__git_ESC}["
284+
local c_post="m${__git_STX}"
285+
286+
local c_red="${c_pre}31${c_post}"
287+
local c_green="${c_pre}32${c_post}"
288+
local c_lblue="${c_pre}1;34${c_post}"
289+
local c_clear="${c_pre}0${c_post}"
280290
fi
281291
local bad_color="$c_red"
282292
local ok_color="$c_green"
@@ -312,7 +322,7 @@ __git_ps1_colorize_gitstring ()
312322
# variable, in that order.
313323
__git_eread ()
314324
{
315-
test -r "$1" && IFS=$'\r\n' read -r "$2" <"$1"
325+
test -r "$1" && IFS=$__git_CRLF read -r "$2" <"$1"
316326
}
317327

318328
# see if a cherry-pick or revert is in progress, if the user has committed a
@@ -430,19 +440,20 @@ __git_ps1 ()
430440
return "$exit"
431441
fi
432442

443+
local LF="$__git_LF"
433444
local short_sha=""
434445
if [ "$rev_parse_exit_code" = "0" ]; then
435-
short_sha="${repo_info##*$'\n'}"
436-
repo_info="${repo_info%$'\n'*}"
446+
short_sha="${repo_info##*$LF}"
447+
repo_info="${repo_info%$LF*}"
437448
fi
438-
local ref_format="${repo_info##*$'\n'}"
439-
repo_info="${repo_info%$'\n'*}"
440-
local inside_worktree="${repo_info##*$'\n'}"
441-
repo_info="${repo_info%$'\n'*}"
442-
local bare_repo="${repo_info##*$'\n'}"
443-
repo_info="${repo_info%$'\n'*}"
444-
local inside_gitdir="${repo_info##*$'\n'}"
445-
local g="${repo_info%$'\n'*}"
449+
local ref_format="${repo_info##*$LF}"
450+
repo_info="${repo_info%$LF*}"
451+
local inside_worktree="${repo_info##*$LF}"
452+
repo_info="${repo_info%$LF*}"
453+
local bare_repo="${repo_info##*$LF}"
454+
repo_info="${repo_info%$LF*}"
455+
local inside_gitdir="${repo_info##*$LF}"
456+
local g="${repo_info%$LF*}"
446457

447458
if [ "true" = "$inside_worktree" ] &&
448459
[ -n "${GIT_PS1_HIDE_IF_PWD_IGNORED-}" ] &&

0 commit comments

Comments
 (0)