From 83fdc89ec194960a0ce72b2f4080614fcfe1a31a Mon Sep 17 00:00:00 2001 From: Markus Krause Date: Sun, 6 Oct 2019 12:33:12 +0200 Subject: [PATCH] implement gitstatusd support --- bash_it.sh | 7 +++ template/bash_profile.template.bash | 6 +++ themes/base.theme.bash | 35 ++++++++++-- themes/githelpers.theme.bash | 84 +++++++++++++++++++++-------- 4 files changed, 105 insertions(+), 27 deletions(-) diff --git a/bash_it.sh b/bash_it.sh index ab911019..e09c3ba7 100755 --- a/bash_it.sh +++ b/bash_it.sh @@ -121,5 +121,12 @@ if ! command -v reload &>/dev/null && [ -n "$BASH_IT_RELOAD_LEGACY" ]; then esac fi +# If gitstatusd is requested for the current shell, launch it if the shell is interactive +if [[ "${SCM_GIT_USE_GITSTATUSD}" == "true" ]] && [[ "$SCM_CHECK" == "true" ]] && [[ $- == *i* ]]; then + test -z "${SCM_GIT_GITSTATUSD_LOC}" || SCM_GIT_GITSTATUSD_LOC="$HOME/gitstatus/gitstatus.plugin.sh" + source "${SCM_GIT_GITSTATUSD_LOC}" + gitstatus_stop && gitstatus_start -s -1 -u -1 -c -1 -d -1 +fi + # Disable trap DEBUG on subshells - https://github.com/Bash-it/bash-it/pull/1040 set +T diff --git a/template/bash_profile.template.bash b/template/bash_profile.template.bash index e7f92dd3..9e9e6b9d 100755 --- a/template/bash_profile.template.bash +++ b/template/bash_profile.template.bash @@ -32,6 +32,12 @@ export TODO="t" # Set this to false to turn off version control status checking within the prompt for all themes export SCM_CHECK=true +# when using Git, consider installing https://github.com/romkatv/gitstatus for faster status prompt +# enable it here if you wish, change the LOC variable if you did not choose the standard location in your home +#export SCM_GIT_USE_GITSTATUSD=true +#export SCM_GIT_GITSTATUSD_LOC="$HOME/gitstatus/gitstatus.plugin.sh" +# per default gitstatusd uses 2 times as many threads as CPU cores, you can change this here if you must +#export GITSTATUS_NUM_THREADS=8 # Set Xterm/screen/Tmux title with only a short hostname. # Uncomment this (or set SHORT_HOSTNAME to something else), diff --git a/themes/base.theme.bash b/themes/base.theme.bash index 97bbee45..f92bd268 100644 --- a/themes/base.theme.bash +++ b/themes/base.theme.bash @@ -34,6 +34,8 @@ SCM_GIT_SHOW_CURRENT_USER=${SCM_GIT_SHOW_CURRENT_USER:=false} SCM_GIT_SHOW_MINIMAL_INFO=${SCM_GIT_SHOW_MINIMAL_INFO:=false} SCM_GIT_SHOW_STASH_INFO=${SCM_GIT_SHOW_STASH_INFO:=true} SCM_GIT_SHOW_COMMIT_COUNT=${SCM_GIT_SHOW_COMMIT_COUNT:=true} +SCM_GIT_USE_GITSTATUSD=${SCM_GIT_USE_GITSTATUSD:=false} +SCM_GIT_GITSTATUSD_LOC=${SCM_GIT_GITSTATUSD_LOC:="$HOME/gitstatus/gitstatus.plugin.sh"} SCM_GIT='git' SCM_GIT_CHAR='±' @@ -191,6 +193,15 @@ function git_prompt_minimal_info { } function git_prompt_vars { + if ${SCM_GIT_USE_GITSTATUSD}; then # use faster gitstatusd + gitstatus_query # call gitstatusd + if [[ -z ${VCS_STATUS_WORKDIR} ]] ; then # this var is guaranteed to exist if query was successful + SCM_GIT_GITSTATUSD_RAN=false + else + SCM_GIT_GITSTATUSD_RAN=true # use this in githelpers and below to choose gitstatusd output + fi + fi + if _git-branch &> /dev/null; then SCM_GIT_DETACHED="false" SCM_BRANCH="${SCM_THEME_BRANCH_PREFIX}\$(_git-friendly-ref)$(_git-remote-info)" @@ -206,7 +217,12 @@ function git_prompt_vars { SCM_BRANCH="${detached_prefix}\$(_git-friendly-ref)" fi - IFS=$'\t' read -r commits_behind commits_ahead <<< "$(_git-upstream-behind-ahead)" + if [[ "${SCM_GIT_GITSTATUSD_RAN}" == "true" ]]; then + commits_behind=${VCS_STATUS_COMMITS_BEHIND} + commits_ahead=${VCS_STATUS_COMMITS_AHEAD} + else + IFS=$'\t' read -r commits_behind commits_ahead <<< "$(_git-upstream-behind-ahead)" + fi if [[ "${commits_ahead}" -gt 0 ]]; then SCM_BRANCH+="${SCM_GIT_AHEAD_BEHIND_PREFIX_CHAR}${SCM_GIT_AHEAD_CHAR}" [[ "${SCM_GIT_SHOW_COMMIT_COUNT}" = "true" ]] && SCM_BRANCH+="${commits_ahead}" @@ -218,13 +234,23 @@ function git_prompt_vars { if [[ "${SCM_GIT_SHOW_STASH_INFO}" = "true" ]]; then local stash_count - stash_count="$(git stash list 2> /dev/null | wc -l | tr -d ' ')" + if [[ "${SCM_GIT_GITSTATUSD_RAN}" == "true" ]]; then + stash_count=${VCS_STATUS_STASHES} + else + stash_count="$(git stash list 2> /dev/null | wc -l | tr -d ' ')" + fi [[ "${stash_count}" -gt 0 ]] && SCM_BRANCH+=" ${SCM_GIT_STASH_CHAR_PREFIX}${stash_count}${SCM_GIT_STASH_CHAR_SUFFIX}" fi SCM_STATE=${GIT_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} if ! _git-hide-status; then - IFS=$'\t' read -r untracked_count unstaged_count staged_count <<< "$(_git-status-counts)" + if [[ "${SCM_GIT_GITSTATUSD_RAN}" == "true" ]]; then + untracked_count=${VCS_STATUS_NUM_UNTRACKED} + unstaged_count=${VCS_STATUS_NUM_UNSTAGED} + staged_count=${VCS_STATUS_NUM_STAGED} + else + IFS=$'\t' read -r untracked_count unstaged_count staged_count <<< "$(_git-status-counts)" + fi if [[ "${untracked_count}" -gt 0 || "${unstaged_count}" -gt 0 || "${staged_count}" -gt 0 ]]; then SCM_DIRTY=1 if [[ "${SCM_GIT_SHOW_DETAILS}" = "true" ]]; then @@ -236,12 +262,13 @@ function git_prompt_vars { fi fi + # no if for gitstatusd here, user extraction is not supported by it [[ "${SCM_GIT_SHOW_CURRENT_USER}" == "true" ]] && SCM_BRANCH+="$(git_user_info)" SCM_PREFIX=${GIT_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} SCM_SUFFIX=${GIT_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} - SCM_CHANGE=$(_git-short-sha 2>/dev/null || echo "") + } function p4_prompt_vars { diff --git a/themes/githelpers.theme.bash b/themes/githelpers.theme.bash index 24c4b1f4..c31e1ff5 100644 --- a/themes/githelpers.theme.bash +++ b/themes/githelpers.theme.bash @@ -9,11 +9,19 @@ function _git-symbolic-ref { # same commit. _git-branch is used to explicitly choose the checked-out # branch. function _git-branch { - git symbolic-ref -q --short HEAD 2> /dev/null || return 1 + if [[ "${SCM_GIT_GITSTATUSD_RAN}" == "true" ]]; then + test -n "${VCS_STATUS_LOCAL_BRANCH}" && echo "${VCS_STATUS_LOCAL_BRANCH}" || return 1 + else + git symbolic-ref -q --short HEAD 2> /dev/null || return 1 + fi } function _git-tag { - git describe --tags --exact-match 2> /dev/null + if [[ "${SCM_GIT_GITSTATUSD_RAN}" == "true" ]]; then + test -n "${VCS_STATUS_TAG}" && echo "${VCS_STATUS_TAG}" + else + git describe --tags --exact-match 2> /dev/null + fi } function _git-commit-description { @@ -21,12 +29,20 @@ function _git-commit-description { } function _git-short-sha { - git rev-parse --short HEAD + if [[ "${SCM_GIT_GITSTATUSD_RAN}" == "true" ]]; then + echo ${VCS_STATUS_COMMIT:0:7} + else + git rev-parse --short HEAD + fi } # Try the checked-out branch first to avoid collision with branches pointing to the same ref. function _git-friendly-ref { + if [[ "${SCM_GIT_GITSTATUSD_RAN}" == "true" ]]; then + _git-branch || _git-tag || _git-short-sha # there is no tag based describe output in gitstatusd + else _git-branch || _git-tag || _git-commit-description || _git-short-sha + fi } function _git-num-remotes { @@ -101,29 +117,51 @@ function _git-status-counts { } function _git-remote-info { - [[ "$(_git-upstream)" == "" ]] && return || true - [[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && local same_branch_name=true || true - local same_branch_name= - [[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && same_branch_name=true - if ([[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "auto" ]] && [[ "$(_git-num-remotes)" -ge 2 ]]) || - [[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "true" ]]; then - if [[ "${same_branch_name}" != "true" ]]; then - remote_info="\$(_git-upstream)" - else - remote_info="$(_git-upstream-remote)" + if [[ "${SCM_GIT_GITSTATUSD_RAN}" == "true" ]]; then # prompt handling only, reimplement because patching the routine below gets ugly + [[ "${VCS_STATUS_REMOTE_NAME}" == "" ]] && return || true + [[ "${VCS_STATUS_LOCAL_BRANCH}" == "${VCS_STATUS_REMOTE_BRANCH}" ]] && local same_branch_name=true || true + local same_branch_name= + [[ "${VCS_STATUS_LOCAL_BRANCH}" == "${VCS_STATUS_REMOTE_BRANCH}" ]] && same_branch_name=true + if [[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "true" ]] || [[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "auto" ]]; then # no multiple remote support in gitstatusd + if [[ "${same_branch_name}" != "true" ]]; then + remote_info="\${VCS_STATUS_REMOTE_NAME}" + else + remote_info="${VCS_STATUS_REMOTE_NAME}/${VCS_STATUS_REMOTE_BRANCH}" + fi + elif [[ ${same_branch_name} != "true" ]]; then + remote_info="\${VCS_STATUS_REMOTE_BRANCH}" fi - elif [[ ${same_branch_name} != "true" ]]; then - remote_info="\$(_git-upstream-branch)" - fi - if [[ -n "${remote_info}" ]];then - local branch_prefix - if _git-upstream-branch-gone; then - branch_prefix="${SCM_THEME_BRANCH_GONE_PREFIX}" - else - branch_prefix="${SCM_THEME_BRANCH_TRACK_PREFIX}" + if [[ -n "${remote_info}" ]];then + local branch_prefix + branch_prefix="${SCM_THEME_BRANCH_TRACK_PREFIX}" # no support for gone remote branches in gitstatusd + echo "${branch_prefix}${remote_info}" + fi + else + [[ "$(_git-upstream)" == "" ]] && return || true + + [[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && local same_branch_name=true || true + local same_branch_name= + [[ "$(_git-branch)" == "$(_git-upstream-branch)" ]] && same_branch_name=true + if ([[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "auto" ]] && [[ "$(_git-num-remotes)" -ge 2 ]]) || + [[ "${SCM_GIT_SHOW_REMOTE_INFO}" = "true" ]]; then + if [[ "${same_branch_name}" != "true" ]]; then + remote_info="\$(_git-upstream)" + else + remote_info="$(_git-upstream-remote)" + fi + elif [[ ${same_branch_name} != "true" ]]; then + remote_info="\$(_git-upstream-branch)" + fi + if [[ -n "${remote_info}" ]];then + local branch_prefix + if _git-upstream-branch-gone; then + branch_prefix="${SCM_THEME_BRANCH_GONE_PREFIX}" + else + branch_prefix="${SCM_THEME_BRANCH_TRACK_PREFIX}" + fi + echo "${branch_prefix}${remote_info}" fi - echo "${branch_prefix}${remote_info}" fi }