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) <avihpit@yahoo.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Avi Halachmi (:avih) committed Aug 20, 2024 at 01:48 UTC 29bcec82a67ebeec0c3eaf865a06e52cde8c589b
1 file changed +29 -18
contrib/completion/git-prompt.sh
+29 -18
@@ -111,6 +111,12 @@
111 __git_printf_supports_v=
112 printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1
113
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 +
120 # stores the divergence from upstream in $p
121 # used by GIT_PS1_SHOWUPSTREAM
122 __git_ps1_show_upstream ()
@@ -118,7 +124,7 @@ __git_ps1_show_upstream ()
124 local key value
125 local svn_remotes="" svn_url_pattern="" count n
126 local upstream_type=git legacy="" verbose="" name=""
121 - local LF=$'\n'
127 + local LF="$__git_LF"
128
129 # get some config options from git-config
130 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 ()
277 local c_lblue='%F{blue}'
278 local c_clear='%f'
279 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}"
290 fi
291 local bad_color="$c_red"
292 local ok_color="$c_green"
@@ -312,7 +322,7 @@ __git_ps1_colorize_gitstring ()
322 # variable, in that order.
323 __git_eread ()
324 {
315 - test -r "$1" && IFS=$'\r\n' read -r "$2" <"$1"
325 + test -r "$1" && IFS=$__git_CRLF read -r "$2" <"$1"
326 }
327
328 # see if a cherry-pick or revert is in progress, if the user has committed a
@@ -430,19 +440,20 @@ __git_ps1 ()
440 return "$exit"
441 fi
442
443 + local LF="$__git_LF"
444 local short_sha=""
445 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*}"
448 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*}"
457
458 if [ "true" = "$inside_worktree" ] &&
459 [ -n "${GIT_PS1_HIDE_IF_PWD_IGNORED-}" ] &&