Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does __git_ps1 update the bash prompt?

Tags:

git

bash

shell

I'm a Windows user with the Git Bash shell as my daily-driver. I'm curious how the __git_ps1 function updates the prompt every time you change a directory. It's really the only example of updating the bash prompt on the fly that I've seen. I want to leverage this behavior in my own function to add a display on my prompt if I have an RDP session open.

tldr: Any ideas on how the __git_ps1 function evaluates the bash prompt on the fly????

So here is my simple function to see if the RDP client is running

function __rdp_ps1() {
  local MATCH=
  if tasklist | grep --quiet mstsc; then
    MATCH="\e[41mRDP\e[0m"
  fi
  echo "$MATCH"
}

So the idea is I want to display RDP with a red background, and I want my shell to evaluate this on the fly the same way __git__ps1 is seemingly able to.

What I've investigated (without real success) so far

/etc/profile.d/git-prompt.sh

This block seems to create the PS1 my shell is using

    PS1='\[\033]0;$TITLEPREFIX:$PWD\007\]' # set window title
    PS1="$PS1"'\n'                 # new line
    PS1="$PS1"'\[\033[32m\]'       # change to green
    PS1="$PS1"'\u@\h '             # user@host<space>
    PS1="$PS1"'\[\033[35m\]'       # change to purple
    PS1="$PS1"'$MSYSTEM '          # show MSYSTEM
    PS1="$PS1"'\[\033[33m\]'       # change to brownish yellow
    PS1="$PS1"'\w'                 # current working directory
    if test -z "$WINELOADERNOEXEC"
    then
        GIT_EXEC_PATH="$(git --exec-path 2>/dev/null)"
        COMPLETION_PATH="${GIT_EXEC_PATH%/libexec/git-core}"
        COMPLETION_PATH="${COMPLETION_PATH%/lib/git-core}"
        COMPLETION_PATH="$COMPLETION_PATH/share/git/completion"
        if test -f "$COMPLETION_PATH/git-prompt.sh"
        then
            . "$COMPLETION_PATH/git-completion.bash"
            . "$COMPLETION_PATH/git-prompt.sh"
            PS1="$PS1"'\[\033[36m\]'  # change color to cyan

# tried hamjamming PS1="$PS1 `__rdp_ps1`" here, it only works on login

            PS1="$PS1"'`__git_ps1`'   # bash function
        fi
    fi
    PS1="$PS1"'\[\033[0m\]'        # change color
    PS1="$PS1"'\n'                 # new line
    PS1="$PS1"'$ '                 # prompt: always $

So I went to see where this file was being sourced to see if that could lead to the answer

/etc/bash.bashrc

Last line held the gold

# Fixup git-bash in non login env
shopt -q login_shell || . /etc/profile.d/git-prompt.sh`

So I evaluated shopt login_shell and it's always on, but I don't really know what that means because the comment leads me to believe that when login env is off, the prompt script will be evaluated

Any ideas???

like image 300
Sean Kelly Avatar asked Feb 28 '26 08:02

Sean Kelly


2 Answers

Your problem might be that you define your $PS1 with double quotes, which bash interprets when executing. Which means that __rdp_ps1 is ran when $PS1 is defined.

In your .bashrc, try replacing the definition with:

PS1='$PS1 `__rdp_ps1`' # Note the single quote. 

I have a similar feature on my PS1 (but to display the number of jobs in the background), here is the full version (available here: https://github.com/padawin/dotfiles/blob/master/.bashrc#L70):

function j(){
    jobs | wc -l | egrep -v ^0 | sed -r 's/^([0-9]+)/ (\1)/'
}

PROMPT_COMMAND=__prompt_command # Func to gen PS1 after CMDs

__prompt_command() {
    local EXIT="$?" # This needs to be first
    PS1="$(virtual_env_name)"

    local RCol='\[\e[0m\]'

    local Red='\e[0;31m'
    local Gre='\e[0;32m'
    local Blu='\e[1;34m'

    PS1+="${Gre}\u@\h$(j)${RCol}: ${Red}\w${Blu}$(__git_ps1)"
    if [ $EXIT != 0 ]; then
        PS1+="$Red \342\234\226 (${EXIT})"
    else
        PS1+="$Gre \342\234\224"
    fi
    PS1+="$RCol\n> "
}

Which can be simplified as the following in .bashrc:

function j(){
    jobs | wc -l | egrep -v ^0 | sed -r 's/^([0-9]+)/ (\1)/'
}

PS1='\u$(j) > ' # Note the single quote here

Which behaves as follow:

padawin > vim

[1]+  Stopped                 vim
padawin (1) > fg
vim
padawin > 
like image 148
padawin Avatar answered Mar 02 '26 21:03

padawin


Not directly a solution but this might help: if you want to know where the __git_ps1 function lives locally on your filesystem so you can experiment with making edits, you can do

grep -r __git_ps1 /

which searches for the string '__git_ps1' across the file contents of git bash's entire filesystem (where / is actually C:\Program Files\Git or wherever you have it installed).

For me, it was at /mingw64/share/git/completion/git-prompt.sh

My use case was removing the parenthesis from the branch name, which I did by changing this line:

local printf_format=' (%s)'

in the __git_ps1 () function

like image 22
Eric Pedley Avatar answered Mar 02 '26 23:03

Eric Pedley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!