Bash – __git_ps1 (current branch) in bash prompt is always out of date somehow

bashprompt

My PS1 in my ~/.bash_profile:

export PS1="\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]`__git_ps1`\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "

(sorry, I don't have any aliases for my color codes, I created this prompt with an online editor)

Which is a bit messy but produces a very nice prompt: enter image description here

But the current branch displayed is always wrong if I switch

wrong branch

I'm not sure why this would happen. If I run the command by itself, I get the correct value.

$ echo `__git_ps1`
(dev)

If I source the .bash_profile the new value will come in (but will be wrong next time I switch). Am I doing something wrong?

Best Answer

export PS1="…`__git_ps1`…"

With `__git_ps1` inside double quotes, this command runs the command __git_ps1 and assigns its output (and other surrounding text) to the variable PS1. Thus your prompt is showing the branch that was determined when your .bash_profile was executed.

You need to run __git_ps1 each time bash displays a prompt. (Actually you don't need to run it again until the git information has changed, but that's difficult to detect.) There are two ways to do that.

  • Include the literal text `__git_ps1` in the PS1 variable. Make sure that bash is configured to perform shell expansions on the prompt string, with the promptvars option turned on; that's the case by default but it can be turned off with shopt -u promptvars.

    PS1='\n\[…\]$(__git_ps1)\[…\]\$ '
    
  • Update the prompt content by a command run from the PROMPT_COMMAND variable.

    update_PS1 () {
      PS1="\\n\\[…\\]$(__git_ps1)\[…\]\\$ "
    }
    shopt -u promptvars
    PROMPT_COMMAND=update_PS1
    

By the way, the prompt is a shell configuration, not a global setting, so you should set it in ~/.bashrc, not in ~/.bash_profile.

Related Question