Merge remote-tracking branch 'magicmonty/master'

master
Clemens Schwaighofer 10 years ago
commit 7f4d122fd2
  1. 11
      README.md
  2. 2
      git-prompt-help.sh
  3. 111
      gitprompt.sh
  4. 175
      gitstatus.py
  5. 125
      gitstatus.sh
  6. 123
      gitstatus_pre-1.7.10.sh
  7. 31
      themes/Chmike.bgptheme
  8. 8
      themes/Default.bgptheme
  9. 41
      themes/TruncatedPwd_WindowTitle.bgptheme
  10. 41
      themes/TruncatedPwd_WindowTitle_NoExitState.bgptheme

@ -1,5 +1,7 @@
# Informative git prompt for bash and fish # Informative git prompt for bash and fish
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/magicmonty/bash-git-prompt?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
This prompt is a port of the "Informative git prompt for zsh" which you can This prompt is a port of the "Informative git prompt for zsh" which you can
find [here](https://github.com/olivierverdier/zsh-git-prompt) find [here](https://github.com/olivierverdier/zsh-git-prompt)
@ -65,7 +67,7 @@ The symbols are as follows:
- Local Status Symbols - Local Status Symbols
- ``✔``: repository clean - ``✔``: repository clean
- ``●n``: there are ``n`` staged files - ``●n``: there are ``n`` staged files
- ``✖n``: there are ``n`` unmerged files - ``✖n``: there are ``n`` files with merge conflict(s)
- ``✚n``: there are ``n`` changed but *unstaged* files - ``✚n``: there are ``n`` changed but *unstaged* files
- ``…n``: there are ``n`` untracked files - ``…n``: there are ``n`` untracked files
- ``⚑n``: there are ``n`` stash entries - ``⚑n``: there are ``n`` stash entries
@ -198,6 +200,10 @@ function prompt_callback {
} }
``` ```
- There are two helper functions that can be used within `prompt_callback`:
- `gp_set_window_title <String>` - sets the window title to the given string (should work for XTerm type terminals like in OS X or Ubuntu)
- `gp_truncate_pwd` - a function that returns the current PWD truncated to fit the current terminal width
- If you want to show the git prompt only if you are in a git repository you - If you want to show the git prompt only if you are in a git repository you
can set ``GIT_PROMPT_ONLY_IN_REPO=1`` before sourcing the gitprompt script can set ``GIT_PROMPT_ONLY_IN_REPO=1`` before sourcing the gitprompt script
@ -302,9 +308,8 @@ Please leave a comment on the issue, that you want to fix it, so others know, th
Pull requests are welcome. I will check them and merge them, if I think they help the project. Pull requests are welcome. I will check them and merge them, if I think they help the project.
## Donations ## Donations
I accept tips through [Gittip][tip] and [Flattr][flattr]. I accept tips through [Flattr][flattr].
[![Gittip](https://img.shields.io/gittip/magicmonty.svg?style=flat)](https://www.gittip.com/magicmonty/)
[![Flattr](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=magicmonty&url=https%3A%2F%2Fgithub.com%2Fmagicmonty%2Fbash-git-prompt) [![Flattr](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=magicmonty&url=https%3A%2F%2Fgithub.com%2Fmagicmonty%2Fbash-git-prompt)
[blog post]: http://sebastiancelis.com/2009/nov/16/zsh-prompt-git-users/ [blog post]: http://sebastiancelis.com/2009/nov/16/zsh-prompt-git-users/

@ -22,7 +22,7 @@ LOCALSTATUS is one of the following:
${GIT_PROMPT_CLEAN}${ResetColor} - repository clean ${GIT_PROMPT_CLEAN}${ResetColor} - repository clean
${GIT_PROMPT_STAGED}N${ResetColor} - N staged files ${GIT_PROMPT_STAGED}N${ResetColor} - N staged files
${GIT_PROMPT_CONFLICTS}N${ResetColor} - N conflicted files ${GIT_PROMPT_CONFLICTS}N${ResetColor} - N files with merge conflicts
${GIT_PROMPT_CHANGED}N${ResetColor} - N changed but *unstaged* files ${GIT_PROMPT_CHANGED}N${ResetColor} - N changed but *unstaged* files
${GIT_PROMPT_UNTRACKED}N${ResetColor} - N untracked files ${GIT_PROMPT_UNTRACKED}N${ResetColor} - N untracked files
${GIT_PROMPT_STASHED}N${ResetColor} - N stash entries ${GIT_PROMPT_STASHED}N${ResetColor} - N stash entries

@ -1,14 +1,12 @@
#!/bin/sh #!/bin/sh
function async_run() function async_run() {
{
{ {
eval "$@" &> /dev/null eval "$@" &> /dev/null
}& }&
} }
function git_prompt_dir() function git_prompt_dir() {
{
# assume the gitstatus.sh is in the same directory as this script # assume the gitstatus.sh is in the same directory as this script
# code thanks to http://stackoverflow.com/questions/59895 # code thanks to http://stackoverflow.com/questions/59895
if [ -z "$__GIT_PROMPT_DIR" ]; then if [ -z "$__GIT_PROMPT_DIR" ]; then
@ -26,8 +24,7 @@ function echoc() {
echo -e "${1}$2${ResetColor}" | sed 's/\\\]//g' | sed 's/\\\[//g' echo -e "${1}$2${ResetColor}" | sed 's/\\\]//g' | sed 's/\\\[//g'
} }
function get_theme() function get_theme() {
{
local CUSTOM_THEME_FILE="${HOME}/.git-prompt-colors.sh" local CUSTOM_THEME_FILE="${HOME}/.git-prompt-colors.sh"
local DEFAULT_THEME_FILE="${__GIT_PROMPT_DIR}/themes/Default.bgptheme" local DEFAULT_THEME_FILE="${__GIT_PROMPT_DIR}/themes/Default.bgptheme"
@ -52,9 +49,11 @@ function get_theme()
local theme="" local theme=""
# use default theme, if theme was not found # use default theme, if theme was not found
for themefile in $(cd "$__GIT_PROMPT_DIR/themes" && echo *); do for themefile in "${__GIT_PROMPT_DIR}/themes/"*.bgptheme; do
if [[ "${themefile}" = "${GIT_PROMPT_THEME}.bgptheme" ]]; then local basename=${themefile##*/}
if [[ "${basename%.bgptheme}" = "${GIT_PROMPT_THEME}" ]]; then
theme=$GIT_PROMPT_THEME theme=$GIT_PROMPT_THEME
break
fi fi
done done
@ -67,25 +66,23 @@ function get_theme()
fi fi
} }
function git_prompt_load_theme() function git_prompt_load_theme() {
{
get_theme get_theme
local DEFAULT_THEME_FILE="${__GIT_PROMPT_DIR}/themes/Default.bgptheme" local DEFAULT_THEME_FILE="${__GIT_PROMPT_DIR}/themes/Default.bgptheme"
source "${DEFAULT_THEME_FILE}" source "${DEFAULT_THEME_FILE}"
source "${__GIT_PROMPT_THEME_FILE}" source "${__GIT_PROMPT_THEME_FILE}"
} }
function git_prompt_list_themes() function git_prompt_list_themes() {
{
local oldTheme local oldTheme
local oldThemeFile local oldThemeFile
git_prompt_dir git_prompt_dir
get_theme get_theme
for themefile in `ls "$__GIT_PROMPT_DIR/themes"`; do for themefile in "${__GIT_PROMPT_DIR}/themes/"*.bgptheme; do
local theme="$(basename $themefile .bgptheme)" local basename=${themefile##*/}
local theme="${basename%.bgptheme}"
if [[ "${GIT_PROMPT_THEME}" = "${theme}" ]]; then if [[ "${GIT_PROMPT_THEME}" = "${theme}" ]]; then
echoc ${Red} "*${theme}" echoc ${Red} "*${theme}"
else else
@ -117,7 +114,7 @@ function git_prompt_make_custom_theme() {
if [[ "${base}" = "Custom" ]]; then if [[ "${base}" = "Custom" ]]; then
echoc ${Red} "You cannot use the custom theme as base" echoc ${Red} "You cannot use the custom theme as base"
else else
echoc ${Green} "Creating new cutom theme in \"${HOME}/.git-prompt-colors.sh\"" echoc ${Green} "Creating new custom theme in \"${HOME}/.git-prompt-colors.sh\""
echoc ${DimYellow} "Please add ${Magenta}\"GIT_PROMPT_THEME=Custom\"${DimYellow} to your .bashrc to use this theme" echoc ${DimYellow} "Please add ${Magenta}\"GIT_PROMPT_THEME=Custom\"${DimYellow} to your .bashrc to use this theme"
if [[ "${base}" == "Default" ]]; then if [[ "${base}" == "Default" ]]; then
cp "${__GIT_PROMPT_DIR}/themes/Custom.bgptemplate" "${HOME}/.git-prompt-colors.sh" cp "${__GIT_PROMPT_DIR}/themes/Custom.bgptemplate" "${HOME}/.git-prompt-colors.sh"
@ -203,15 +200,14 @@ gp_format_exit_status() {
fi fi
} }
function git_prompt_config() function git_prompt_config() {
{
#Checking if root to change output #Checking if root to change output
_isroot=false _isroot=false
[[ $UID -eq 0 ]] && _isroot=true [[ $UID -eq 0 ]] && _isroot=true
# There are two files related to colors: # There are two files related to colors:
# #
# prompt-colors.sh -- sets generic color names suitable for bash `PS1` prompt # prompt-colors.sh -- sets generic color names suitable for bash 'PS1' prompt
# git-prompt-colors.sh -- sets the GIT_PROMPT color scheme, using names from prompt-colors.sh # git-prompt-colors.sh -- sets the GIT_PROMPT color scheme, using names from prompt-colors.sh
if gp_set_file_var __PROMPT_COLORS_FILE prompt-colors.sh ; then if gp_set_file_var __PROMPT_COLORS_FILE prompt-colors.sh ; then
@ -225,6 +221,12 @@ function git_prompt_config()
git_prompt_load_theme git_prompt_load_theme
if is_function prompt_callback; then
prompt_callback="prompt_callback"
else
prompt_callback="prompt_callback_default"
fi
if [ $GIT_PROMPT_LAST_COMMAND_STATE = 0 ]; then if [ $GIT_PROMPT_LAST_COMMAND_STATE = 0 ]; then
LAST_COMMAND_INDICATOR="$GIT_PROMPT_COMMAND_OK"; LAST_COMMAND_INDICATOR="$GIT_PROMPT_COMMAND_OK";
else else
@ -270,16 +272,7 @@ function git_prompt_config()
if [[ "$GIT_PROMPT_ONLY_IN_REPO" = 1 ]]; then if [[ "$GIT_PROMPT_ONLY_IN_REPO" = 1 ]]; then
EMPTY_PROMPT="$OLD_GITPROMPT" EMPTY_PROMPT="$OLD_GITPROMPT"
else else
local ps="" local ps="$(gp_add_virtualenv_to_prompt)$PROMPT_START$($prompt_callback)$PROMPT_END"
if [[ -n "$VIRTUAL_ENV" ]]; then
VENV=$(basename "${VIRTUAL_ENV}")
ps="${ps}${GIT_PROMPT_VIRTUALENV//_VIRTUALENV_/${VENV}}"
fi
if [[ -n "$CONDA_DEFAULT_ENV" ]]; then
VENV=$(basename "${CONDA_DEFAULT_ENV}")
ps="${ps}${GIT_PROMPT_VIRTUALENV//_VIRTUALENV_/${VENV}}"
fi
ps="$ps$PROMPT_START$($prompt_callback)$PROMPT_END"
EMPTY_PROMPT="${ps//_LAST_COMMAND_INDICATOR_/${LAST_COMMAND_INDICATOR}}" EMPTY_PROMPT="${ps//_LAST_COMMAND_INDICATOR_/${LAST_COMMAND_INDICATOR}}"
fi fi
@ -289,8 +282,8 @@ function git_prompt_config()
fi fi
if [[ -z "$__GIT_STATUS_CMD" ]] ; then # if GIT_STATUS_CMD not defined.. if [[ -z "$__GIT_STATUS_CMD" ]] ; then # if GIT_STATUS_CMD not defined..
git_prompt_dir git_prompt_dir
if ! gp_maybe_set_envar_to_path __GIT_STATUS_CMD "$__GIT_PROMPT_DIR/gitstatus.sh" ; then if ! gp_maybe_set_envar_to_path __GIT_STATUS_CMD "$__GIT_PROMPT_DIR/$GIT_PROMPT_STATUS_COMMAND" ; then
echo 1>&2 "Cannot find gitstatus.sh!" echo 1>&2 "Cannot find $GIT_PROMPT_STATUS_COMMAND!"
fi fi
# __GIT_STATUS_CMD defined # __GIT_STATUS_CMD defined
fi fi
@ -319,7 +312,7 @@ function update_old_git_prompt() {
function setGitPrompt() { function setGitPrompt() {
update_old_git_prompt update_old_git_prompt
local repo=`git rev-parse --show-toplevel 2> /dev/null` local repo=$(git rev-parse --show-toplevel 2> /dev/null)
if [[ ! -e "$repo" ]] && [[ "$GIT_PROMPT_ONLY_IN_REPO" = 1 ]]; then if [[ ! -e "$repo" ]] && [[ "$GIT_PROMPT_ONLY_IN_REPO" = 1 ]]; then
# we do not permit bash-git-prompt outside git repos, so nothing to do # we do not permit bash-git-prompt outside git repos, so nothing to do
PS1="$OLD_GITPROMPT" PS1="$OLD_GITPROMPT"
@ -375,7 +368,7 @@ function olderThanMinutes() {
fi fi
if [[ "$_have_find_mmin" = 1 ]]; then if [[ "$_have_find_mmin" = 1 ]]; then
matches=`"$_find_command" "$1" -mmin +"$2" 2> /dev/null` matches=$("$_find_command" "$1" -mmin +"$2" 2> /dev/null)
find_exit_code="$?" find_exit_code="$?"
if [[ -n "$matches" ]]; then if [[ -n "$matches" ]]; then
return 0 return 0
@ -418,8 +411,7 @@ function checkUpstream() {
fi fi
} }
function replaceSymbols() function replaceSymbols() {
{
if [[ -z ${GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING} ]]; then if [[ -z ${GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING} ]]; then
GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING=L GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING=L
fi fi
@ -499,23 +491,46 @@ function updatePrompt() {
__chk_gitvar_status 'CLEAN' '-eq 1' - __chk_gitvar_status 'CLEAN' '-eq 1' -
__add_status "$ResetColor$GIT_PROMPT_SUFFIX" __add_status "$ResetColor$GIT_PROMPT_SUFFIX"
NEW_PROMPT="" NEW_PROMPT="$(gp_add_virtualenv_to_prompt)$PROMPT_START$($prompt_callback)$STATUS$PROMPT_END"
if [[ -n "$VIRTUAL_ENV" ]]; then else
VENV=$(basename "${VIRTUAL_ENV}") NEW_PROMPT="$EMPTY_PROMPT"
NEW_PROMPT="$NEW_PROMPT${GIT_PROMPT_VIRTUALENV//_VIRTUALENV_/${VENV}}"
fi fi
PS1="${NEW_PROMPT//_LAST_COMMAND_INDICATOR_/${LAST_COMMAND_INDICATOR}}"
}
# Helper function that returns virtual env information to be set in prompt
# Honors virtualenvs own setting VIRTUAL_ENV_DISABLE_PROMPT
function gp_add_virtualenv_to_prompt {
local ACCUMULATED_VENV_PROMPT=""
local VENV=""
if [[ -n "$VIRTUAL_ENV" && -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ]]; then
VENV=$(basename "${VIRTUAL_ENV}")
ACCUMULATED_VENV_PROMPT="${ACCUMULATED_VENV_PROMPT}${GIT_PROMPT_VIRTUALENV//_VIRTUALENV_/${VENV}}"
fi
if [[ -n "$CONDA_DEFAULT_ENV" ]]; then if [[ -n "$CONDA_DEFAULT_ENV" ]]; then
VENV=$(basename "${CONDA_DEFAULT_ENV}") VENV=$(basename "${CONDA_DEFAULT_ENV}")
NEW_PROMPT="$NEW_PROMPT${GIT_PROMPT_VIRTUALENV//_VIRTUALENV_/${VENV}}" ACCUMULATED_VENV_PROMPT="${ACCUMULATED_VENV_PROMPT}${GIT_PROMPT_VIRTUALENV//_VIRTUALENV_/${VENV}}"
fi fi
echo "$ACCUMULATED_VENV_PROMPT"
}
NEW_PROMPT="$NEW_PROMPT$PROMPT_START$($prompt_callback)$STATUS$PROMPT_END" # Use exit status from declare command to determine whether input argument is a
else # bash function
NEW_PROMPT="$EMPTY_PROMPT" function is_function {
fi declare -Ff "$1" >/dev/null;
}
#Helper function that truncates $PWD depending on window width
function gp_truncate_pwd {
local newPWD="${PWD/#$HOME/~}"
local pwdmaxlen=$((${COLUMNS:-80}/3))
[ ${#newPWD} -gt $pwdmaxlen ] && newPWD="...${newPWD:3-$pwdmaxlen}"
echo -n "$newPWD"
}
PS1="${NEW_PROMPT//_LAST_COMMAND_INDICATOR_/${LAST_COMMAND_INDICATOR}}" #Sets the window title to the given argument string
function gp_set_window_title {
echo -ne "\033]0;"$@"\007"
} }
function prompt_callback_default { function prompt_callback_default {
@ -523,12 +538,6 @@ function prompt_callback_default {
} }
function gp_install_prompt { function gp_install_prompt {
if [ "`type -t prompt_callback`" = 'function' ]; then
prompt_callback="prompt_callback"
else
prompt_callback="prompt_callback_default"
fi
if [ -z "$OLD_GITPROMPT" ]; then if [ -z "$OLD_GITPROMPT" ]; then
OLD_GITPROMPT=$PS1 OLD_GITPROMPT=$PS1
fi fi

@ -1,26 +1,32 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
"""This module defines a Print function to use with python 2.x or 3.x., so we can use the prompt with older versions of Python too """This module defines a Print function to use with python 2.x or 3.x., so we can use the prompt with older versions of
Python too
It's interface is that of python 3.0's print. See It's interface is that of python 3.0's print. See
http://docs.python.org/3.0/library/functions.html?highlight=print#print http://docs.python.org/3.0/library/functions.html?highlight=print#print
Shamelessly ripped from http://www.daniweb.com/software-development/python/code/217214/a-print-function-for-different-versions-of-python Shamelessly ripped from
http://www.daniweb.com/software-development/python/code/217214/a-print-function-for-different-versions-of-python
""" """
# change those symbols to whatever you prefer
symbols = {'ahead of': '↑·', 'behind': '↓·', 'prehash': ':'}
__all__ = ["Print"]
import sys import sys
import re
from subprocess import Popen, PIPE
__all__ = ["Print"]
try: try:
Print = eval("print") # python 3.0 case Print = eval("print") # python 3.0 case
except SyntaxError: except SyntaxError:
try:
D = dict() D = dict()
try:
exec ("from __future__ import print_function\np=print", D) exec ("from __future__ import print_function\np=print", D)
Print = D["p"] # 2.6 case Print = D["p"] # 2.6 case
del D
except SyntaxError: except SyntaxError:
del D
def Print(*args, **kwd): # 2.4, 2.5, define our own Print function def Print(*args, **kwd): # 2.4, 2.5, define our own Print function
fout = kwd.get("file", sys.stdout) fout = kwd.get("file", sys.stdout)
w = fout.write w = fout.write
@ -31,94 +37,103 @@ except SyntaxError:
w(sep) w(sep)
w(str(a)) w(str(a))
w(kwd.get("end", "\n")) w(kwd.get("end", "\n"))
finally:
del D
# change those symbols to whatever you prefer def get_tag_or_hash():
symbols = {'ahead of': '↑·', 'behind': '↓·', 'prehash':':'} cmd = Popen(['git', 'describe', '--exact-match'], stdout=PIPE, stderr=PIPE)
so, se = cmd.communicate()
from subprocess import Popen, PIPE tag = '%s' % so.decode('utf-8').strip()
import sys if tag:
gitsym = Popen(['git', 'symbolic-ref', 'HEAD'], stdout=PIPE, stderr=PIPE) return tag
branch, error = gitsym.communicate()
error_string = error.decode('utf-8')
if 'fatal: Not a git repository' in error_string:
sys.exit(0)
branch = branch.decode('utf-8').strip()[11:]
res, err = Popen(['git','diff','--name-status'], stdout=PIPE, stderr=PIPE).communicate()
err_string = err.decode('utf-8')
if 'fatal' in err_string:
sys.exit(0)
changed_files = [namestat[0] for namestat in res.splitlines()]
staged_files = [namestat[0] for namestat in Popen(['git','diff', '--staged','--name-status'], stdout=PIPE).communicate()[0].splitlines()]
nb_changed = len(changed_files) - changed_files.count('U')
nb_U = staged_files.count('U')
nb_staged = len(staged_files) - nb_U
staged = str(nb_staged)
conflicts = str(nb_U)
changed = str(nb_changed)
status_lines = Popen(['git','status','-s','-uall'],stdout=PIPE).communicate()[0].splitlines()
untracked_lines = [a for a in map(lambda s: s.decode('utf-8'), status_lines) if a.startswith("??")]
nb_untracked = len(untracked_lines)
untracked = str(nb_untracked)
stashes = Popen(['git','stash','list'],stdout=PIPE).communicate()[0].splitlines()
nb_stashed = len(stashes)
stashed = str(nb_stashed)
if not nb_changed and not nb_staged and not nb_U and not nb_untracked and not nb_stashed:
clean = '1'
else: else:
clean = '0' cmd = Popen(['git', 'rev-parse', '--short', 'HEAD'], stdout=PIPE, stderr=PIPE)
so, se = cmd.communicate()
hash_name = '%s' % so.decode('utf-8').strip()
return ''.join([symbols['prehash'], hash_name])
remote = ''
tag, tag_error = Popen(['git', 'describe', '--exact-match'], stdout=PIPE, stderr=PIPE).communicate() def get_stash():
cmd = Popen(['git', 'rev-parse', '--git-dir'], stdout=PIPE, stderr=PIPE)
so, se = cmd.communicate()
stash_file = '%s%s' % (so.decode('utf-8').rstrip(), '/logs/refs/stash')
if not branch: # not on any branch try:
if tag: # if we are on a tag, print the tag's name with open(stash_file) as f:
branch = tag return sum(1 for _ in f)
except IOError:
return 0
# `git status --porcelain --branch` can collect all information
# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
po = Popen(['git', 'status', '--porcelain', '--branch'], env={'LC_ALL': 'C'}, stdout=PIPE, stderr=PIPE)
stdout, stderr = po.communicate()
if po.returncode != 0:
sys.exit(0) # Not a git repository
# collect git status information
untracked, staged, changed, conflicts = [], [], [], []
num_ahead, num_behind = 0, 0
ahead, behind = '', ''
branch = ''
remote = ''
status = [(line[0], line[1], line[2:]) for line in stdout.decode('utf-8').splitlines()]
for st in status:
if st[0] == '#' and st[1] == '#':
if re.search('Initial commit on', st[2]):
branch = st[2].split(' ')[-1]
elif re.search('no branch', st[2]): # detached status
branch = get_tag_or_hash()
elif len(st[2].strip().split('...')) == 1:
branch = st[2].strip()
else: else:
branch = symbols['prehash']+ Popen(['git','rev-parse','--short','HEAD'], stdout=PIPE).communicate()[0].decode('utf-8')[:-1] # current and remote branch info
branch, rest = st[2].strip().split('...')
if len(rest.split(' ')) == 1:
# remote_branch = rest.split(' ')[0]
pass
else: else:
remote_name = Popen(['git','config','branch.%s.remote' % branch], stdout=PIPE).communicate()[0].strip() # ahead or behind
if remote_name: divergence = ' '.join(rest.split(' ')[1:])
merge_name = Popen(['git','config','branch.%s.merge' % branch], stdout=PIPE).communicate()[0].strip() divergence = divergence.lstrip('[').rstrip(']')
for div in divergence.split(', '):
if 'ahead' in div:
num_ahead = int(div[len('ahead '):].strip())
ahead = '%s%s' % (symbols['ahead of'], num_ahead)
elif 'behind' in div:
num_behind = int(div[len('behind '):].strip())
behind = '%s%s' % (symbols['behind'], num_behind)
remote = ''.join([behind, ahead])
elif st[0] == '?' and st[1] == '?':
untracked.append(st)
else: else:
remote_name = "origin" if st[1] == 'M':
merge_name = "refs/heads/%s" % branch changed.append(st)
if st[0] == 'U':
if remote_name == '.': # local conflicts.append(st)
remote_ref = merge_name elif st[0] != ' ':
staged.append(st)
stashed = get_stash()
if not changed and not staged and not conflicts and not untracked and not stashed:
clean = 1
else: else:
remote_ref = 'refs/remotes/%s/%s' % (remote_name, merge_name[11:]) clean = 0
revgit = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % remote_ref],stdout=PIPE, stderr=PIPE)
revlist = revgit.communicate()[0]
if revgit.poll(): # fallback to local
revlist = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % merge_name],stdout=PIPE, stderr=PIPE).communicate()[0]
behead = revlist.splitlines()
ahead = len([x for x in behead if x[0]=='>'])
behind = len(behead) - ahead
if behind:
remote += '%s%s' % (symbols['behind'], behind)
if ahead:
remote += '%s%s' % (symbols['ahead of'], ahead)
if remote == "": if remote == "":
remote = '.' remote = '.'
out = '\n'.join([ out = '\n'.join([
str(branch), branch,
str(remote), remote.decode('utf-8'),
staged, str(len(staged)),
conflicts, str(len(conflicts)),
changed, str(len(changed)),
untracked, str(len(untracked)),
stashed, str(stashed),
clean]) str(clean)
])
Print(out) Print(out)

@ -5,10 +5,6 @@
# #
# Alan K. Stebbens <aks@stebbens.org> [http://github.com/aks] # Alan K. Stebbens <aks@stebbens.org> [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 if [ -z "${__GIT_PROMPT_DIR}" ]; then
SOURCE="${BASH_SOURCE[0]}" SOURCE="${BASH_SOURCE[0]}"
while [ -h "${SOURCE}" ]; do while [ -h "${SOURCE}" ]; do
@ -19,81 +15,72 @@ if [ -z "${__GIT_PROMPT_DIR}" ]; then
__GIT_PROMPT_DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )" __GIT_PROMPT_DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )"
fi fi
gitsym=`git symbolic-ref HEAD` gitstatus=$( LC_ALL=C git status --untracked-files=all --porcelain --branch )
# if "fatal: Not a git repo .., then exit # if the status is fatal, exit now
case "$gitsym" in fatal*) exit 0 ;; esac [[ "$?" -ne 0 ]] && exit 0
# the current branch is the tail end of the symbolic reference num_staged=0
branch="${gitsym##refs/heads/}" # get the basename after "refs/heads/" num_changed=0
num_conflicts=0
gitstatus=`git diff --name-status 2>&1` num_untracked=0
while IFS='' read -r line || [[ -n "$line" ]]; do
# if the diff is fatal, exit now status=${line:0:2}
case "$gitstatus" in fatal*) exit 0 ;; esac case "$status" in
\#\#) branch_line="${line/\.\.\./^}" ;;
?M) ((num_changed++)) ;;
U?) ((num_conflicts++)) ;;
\?\?) ((num_untracked++)) ;;
*) ((num_staged++)) ;;
esac
done <<< "$gitstatus"
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 num_stashed=0
else if [[ "$__GIT_PROMPT_IGNORE_STASH" != "1" ]]; then
num_stashed=`git stash list | wc -l` 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 fi
clean=0 clean=0
if (( num_changed == 0 && num_staged == 0 && num_U == 0 && num_untracked == 0 && num_stashed == 0 )) ; then if (( num_changed == 0 && num_staged == 0 && num_untracked == 0 && num_stashed == 0 )) ; then
clean=1 clean=1
fi fi
IFS="^" read -ra branch_fields <<< "${branch_line/\#\# }"
branch="${branch_fields[0]}"
remote= remote=
if [[ -z "$branch" ]]; then if [[ "$branch" == *"Initial commit on"* ]]; then
tag=`git describe --exact-match` IFS=" " read -ra fields <<< "$branch"
branch="${fields[3]}"
remote="_NO_REMOTE_TRACKING_"
elif [[ "$branch" == *"no branch"* ]]; then
tag=$( git describe --exact-match )
if [[ -n "$tag" ]]; then if [[ -n "$tag" ]]; then
branch="$tag" branch="$tag"
else else
branch="_PREHASH_`git rev-parse --short HEAD`" 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 fi
if [[ "$remote_name" == '.' ]]; then
remote_ref="$merge_name"
else else
remote_ref="refs/remotes/$remote_name/${merge_name##refs/heads/}" if [[ "${#branch_fields[@]}" -eq 1 ]]; then
fi remote="_NO_REMOTE_TRACKING_"
# detect if the local branch have a remote tracking branch
cmd_output=$(git rev-parse --abbrev-ref ${branch}@{upstream} 2>&1 >/dev/null)
if [ `count_lines "$cmd_output" "fatal: No upstream"` == 1 ] ; then
has_remote_tracking=0
else else
has_remote_tracking=1 IFS="[,]" read -ra remote_fields <<< "${branch_fields[1]}"
for remote_field in "${remote_fields[@]}"; do
if [[ "$remote_field" == *ahead* ]]; then
num_ahead=${remote_field:6}
ahead="_AHEAD_${num_ahead}"
fi fi
if [[ "$remote_field" == *behind* ]]; then
# get the revision list, and count the leading "<" and ">" num_behind=${remote_field:7}
revgit=`git rev-list --left-right ${remote_ref}...HEAD` behind="_BEHIND_${num_behind# }"
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 fi
if (( num_ahead > 0 )) ; then done
remote="${remote}_AHEAD_${num_ahead}" remote="${behind}${ahead}"
fi fi
fi fi
@ -101,12 +88,14 @@ if [[ -z "$remote" ]] ; then
remote='.' remote='.'
fi fi
if [[ "$has_remote_tracking" == "0" ]] ; then printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n" \
remote='_NO_REMOTE_TRACKING_' "$branch" \
fi "$remote" \
$num_staged \
for w in "$branch" "$remote" $num_staged $num_conflicts $num_changed $num_untracked $num_stashed $clean ; do $num_conflicts \
echo "$w" $num_changed \
done $num_untracked \
$num_stashed \
$clean
exit exit

@ -0,0 +1,123 @@
#!/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 <aks@stebbens.org> [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`
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
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
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

@ -0,0 +1,31 @@
# This theme for gitprompt.sh is designed for dark color schemes
# it is clone of oh-my-zsh crunch theme style with exit status
override_git_prompt_colors() {
if [ -e ~/.rvm/bin/rvm-prompt ]; then
RUBY_PROMPT='{$(~/.rvm/bin/rvm-prompt i v)}'
else
if command -v rbenv > /dev/null; then
RUBY_PROMPT='{$(rbenv version | sed -e "s/ (set.*$//")}'
fi
fi
Time12a="\$(date +%H:%M)"
GIT_PROMPT_THEME_NAME="Chmike"
GIT_PROMPT_BRANCH="${Green}"
GIT_PROMPT_REMOTE=" "
GIT_PROMPT_SYMBOLS_NO_REMOTE_TRACKING="⭐"
GIT_PROMPT_SEPARATOR="|"
GIT_PROMPT_CHANGED="${Cyan}❗"
GIT_PROMPT_STAGED="${Yellow}▸"
GIT_PROMPT_UNTRACKED="${Blue}…"
GIT_PROMPT_CONFLICTS="${BoldRed}❓"
GIT_PROMPT_STASHED="${Magenta}>"
GIT_PROMPT_CLEAN="${Green}✔ "
GIT_PROMPT_COMMAND_OK="${Green}✔"
GIT_PROMPT_COMMAND_FAIL="${Red}✘"
}
reload_git_prompt_colors "Crunch"

@ -16,6 +16,7 @@ unset_git_prompt_colors() {
unset GIT_PROMPT_CLEAN unset GIT_PROMPT_CLEAN
unset GIT_PROMPT_COMMAND_OK unset GIT_PROMPT_COMMAND_OK
unset GIT_PROMPT_COMMAND_FAIL unset GIT_PROMPT_COMMAND_FAIL
unset GIT_PROMPT_STATUS_COMMAND
unset GIT_PROMPT_VIRTUALENV unset GIT_PROMPT_VIRTUALENV
unset GIT_PROMPT_START_USER unset GIT_PROMPT_START_USER
unset GIT_PROMPT_START_ROOT unset GIT_PROMPT_START_ROOT
@ -60,6 +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_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_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
# 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 # 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) # the name of the current virtual environment (currently CONDA and VIRTUAL_ENV)

@ -0,0 +1,41 @@
##############################################################################
# Changes the prompt to a Debian-style one that truncates pwd to a max length
# depending on the terminal column width. Also uses the prompt_callback
# function of bash-git-prompt to set the window title to almost the same
# Debian-style.
#
# The prompt will use a Debian-style on the form
#
# [user@host: <truncated PWD>] [bash-git-prompt-info] <exit status>
# HH:MM $
#
# The window title will have the form
# user@host: <truncated PWD>
#
# Example usage:
# if [ -f ~/.bash-git-prompt/gitprompt.sh ]; then
# GIT_PROMPT_THEME=TruncatedPwd_WindowTitle
# source ~/.bash-git-prompt/gitprompt.sh
# fi
#
# oGre <oGre@muppfarmen.se> [https://github.com/ogr3]
##############################################################################
override_git_prompt_colors() {
GIT_PROMPT_THEME_NAME="TruncatedPwd_WindowTitle"
#Overrides the prompt_callback function used by bash-git-prompt
function prompt_callback {
local PS1="\u@\h: $(gp_truncate_pwd)"
gp_set_window_title "$PS1"
echo -n "[${PS1}]${ResetColor}"
}
Time12a="\$(date +%H:%M)"
GIT_PROMPT_START_USER="${Yellow}"
GIT_PROMPT_START_ROOT="${GIT_PROMPT_START_USER}"
GIT_PROMPT_END_USER=" _LAST_COMMAND_INDICATOR_\n${White}${Time12a}${ResetColor} $ "
GIT_PROMPT_END_ROOT=" _LAST_COMMAND_INDICATOR_\n${White}${Time12a}${ResetColor} # "
}
reload_git_prompt_colors "TruncatedPwd_WindowTitle"

@ -0,0 +1,41 @@
##############################################################################
# Changes the prompt to a Debian-style one that truncates pwd to a max length
# depending on the terminal column width. Also uses the prompt_callback
# function of bash-git-prompt to set the window title to almost the same
# Debian-style.
#
# The prompt will use a Debian-style on the form
#
# [user@host: <truncated PWD>] [bash-git-prompt-info]
# HH:MM $
#
# The window title will have the form
# user@host: <truncated PWD>
#
# Example usage:
# if [ -f ~/.bash-git-prompt/gitprompt.sh ]; then
# GIT_PROMPT_THEME=TruncatedPwd_WindowTitle_NoExitState
# source ~/.bash-git-prompt/gitprompt.sh
# fi
#
# oGre <oGre@muppfarmen.se> [https://github.com/ogr3]
##############################################################################
override_git_prompt_colors() {
GIT_PROMPT_THEME_NAME="TruncatedPwd_WindowTitle_NoExitState"
#Overrides the prompt_callback function used by bash-git-prompt
function prompt_callback {
local PS1="\u@\h: $(gp_truncate_pwd)"
gp_set_window_title "$PS1"
echo -n "[${PS1}]${ResetColor}"
}
Time12a="\$(date +%H:%M)"
GIT_PROMPT_START_USER="${Yellow}"
GIT_PROMPT_START_ROOT="${GIT_PROMPT_START_USER}"
GIT_PROMPT_END_USER="\n${White}${Time12a}${ResetColor} $ "
GIT_PROMPT_END_ROOT="\n${White}${Time12a}${ResetColor} # "
}
reload_git_prompt_colors "TruncatedPwd_WindowTitle_NoExitState"
Loading…
Cancel
Save