2020-05-10 15:58:05 +02:00
|
|
|
# Simple Bash prompt with Git status.
|
|
|
|
|
|
|
|
# Source gitstatus.plugin.sh from $GITSTATUS_DIR or from the same directory
|
|
|
|
# in which the current script resides if the variable isn't set.
|
2023-08-15 10:30:02 +02:00
|
|
|
if [[ -n "${GITSTATUS_DIR-}" ]]; then
|
2020-05-10 15:58:05 +02:00
|
|
|
source "$GITSTATUS_DIR" || return
|
|
|
|
elif [[ "${BASH_SOURCE[0]}" == */* ]]; then
|
|
|
|
source "${BASH_SOURCE[0]%/*}/gitstatus.plugin.sh" || return
|
|
|
|
else
|
|
|
|
source gitstatus.plugin.sh || return
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Sets GITSTATUS_PROMPT to reflect the state of the current git repository.
|
|
|
|
# The value is empty if not in a git repository. Forwards all arguments to
|
|
|
|
# gitstatus_query.
|
|
|
|
#
|
|
|
|
# Example value of GITSTATUS_PROMPT: master ⇣42⇡42 ⇠42⇢42 *42 merge ~42 +42 !42 ?42
|
|
|
|
#
|
|
|
|
# master current branch
|
|
|
|
# ⇣42 local branch is 42 commits behind the remote
|
|
|
|
# ⇡42 local branch is 42 commits ahead of the remote
|
|
|
|
# ⇠42 local branch is 42 commits behind the push remote
|
|
|
|
# ⇢42 local branch is 42 commits ahead of the push remote
|
|
|
|
# *42 42 stashes
|
|
|
|
# merge merge in progress
|
|
|
|
# ~42 42 merge conflicts
|
|
|
|
# +42 42 staged changes
|
|
|
|
# !42 42 unstaged changes
|
|
|
|
# ?42 42 untracked files
|
|
|
|
function gitstatus_prompt_update() {
|
|
|
|
GITSTATUS_PROMPT=""
|
|
|
|
|
|
|
|
gitstatus_query "$@" || return 1 # error
|
|
|
|
[[ "$VCS_STATUS_RESULT" == ok-sync ]] || return 0 # not a git repo
|
|
|
|
|
2021-07-02 11:02:41 +02:00
|
|
|
local reset=$'\001\e[0m\002' # no color
|
|
|
|
local clean=$'\001\e[38;5;076m\002' # green foreground
|
|
|
|
local untracked=$'\001\e[38;5;014m\002' # teal foreground
|
|
|
|
local modified=$'\001\e[38;5;011m\002' # yellow foreground
|
|
|
|
local conflicted=$'\001\e[38;5;196m\002' # red foreground
|
2020-05-10 15:58:05 +02:00
|
|
|
|
|
|
|
local p
|
|
|
|
|
|
|
|
local where # branch name, tag or commit
|
|
|
|
if [[ -n "$VCS_STATUS_LOCAL_BRANCH" ]]; then
|
|
|
|
where="$VCS_STATUS_LOCAL_BRANCH"
|
|
|
|
elif [[ -n "$VCS_STATUS_TAG" ]]; then
|
|
|
|
p+="${reset}#"
|
|
|
|
where="$VCS_STATUS_TAG"
|
|
|
|
else
|
|
|
|
p+="${reset}@"
|
|
|
|
where="${VCS_STATUS_COMMIT:0:8}"
|
|
|
|
fi
|
|
|
|
|
|
|
|
(( ${#where} > 32 )) && where="${where:0:12}…${where: -12}" # truncate long branch names and tags
|
|
|
|
p+="${clean}${where}"
|
|
|
|
|
|
|
|
# ⇣42 if behind the remote.
|
|
|
|
(( VCS_STATUS_COMMITS_BEHIND )) && p+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}"
|
|
|
|
# ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42.
|
|
|
|
(( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && p+=" "
|
|
|
|
(( VCS_STATUS_COMMITS_AHEAD )) && p+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}"
|
|
|
|
# ⇠42 if behind the push remote.
|
|
|
|
(( VCS_STATUS_PUSH_COMMITS_BEHIND )) && p+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}"
|
|
|
|
(( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && p+=" "
|
|
|
|
# ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42.
|
|
|
|
(( VCS_STATUS_PUSH_COMMITS_AHEAD )) && p+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}"
|
|
|
|
# *42 if have stashes.
|
|
|
|
(( VCS_STATUS_STASHES )) && p+=" ${clean}*${VCS_STATUS_STASHES}"
|
|
|
|
# 'merge' if the repo is in an unusual state.
|
|
|
|
[[ -n "$VCS_STATUS_ACTION" ]] && p+=" ${conflicted}${VCS_STATUS_ACTION}"
|
|
|
|
# ~42 if have merge conflicts.
|
|
|
|
(( VCS_STATUS_NUM_CONFLICTED )) && p+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}"
|
|
|
|
# +42 if have staged changes.
|
|
|
|
(( VCS_STATUS_NUM_STAGED )) && p+=" ${modified}+${VCS_STATUS_NUM_STAGED}"
|
|
|
|
# !42 if have unstaged changes.
|
|
|
|
(( VCS_STATUS_NUM_UNSTAGED )) && p+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}"
|
|
|
|
# ?42 if have untracked files. It's really a question mark, your font isn't broken.
|
|
|
|
(( VCS_STATUS_NUM_UNTRACKED )) && p+=" ${untracked}?${VCS_STATUS_NUM_UNTRACKED}"
|
|
|
|
|
|
|
|
GITSTATUS_PROMPT="${p}${reset}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Start gitstatusd in the background.
|
|
|
|
gitstatus_stop && gitstatus_start -s -1 -u -1 -c -1 -d -1
|
|
|
|
|
|
|
|
# On every prompt, fetch git status and set GITSTATUS_PROMPT.
|
2023-08-15 10:30:02 +02:00
|
|
|
if [[ -z "${PROMPT_COMMAND[*]}" ]]; then
|
|
|
|
PROMPT_COMMAND=gitstatus_prompt_update
|
|
|
|
elif [[ ! "${PROMPT_COMMAND[*]}" =~ [[:space:]\;]?gitstatus_prompt_update[[:space:]\;]? ]]; then
|
|
|
|
# Note: If PROMPT_COMMAND is an array, this will modify its first element.
|
|
|
|
PROMPT_COMMAND=$'gitstatus_prompt_update\n'"$PROMPT_COMMAND"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Retain 3 trailing components of the current directory.
|
2021-08-18 17:05:04 +02:00
|
|
|
PROMPT_DIRTRIM=3
|
2020-05-10 15:58:05 +02:00
|
|
|
|
|
|
|
# Enable promptvars so that ${GITSTATUS_PROMPT} in PS1 is expanded.
|
|
|
|
shopt -s promptvars
|
|
|
|
|
|
|
|
# Customize prompt. Put $GITSTATUS_PROMPT in it reflect git status.
|
|
|
|
#
|
|
|
|
# Example:
|
|
|
|
#
|
2020-06-14 10:29:29 +02:00
|
|
|
# user@host ~/projects/skynet master ⇡42
|
2020-05-10 15:58:05 +02:00
|
|
|
# $ █
|
|
|
|
PS1='\[\033[01;32m\]\u@\h\[\033[00m\] ' # green user@host
|
|
|
|
PS1+='\[\033[01;34m\]\w\[\033[00m\]' # blue current working directory
|
|
|
|
PS1+='${GITSTATUS_PROMPT:+ $GITSTATUS_PROMPT}' # git status (requires promptvars option)
|
|
|
|
PS1+='\n\[\033[01;$((31+!$?))m\]\$\[\033[00m\] ' # green/red (success/error) $/# (normal/root)
|
|
|
|
PS1+='\[\e]0;\u@\h: \w\a\]' # terminal title: user@host: dir
|