Created
March 11, 2020 09:20
-
-
Save harisund/44eb3b7f1ffe8b6a8718fc5c8b2119bd to your computer and use it in GitHub Desktop.
better bash prompt for git repos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Colors | |
RED="\[\033[0;31m\]" | |
YELLOW="\[\033[0;33m\]" | |
BLUE="\[\033[0;34m\]" | |
LIGHT_RED="\[\033[1;31m\]" | |
LIGHT_GREEN="\[\033[1;32m\]" | |
WHITE="\[\033[1;37m\]" | |
LIGHT_GRAY="\[\033[0;37m\]" | |
COLOR_NONE="\[\e[0m\]" | |
# Used by GIT and SVN for clean directories | |
GREEN="\[\033[0;32m\]" | |
# Used by SVN for modified files | |
# Used by GIT for files tracked, modified but not staged. | |
YELLOW="\[\033[0;33m\]" | |
# Used by GIT for staged, but modified. Shouldn't normally see this, the way I work. | |
CYAN="\[\033[0;36m\]" | |
# Used by GIT and SVN for unrevisioned / untracked files | |
RED="\[\033[0;31m\]" | |
function is_git_repo { | |
git branch > /dev/null 2>&1 | |
} | |
function set_git_branch { | |
# Capture the output of the "git status" command. | |
git_status="$(git status 2>&1)" | |
# Set color based on clean/staged/dirty. | |
if [[ ${git_status} =~ "working directory clean" ]]; then | |
state="${GREEN}" | |
elif [[ ${git_status} =~ "working tree clean" ]]; then | |
state="${GREEN}" | |
elif [[ ${git_status} =~ "Changes to be committed" ]]; then | |
state="${YELLOW}" | |
elif [[ ${git_status} =~ "fatal: this operation" ]]; then | |
state="${BLUE}" | |
else | |
state="${RED}" | |
fi | |
# Set arrow icon based on status against remote. | |
ahead_pattern="Your branch is ahead of" | |
behind_pattern="Your branch is behind" | |
diverge_pattern="Your branch and (.*) have diverged" | |
if [[ ${git_status} =~ ${ahead_pattern} ]]; then | |
compared_to_remote="↑" | |
elif [[ ${git_status} =~ ${behind_pattern} ]]; then | |
compared_to_remote="↓" | |
elif [[ ${git_status} =~ ${diverge_pattern} ]]; then | |
compared_to_remote="↕" | |
else | |
compared_to_remote="" | |
fi | |
# Get the name of the branch. | |
branch_pattern="On branch ([^${IFS}]*)" | |
if [[ ${git_status} =~ ${branch_pattern} ]]; then | |
branch=${BASH_REMATCH[1]} | |
else | |
detached_pattern="HEAD detached at ([^${IFS}]*)" | |
if [[ ${git_status} =~ ${detached_pattern} ]]; then | |
branch=${BASH_REMATCH[1]} | |
else | |
branch="no branch" | |
fi | |
fi | |
# Get Current branch. If no branch, warn about detached HEAD | |
#cur_branch=$(git rev-parse --abbrev-ref HEAD) | |
#[[ ${cur_branch} == "HEAD" ]] || branch=${cur_branch} &&\ | |
# branch="DETACHED: $(git rev-parse --short HEAD)" | |
# Are we in a submodule? | |
dotgit="$(git rev-parse --show-toplevel)/.git" | |
[[ -f "${dotgit}" ]] && sub="<sub>" || sub="" | |
# Set the final branch string that gets used in the caller function | |
GITPROMPT="${state}(${branch})${sub}${compared_to_remote}${COLOR_NONE} " | |
} | |
# Return the prompt symbol to use, colorized based on the return value of the | |
# previous command. | |
function set_prompt_symbol () { | |
if test $1 -eq 0 ; then | |
PROMPT_SYMBOL="\$" | |
else | |
PROMPT_SYMBOL="${RED}\$${COLOR_NONE}" | |
fi | |
} | |
# Set the full bash prompt. | |
function set_bash_prompt () { | |
#{{{ | |
# Set the PROMPT_SYMBOL variable. We do this first so we don't lose the | |
# return value of the last command. | |
set_prompt_symbol $? | |
# Set the GITPROMPT variable. | |
GITPROMPT="" | |
PS1="[\u@${HH}][\w] ${GITPROMPT}${PROMPT_SYMBOL}\n$ " | |
if is_git_repo ; then | |
set_git_branch | |
fi | |
# Set the bash prompt variable. | |
PS1="[\u@${HH}][\w] ${GITPROMPT}${PROMPT_SYMBOL}\n$ " | |
} | |
#}}} | |
PROMPT_COMMAND=set_bash_prompt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment