From 47f4aca1f80c9a41833009152fcc52c9360b8a66 Mon Sep 17 00:00:00 2001 From: oGre Date: Tue, 13 Oct 2015 12:53:10 +0200 Subject: [PATCH 1/5] Added environment variable GIT_PROMPT_STATUS_COMMAND that can point out a custom gitstatus.sh script if needed. --- gitstatus_pre-1.7.10.sh | 112 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 gitstatus_pre-1.7.10.sh diff --git a/gitstatus_pre-1.7.10.sh b/gitstatus_pre-1.7.10.sh new file mode 100644 index 0000000..4370288 --- /dev/null +++ b/gitstatus_pre-1.7.10.sh @@ -0,0 +1,112 @@ +#!/bin/bash +# -*- coding: UTF-8 -*- +# gitstatus.sh -- produce the current git repo status on STDOUT +# Functionally equivalent to 'gitstatus.py', but written in bash (not python). +# +# Alan K. Stebbens [http://github.com/aks] + +# helper functions +count_lines() { echo "$1" | egrep -c "^$2" ; } +all_lines() { echo "$1" | grep -v "^$" | wc -l ; } + +if [ -z "${__GIT_PROMPT_DIR}" ]; then + SOURCE="${BASH_SOURCE[0]}" + while [ -h "${SOURCE}" ]; do + DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )" + SOURCE="$(readlink "${SOURCE}")" + [[ $SOURCE != /* ]] && SOURCE="${DIR}/${SOURCE}" + done + __GIT_PROMPT_DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )" +fi + +gitsym=`git symbolic-ref HEAD` + +# if "fatal: Not a git repo .., then exit +case "$gitsym" in fatal*) exit 0 ;; esac + +# the current branch is the tail end of the symbolic reference +branch="${gitsym##refs/heads/}" # get the basename after "refs/heads/" + +gitstatus=`git diff --name-status 2>&1` + +# if the diff is fatal, exit now +case "$gitstatus" in fatal*) exit 0 ;; esac + + +staged_files=`git diff --staged --name-status` + +num_changed=$(( `all_lines "$gitstatus"` - `count_lines "$gitstatus" U` )) +num_conflicts=`count_lines "$staged_files" U` +num_staged=$(( `all_lines "$staged_files"` - num_conflicts )) +num_untracked=`git ls-files --others --exclude-standard $(git rev-parse --show-cdup) | wc -l` +if [[ "$__GIT_PROMPT_IGNORE_STASH" = "1" ]]; then + num_stashed=0 +else + num_stashed=`git stash list | wc -l` +fi + +clean=0 +if (( num_changed == 0 && num_staged == 0 && num_U == 0 && num_untracked == 0 && num_stashed == 0 )) ; then + clean=1 +fi + +remote= + +if [[ -z "$branch" ]]; then + tag=`git describe --exact-match` + if [[ -n "$tag" ]]; then + branch="$tag" + else + branch="_PREHASH_`git rev-parse --short HEAD`" + fi +else + remote_name=`git config branch.${branch}.remote` + + if [[ -n "$remote_name" ]]; then + merge_name=`git config branch.${branch}.merge` + else + remote_name='origin' + merge_name="refs/heads/${branch}" + fi + + if [[ "$remote_name" == '.' ]]; then + remote_ref="$merge_name" + else + remote_ref="refs/remotes/$remote_name/${merge_name##refs/heads/}" + fi + + # detect if the local branch have a remote tracking branch + cmd_output=$(git rev-parse --abbrev-ref ${branch}@{upstream} 2>&1 >/dev/null) + + if [[ $? == 0 ]]; then + has_remote_tracking=1 + else + has_remote_tracking=0 + fi + + # get the revision list, and count the leading "<" and ">" + revgit=`git rev-list --left-right ${remote_ref}...HEAD` + num_revs=`all_lines "$revgit"` + num_ahead=`count_lines "$revgit" "^>"` + num_behind=$(( num_revs - num_ahead )) + if (( num_behind > 0 )) ; then + remote="${remote}_BEHIND_${num_behind}" + fi + if (( num_ahead > 0 )) ; then + remote="${remote}_AHEAD_${num_ahead}" + fi +fi + +if [[ -z "$remote" ]] ; then + remote='.' +fi + +if [[ "$has_remote_tracking" == "0" ]] ; then + remote='_NO_REMOTE_TRACKING_' +fi + +for w in "$branch" "$remote" $num_staged $num_conflicts $num_changed $num_untracked $num_stashed $clean ; do + echo "$w" +done + +exit From 09c98facb69662ab2657ccf0b2a476515ff16672 Mon Sep 17 00:00:00 2001 From: oGre Date: Tue, 13 Oct 2015 12:59:05 +0200 Subject: [PATCH 2/5] Added environment variable GIT_PROMPT_STATUS_COMMAND that can point out a custom gitstatus.sh script if needed. --- gitprompt.sh | 5 ++--- gitstatus_pre-1.7.10.sh | 0 themes/Default.bgptheme | 11 +++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) mode change 100644 => 100755 gitstatus_pre-1.7.10.sh diff --git a/gitprompt.sh b/gitprompt.sh index 5f3a4fe..178c6d1 100755 --- a/gitprompt.sh +++ b/gitprompt.sh @@ -282,8 +282,8 @@ function git_prompt_config() { fi if [[ -z "$__GIT_STATUS_CMD" ]] ; then # if GIT_STATUS_CMD not defined.. git_prompt_dir - if ! gp_maybe_set_envar_to_path __GIT_STATUS_CMD "$__GIT_PROMPT_DIR/gitstatus.sh" ; then - echo 1>&2 "Cannot find gitstatus.sh!" + if ! gp_maybe_set_envar_to_path __GIT_STATUS_CMD "$__GIT_PROMPT_DIR/$GIT_PROMPT_STATUS_COMMAND" ; then + echo 1>&2 "Cannot find $GIT_PROMPT_STATUS_COMMAND!" fi # __GIT_STATUS_CMD defined fi @@ -520,7 +520,6 @@ function gp_add_virtualenv_to_prompt { function is_function { declare -Ff "$1" >/dev/null; } - #Helper function that truncates $PWD depending on window width function gp_truncate_pwd { local newPWD="${PWD/#$HOME/~}" diff --git a/gitstatus_pre-1.7.10.sh b/gitstatus_pre-1.7.10.sh old mode 100644 new mode 100755 diff --git a/themes/Default.bgptheme b/themes/Default.bgptheme index b37b0e3..40c97ec 100644 --- a/themes/Default.bgptheme +++ b/themes/Default.bgptheme @@ -16,6 +16,7 @@ unset_git_prompt_colors() { unset GIT_PROMPT_CLEAN unset GIT_PROMPT_COMMAND_OK unset GIT_PROMPT_COMMAND_FAIL + unset GIT_PROMPT_STATUS_COMMAND unset GIT_PROMPT_VIRTUALENV unset GIT_PROMPT_START_USER unset GIT_PROMPT_START_ROOT @@ -51,7 +52,7 @@ define_undefined_git_prompt_colors() { if [[ -z ${GIT_PROMPT_STASHED} ]]; then GIT_PROMPT_STASHED="${BoldBlue}⚑ "; fi # the number of stashed files/dir if [[ -z ${GIT_PROMPT_CLEAN} ]]; then GIT_PROMPT_CLEAN="${BoldGreen}✔"; fi # a colored flag indicating a "clean" repo - # For the command indicator, the placeholder _LAST_COMMAND_STATE_ + # For the command indicator, the placeholder _LAST_COMMAND_STATE_ # will be replaced with the exit code of the last command # e.g. # GIT_PROMPT_COMMAND_OK="${Green}✔-_LAST_COMMAND_STATE_ " # indicator if the last command returned with an exit code of 0 @@ -60,11 +61,13 @@ define_undefined_git_prompt_colors() { if [[ -z ${GIT_PROMPT_COMMAND_OK} ]]; then GIT_PROMPT_COMMAND_OK="${Green}✔"; fi # indicator if the last command returned with an exit code of 0 if [[ -z ${GIT_PROMPT_COMMAND_FAIL} ]]; then GIT_PROMPT_COMMAND_FAIL="${Red}✘-_LAST_COMMAND_STATE_"; fi # indicator if the last command returned with an exit code of other than 0 + if [[ -z ${GIT_PROMPT_STATUS_COMMAND} ]]; then GIT_PROMPT_STATUS_COMMAND="gitstatus.sh"; fi # Point out the command to get the gitstatus from + # template for displaying the current virtual environment - # use the placeholder _VIRTUALENV_ will be replaced with + # use the placeholder _VIRTUALENV_ will be replaced with # the name of the current virtual environment (currently CONDA and VIRTUAL_ENV) if [[ -z ${GIT_PROMPT_VIRTUALENV} ]]; then GIT_PROMPT_VIRTUALENV="(${Blue}_VIRTUALENV_${ResetColor}) "; fi - + # _LAST_COMMAND_INDICATOR_ will be replaced by the appropriate GIT_PROMPT_COMMAND_OK OR GIT_PROMPT_COMMAND_FAIL if [[ -z ${GIT_PROMPT_START_USER} ]]; then GIT_PROMPT_START_USER="_LAST_COMMAND_INDICATOR_ ${Yellow}${PathShort}${ResetColor}"; fi if [[ -z ${GIT_PROMPT_START_ROOT} ]]; then GIT_PROMPT_START_ROOT="${GIT_PROMPT_START_USER}"; fi @@ -75,7 +78,7 @@ define_undefined_git_prompt_colors() { if [[ -z ${GIT_PROMPT_SYMBOLS_AHEAD} ]]; then GIT_PROMPT_SYMBOLS_AHEAD="↑·"; fi # The symbol for "n versions ahead of origin" if [[ -z ${GIT_PROMPT_SYMBOLS_BEHIND} ]]; then GIT_PROMPT_SYMBOLS_BEHIND="↓·"; fi # The symbol for "n versions behind of origin" if [[ -z ${GIT_PROMPT_SYMBOLS_PREHASH} ]]; then GIT_PROMPT_SYMBOLS_PREHASH=":"; fi # Written before hash of commit, if no name could be found - if [[ -z ${GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING} ]]; then GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING="L"; fi # This symbol is written after the branch, if the branch is not tracked + if [[ -z ${GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING} ]]; then GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING="L"; fi # This symbol is written after the branch, if the branch is not tracked } # call only from theme file From 50ee0e5fc980ab882be52d8d1d951efbb38bb76e Mon Sep 17 00:00:00 2001 From: oGre Date: Tue, 13 Oct 2015 18:24:57 +0200 Subject: [PATCH 3/5] Backported the new way of counting stashed files and the printf function to speed it up --- gitstatus_pre-1.7.10.sh | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/gitstatus_pre-1.7.10.sh b/gitstatus_pre-1.7.10.sh index 4370288..f613709 100755 --- a/gitstatus_pre-1.7.10.sh +++ b/gitstatus_pre-1.7.10.sh @@ -39,10 +39,15 @@ num_changed=$(( `all_lines "$gitstatus"` - `count_lines "$gitstatus" U` )) num_conflicts=`count_lines "$staged_files" U` num_staged=$(( `all_lines "$staged_files"` - num_conflicts )) num_untracked=`git ls-files --others --exclude-standard $(git rev-parse --show-cdup) | wc -l` -if [[ "$__GIT_PROMPT_IGNORE_STASH" = "1" ]]; then - num_stashed=0 -else - num_stashed=`git stash list | wc -l` + +num_stashed=0 +if [[ "$__GIT_PROMPT_IGNORE_STASH" != "1" ]]; then + stash_file="$( git rev-parse --git-dir )/logs/refs/stash" + if [[ -e "${stash_file}" ]]; then + while IFS='' read -r wcline || [[ -n "$wcline" ]]; do + ((num_stashed++)) + done < ${stash_file} + fi fi clean=0 @@ -105,8 +110,14 @@ if [[ "$has_remote_tracking" == "0" ]] ; then remote='_NO_REMOTE_TRACKING_' fi -for w in "$branch" "$remote" $num_staged $num_conflicts $num_changed $num_untracked $num_stashed $clean ; do - echo "$w" -done +printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n" \ + "$branch" \ + "$remote" \ + $num_staged \ + $num_conflicts \ + $num_changed \ + $num_untracked \ + $num_stashed \ + $clean exit From 52bfba7d37218dbacb066bfef45ff76f9836db35 Mon Sep 17 00:00:00 2001 From: oGre Date: Tue, 13 Oct 2015 18:31:49 +0200 Subject: [PATCH 4/5] Added documentation in Default theme --- themes/Default.bgptheme | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/themes/Default.bgptheme b/themes/Default.bgptheme index 40c97ec..fd823cb 100644 --- a/themes/Default.bgptheme +++ b/themes/Default.bgptheme @@ -61,7 +61,12 @@ define_undefined_git_prompt_colors() { if [[ -z ${GIT_PROMPT_COMMAND_OK} ]]; then GIT_PROMPT_COMMAND_OK="${Green}✔"; fi # indicator if the last command returned with an exit code of 0 if [[ -z ${GIT_PROMPT_COMMAND_FAIL} ]]; then GIT_PROMPT_COMMAND_FAIL="${Red}✘-_LAST_COMMAND_STATE_"; fi # indicator if the last command returned with an exit code of other than 0 - if [[ -z ${GIT_PROMPT_STATUS_COMMAND} ]]; then GIT_PROMPT_STATUS_COMMAND="gitstatus.sh"; fi # Point out the command to get the gitstatus from + # Possible to change which command is used to create git status information + # There are three options: + # 1) gitstatus.sh (uses git status --branch --porcelain - fast, requires git > 1.7.10) + # 2) gitstatus_pre-1.7.10.sh (Uses a variety of git commands and pipes - slower, works with older git clients) + # 3) gitstatus.py (Unsupported, lack features found in the bash versions) + if [[ -z ${GIT_PROMPT_STATUS_COMMAND} ]]; then GIT_PROMPT_STATUS_COMMAND="gitstatus.sh"; fi # Point out the command to get the git status from # template for displaying the current virtual environment # use the placeholder _VIRTUALENV_ will be replaced with From 67e7d6a08b03beb88ea028117babde9fd2c6379c Mon Sep 17 00:00:00 2001 From: oGre Date: Tue, 13 Oct 2015 18:43:44 +0200 Subject: [PATCH 5/5] Fixed bug where not all untracked files in folders were shown --- gitstatus.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitstatus.sh b/gitstatus.sh index 9f345e5..95d312a 100755 --- a/gitstatus.sh +++ b/gitstatus.sh @@ -15,7 +15,7 @@ if [ -z "${__GIT_PROMPT_DIR}" ]; then __GIT_PROMPT_DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )" fi -gitstatus=$( LC_ALL=C git status --porcelain --branch ) +gitstatus=$( LC_ALL=C git status --untracked-files=all --porcelain --branch ) # if the status is fatal, exit now [[ "$?" -ne 0 ]] && exit 0