Do you know if it is possible to configure the bash prompt to show the git status / branch info on the right side as zsh can do? This randomly screen shot from the internet shows what I mean.

Try the following:
PS1='$(printf "%*s\r%s" $(( COLUMNS-1 )) "[$(git branch 2>/dev/null | grep '^*' | sed s/..//)] $(date +%H:%M:%S)" "heipei@wavefront:$PWD$ ")'
Note that you'll never get behavior that exactly matches zsh one with bash only. In the above case I see the following differencies:
accept-line event in terms of zsh).<C-u> or <BS>.The code below will create a prompt which looks like:

It's non-trival to do this in bash due to:
printf solutions won't work in some cases. Because of this:__git_ps1 to deal with git edge cases__git_ps1 only outputting colour in certain circumstances, and only inside $PS1
__git_ps1 output while removing the \[ and \] characters from its output (which can't be nested)\[ and \] to ensure that the prompt doesn't do weird things when browsing / editing / completing commands#!/bin/bash
# _options=$(shopt -op); set -exu # Save and set shell options for testing
##################
# Set the prompt #    Sourced from .bashrc
##################
# Select git info displayed, see /usr/lib/git-core/git-sh-prompt for more
export GIT_PS1_SHOWCOLORHINTS=1           # Make pretty colours inside $PS1
export GIT_PS1_SHOWDIRTYSTATE=1           # '*'=unstaged, '+'=staged
export GIT_PS1_SHOWSTASHSTATE=1           # '$'=stashed
export GIT_PS1_SHOWUNTRACKEDFILES=1       # '%'=untracked
export GIT_PS1_SHOWUPSTREAM="verbose"     # 'u='=no difference, 'u+1'=ahead by 1 commit
export GIT_PS1_STATESEPARATOR=''          # No space between branch and index status
export GIT_PS1_DESCRIBE_STYLE="describe"  # Detached HEAD style:
#  describe      relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
#  contains      relative to newer annotated tag (v1.6.3.2~35)
#  branch        relative to newer tag or branch (master~4)
#  default       exactly eatching tag
# Sets prompt like:
# ravi@boxy:~/prj/sample_app[exit]$                   master*% u= | 30 Apr 22:27
_set_bash_prompt() {
  # Set left hand side of the prompt
  PS1="\u@\h:\w\$ "
  #
  # Git status
  #
  # Save current state of user shopt settings promptvars and extglob
  local user_shopt
  user_shopt=$(shopt -p promptvars extglob)
  # __git_ps1 usually returns literal text "${__git_ps1_branch_name}" rather
  # than the contained branch name, eg "master". This prevents calculating
  # the length of the printable characers in the RHS string (used to move the
  # cursor that many columns left from the terminal's right edge.) However if
  # "shopt promptvars" is unset, __git_ps1 it will include the dereferenced
  # branch name instead.
  shopt -qu promptvars
  # extglob is required for the ${variable//@(pattern)/} replacements
  shopt -qs extglob
  # Allow disabling git status and no error if __git_ps1 undefined
  if [[ ! -v _disable_git_prompt && $(type -t __git_ps1 2>/dev/null) == function ]]; then
    # __git_ps1 will only make pretty colours inside $PS1
    local old_PS1=$PS1
    __git_ps1 "" "" "%s" # force colour; no default round bracket (decorations)
    # Strip "\[" and "\[": non-printable character markers. __git_ps1 outputs
    # them however the whole of the RHS prompt needs to be included in these
    # markers, and they can't be nested.
    git=${PS1//@(\\@(\[|\]))/}
    PS1=$old_PS1
  fi
  #
  # Right hand side of prompt
  #
  local rhs="" # String to be printed on the right hand side of terminal
  # Create a string like: "25 Apr 13:15"
  local date_time
  printf -v date_time "%(%e %b %H:%M)T" -1 # -1 is current time
  # Format the RHS prompt
  [[ -n $git ]] && rhs="$git | " #"
  rhs+="\e[0;1;31m${date_time}"
  # Strip ANSI CSI commands (eg colours) to enble counting the length of
  # printable characters, giving offset of cursor from terminal RHS edge (from
  # https://www.commandlinefu.com/commands/view/12043/remove-color-special-escape-ansi-codes-from-text-with-sed)
  # Neither bash not sed support lookbehind zero-length assertions, so it's not
  # possible to ignore "\\e", (ie a literal '\' followed by a literal 'e'), yet
  # still remove "\e" (ie ESC)
  local rhs_printable=${rhs//@(\\@(\[|]|[Ee]\[*([0-9;])[a-zA-Z]))/}
  # or, in using sed (but requires exec):
  # local rhs_printable=$(sed -e 's,\\[][]\|\\[Ee]\[\([0-9;]\)*[A-Za-z],,g' <<< "$rhs")
  # Reference: https://en.wikipedia.org/wiki/ANSI_escape_code
  local Save='\e[s' # Save cursor position
  local Rest='\e[u' # Restore cursor to save point
  # Save cursor position, jump to (right hand edge minus N columns) where N is
  # the length of the printable RHS string. Print the RHS string, then return
  # to the saved position and print the LHS prompt.
  # Note: "\[" and "\]" are used so that bash can calculate the number of
  # printed characters so that the prompt doesn't do strange things when
  # command line editing/browsing/completion. Ensure that these are not nested.
  PS1="\[\e[0m${Save}\e[$((COLUMNS - ${#rhs_printable}))G${rhs}${Rest}\]${PS1}"
  eval "$user_shopt"
}
# eval "$_options"; unset _options # Restore previous shell options from line 2
Today I built something like that in the following manner. Thorough testing has not been made yet...
preprompt() {
  rc=$?
  c=31
  [ $rc -eq 0 ] && c=32
  PS1="\[$(color $c)\]$rc\[$(color 0)\] \t \w \$ "
  # right "prompt"
  # We cannot use $COLUMNS here, since in new shells the first prompt
  # will get garbled then. Seems like the correct value of COLUMNS is
  # in the shell init.
  printf "%`tput cols`s`tput cr`" "${USER}@${HOST}"
}
PROMPT_COMMAND=preprompt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With