0

I shortened my bash prompt (using the code at line 120 in my bashrc):

PS1='\u:\W\$ '

Now I wanna add the colored git branch to the shortened prompt, so that when the branch has uncommitted changes, it's shown in red and if the working directory is clean (nothing to commit) then the branch is showed in green.

Thank you!

0

This Github Gist by srguiwiz shows a prompt with colours based on branch status:

# http://henrik.nyh.se/2008/12/git-dirty-prompt
# http://www.simplisticcomplexity.com/2008/03/13/show-your-git-branch-name-in-your-prompt/
#   username@Machine ~/dev/dir [master]$   # clean working directory green
#   username@Machine ~/dev/dir [master*]$  # dirty working directory red*
#
function git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}
# http://unix.stackexchange.com/questions/88307/escape-sequences-with-echo-e-in-different-shells
function markup_git_branch {
  if [[ "x$1" = "x" ]]; then
    echo -e "[$1]"
  else
    if [[ $(git status 2> /dev/null | tail -n1) = "nothing to commit, working directory clean" ]]; then
      echo -e '\033[1;32m['"$1"']\033[0;0m'
    else
      echo -e '\033[1;31m['"$1"'*]\033[0;0m'
    fi
  fi
}
export PS1='\u@\h \[\033[0;34m\]\w\[\033[0m\] $(markup_git_branch $(git_branch))$ '

You only need to use $(markup_git_branch $(git_branch)) in your prompt, wherever you want show the commit status and branch.

There's a slight change to original code here: the \033[0;30m at the end should be \033[0;0m to reset the prompt colour. The former sets it black, the latter resets formatting on the text.

srguiwiz's code seems to have some problems, jcgoble3 made a better version:

# Adds the current branch to the bash prompt when the working directory is
# part of a Git repository. Includes color-coding and indicators to quickly
# indicate the status of working directory.
#
# To use: Copy into ~/.bashrc and tweak if desired.
#
# Based upon the following gists:
# <https://gist.github.com/henrik/31631>
# <https://gist.github.com/srguiwiz/de87bf6355717f0eede5>
# Modified by me, using ideas from comments on those gists.
#
# License: MIT, unless the authors of those two gists object :)

git_branch() {
    # -- Finds and outputs the current branch name by parsing the list of
    #    all branches
    # -- Current branch is identified by an asterisk at the beginning
    # -- If not in a Git repository, error message goes to /dev/null and
    #    no output is produced
    git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}

git_status() {
    # Outputs a series of indicators based on the status of the
    # working directory:
    # + changes are staged and ready to commit
    # ! unstaged changes are present
    # ? untracked files are present
    # S changes have been stashed
    # P local commits need to be pushed to the remote
    local status="$(git status --porcelain 2>/dev/null)"
    local output=''
    [[ -n $(egrep '^[MADRC]' <<<"$status") ]] && output="$output+"
    [[ -n $(egrep '^.[MD]' <<<"$status") ]] && output="$output!"
    [[ -n $(egrep '^\?\?' <<<"$status") ]] && output="$output?"
    [[ -n $(git stash list) ]] && output="${output}S"
    [[ -n $(git log --branches --not --remotes) ]] && output="${output}P"
    [[ -n $output ]] && output="|$output"  # separate from branch name
    echo $output
}

git_color() {
    # Receives output of git_status as argument; produces appropriate color
    # code based on status of working directory:
    # - White if everything is clean
    # - Green if all changes are staged
    # - Red if there are uncommitted changes with nothing staged
    # - Yellow if there are both staged and unstaged changes
    local staged=$([[ $1 =~ \+ ]] && echo yes)
    local dirty=$([[ $1 =~ [!\?] ]] && echo yes)
    if [[ -n $staged ]] && [[ -n $dirty ]]; then
        echo -e '\033[1;33m'  # bold yellow
    elif [[ -n $staged ]]; then
        echo -e '\033[1;32m'  # bold green
    elif [[ -n $dirty ]]; then
        echo -e '\033[1;31m'  # bold red
    else
        echo -e '\033[1;37m'  # bold white
    fi
}

git_prompt() {
    # First, get the branch name...
    local branch=$(git_branch)
    # Empty output? Then we're not in a Git repository, so bypass the rest
    # of the function, producing no output
    if [[ -n $branch ]]; then
        local state=$(git_status)
        local color=$(git_color $state)
        # Now output the actual code to insert the branch and status
        echo -e "\x01$color\x02[$branch$state]\x01\033[00m\x02"  # last bit resets color
    fi
}

# Sample prompt declaration based off of the default Ubuntu 14.04.1 color
# prompt. Tweak as you see fit, or just stick "$(git_prompt)" into your
# favorite prompt.
PS1='$debian_chroot\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w$(git_prompt)\[\033[00m\]\$ '
  • Would you please look at the pastebin gist I provided and tell me on which line should I paste it? I'm completely new to playing with Bash. – Indu Pillai Nov 20 '16 at 4:06
  • Just add this at the bottom. BTW, there's another (better) version at github.com/jcgoble3/gitstuff/blob/master/gitprompt.sh. In either case you can just add the contents at the bottom of your .bashrc and change the PS1 to suit your needs. – muru Nov 20 '16 at 4:10
0

I wrote something like this for myself. It relies on __git_ps1 from /usr/lib/git-core/git-sh-prompt, so you may need to source /usr/lib/git-core/git-sh-prompt if your shell isn't already set to do that.

_prompt_git_branch(){
    # Print git branch in color, for use in Bash PS1 or PROMPT_COMMAND.
    #   Red: untracked files
    #   Yellow: unstaged changes
    #   Blue: staged changes
    #   Cyan: nothing to commit, working directory clean

    local bold=1  # Change to 21 for not bold
    local color
    local status

    GIT_PS1_SHOWDIRTYSTATE=1
    GIT_PS1_SHOWSTASHSTATE=1
    GIT_PS1_SHOWUNTRACKEDFILES=1

    status="$(__git_ps1)"

    case $status in
    '')
        # Not in a git repo
        return
        ;;
    *'%'*)
        # Untracked files
        color=1  # red
        ;;
    *'*'*)
        # Unstaged changes
        color=3  # yellow
        ;;
    *'+'*)
        # Staged changes
        color=4  # blue
        ;;
    *)
        # Otherwise
        color=6  # cyan
        ;;
    esac

    printf '\e[%d;3%dm%s\e[m' "$bold" "$color" "$status"
}

Then for setting the PS1 in the bashrc, I would actually remove line 120 and edit lines 60 and 62 instead.

line 60 (color):

PS1='${debian_chroot:+($debian_chroot)}\[\e[1;32m\]\u\[\e[m\]:\[\e[1;34m\]\W\[\e[m\]$(_prompt_git_branch)\$ '

line 62 (no color):

PS1='${debian_chroot:+($debian_chroot)}\u:\W$(__git_ps1)\$ '

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.