0

I have limited experience with BASH and I am looking for some guidance about how to proceed so please bear with me.

I am trying to change the command prompt when I am inside a git repo, which I can do using this post I found on google, but I also would like to add color depending on the current state of the repo (clean, untracked files, modified files).

Currently I have this at the end of my .bashrc file:

parse_git_branch () {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1]/'
}

modified () {
  git status 2> /dev/null | grep -q modified
}

untracked () {
  git status 2> /dev/null | grep -q Untracked
}

clean () {
  git status 2> /dev/null | grep -q clean
}

NO_COLOR="\[\033[0m\]"
GREEN="\[\033[0;32m\]"
YELLOW="\[\033[0;33m\]"
RED="\[\033[0;31m\]"

set_color () {

  if untracked ; then
    echo $RED
  elif modified ; then
    echo $YELLOW
  elif clean ; then
    echo $GREEN
  else
    echo $NO_COLOR
  fi
}

PS1="\u:\w\$(set_color)\$(parse_git_branch)$NO_COLOR> "

The command prompt changes but does not change the color like I think it should.

Here is what I get instead:
outside git repo arod:~\[\033[0m\]>
inside a git repo arod:~/tos\[\033[0;32m\][dev]>

I am unsure how to get the color to evaluate I think, just looking for some guidance from someone with more BASH experience than I have.

  • Example: `echo -e "\033[31m Hello World"` . Check this link :http://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux – Noproblem Nov 04 '15 at 05:57
  • This was the solution that I was looking for. Thanks – Anthony Rodriguez Nov 05 '15 at 04:33
  • Better to use `printf` (defined by POSIX) than `echo -e` (which bash actually violates the standard by implementing in any way other than having it print `-e` to output). – Charles Duffy Nov 05 '15 at 04:52
  • See `printf '%b' "$color"` -- though hardcoding colors is itself bad form; different terminal types can have different codes for setting colors; the right way to do it is to get codes appropriate to your current terminal with `tput`. – Charles Duffy Nov 05 '15 at 04:54
  • See BashFAQ #37: http://mywiki.wooledge.org/BashFAQ/037 – Charles Duffy Nov 05 '15 at 04:54
  • ...also, calling `git status` three times to print just one prompt is wildly inefficient. Consider calling it only once and reusing the result. For instance: `case "$(git status 2>/dev/null)" in *Untracked*) printf '%b' "$RED" ;; *modified*) printf '%b' "$YELLOW" ;; *clean*) printf '%b' "$GREEN"; *) printf '%b' "$NO_COLOR";; esac` -- only calls `git status` once, but compares its values against all four possibilities – Charles Duffy Nov 05 '15 at 04:55
  • ...moreover, using built-in pattern matching in the shell is far more efficient than `grep`. – Charles Duffy Nov 05 '15 at 04:56
  • ...also, as a matter of convention, consider using lower-case variable names; as described at http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html (fourth paragraph), all-uppercase names are reserved for system-impacting environment variable use. Since environment variables and shell variables share a namespace, the convention applies here too. – Charles Duffy Nov 05 '15 at 04:57

1 Answers1

0

If anyone is looking for an answer; or at least the solution that I used:

parse_git_branch () {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1]/'
}

modified () {
  git status 2> /dev/null | grep -q modified
}

untracked () {
  git status 2> /dev/null | grep -q Untracked
}

clean () {
  git status 2> /dev/null | grep -q clean
}

NO_COLOR="\033[0m"
GREEN="\033[0;32m"
YELLOW="\033[0;33m"
RED="\033[0;31m"

set_color () {

  if untracked ; then
    echo -e $RED
  elif modified ; then
    echo -e $YELLOW
  elif clean ; then
    echo -e $GREEN
  else
    echo -e $NO_COLOR
  fi
}

PS1="\u:\w\$(set_color)\$(parse_git_branch)$NO_COLOR> "

The main difference between the code in the question and this one is that I did add the -e flag to echo, and removed the \'s from the color variables.

Hope this helps someone

EDIT

After receiving a bit more feedback, here is what this looks like now:

parse_git_branch () {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1]/'
}

no_color="\033[0m"
green="\033[0;32m"
yellow="\033[0;33m"
red="\033[0;31m"

set_color () {

  case "$(git status 2> /dev/null)" in
    *Untracked*)
      printf '%b' "$red";;
    *modified*)
      printf '%b' "$yellow";;
    *clean*)
      printf '%b' "$green";;
    *)
      printf '%b' "$no_color";;
  esac

}

PS1="\u:\w\$(set_color)\$(parse_git_branch)$no_color> "

All of this came from @Charles Duffy.
The only thing I did not incorporate was using tput to get the color escape sequences.