mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2026-05-08 04:34:00 +02:00
Merge f4b8687138 into 291e96dcd0
This commit is contained in:
commit
e64933fb87
2 changed files with 87 additions and 96 deletions
|
|
@ -29,24 +29,99 @@ preexec_functions+=(preexec_update_git_vars)
|
||||||
|
|
||||||
|
|
||||||
## Function definitions
|
## Function definitions
|
||||||
function update_current_git_vars() {
|
|
||||||
unset __CURRENT_GIT_STATUS
|
|
||||||
|
|
||||||
local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py"
|
function get_tagname_or_hash() {
|
||||||
_GIT_STATUS=$(python ${gitstatus} 2>/dev/null)
|
local log_string
|
||||||
__CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}")
|
local refs ref
|
||||||
GIT_BRANCH=$__CURRENT_GIT_STATUS[1]
|
local ret_hash ret_tag
|
||||||
GIT_AHEAD=$__CURRENT_GIT_STATUS[2]
|
log_string="$(git log -1 --decorate=full --format="%h%d" 2> /dev/null)"
|
||||||
GIT_BEHIND=$__CURRENT_GIT_STATUS[3]
|
if [[ "$log_string" == *' ('*')' ]]; then
|
||||||
GIT_STAGED=$__CURRENT_GIT_STATUS[4]
|
ret_hash="${log_string%% (*)}"
|
||||||
GIT_CONFLICTS=$__CURRENT_GIT_STATUS[5]
|
refs="${(M)log_string%% (*)}"
|
||||||
GIT_CHANGED=$__CURRENT_GIT_STATUS[6]
|
refs="${refs# \(}"
|
||||||
GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7]
|
refs="${refs%\)}"
|
||||||
|
for ref in ${(s:, :)refs}; do
|
||||||
|
if [[ "$ref" == 'refs/tags/'* ]]; then # git 1.7.x
|
||||||
|
ret_tag="${ref#refs/tags/}"
|
||||||
|
elif [[ "$ref" == 'tag: refs/tags/'* ]]; then # git 2.1.x
|
||||||
|
ret_tag="${ref#tag: refs/tags/}"
|
||||||
|
fi
|
||||||
|
if [[ "$ret_tag" != "" ]]; then
|
||||||
|
TAG_OR_HASH="tags/$ret_tag"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
TAG_OR_HASH="$ret_hash"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_current_git_vars() {
|
||||||
|
local branch branch_description branch_parts
|
||||||
|
local ahead=0 behind=0
|
||||||
|
local staged=0 conflict=0 changed=0 untracked=0
|
||||||
|
local status_string status_line
|
||||||
|
local divergence div
|
||||||
|
|
||||||
|
__CURRENT_GIT_STATUS=0
|
||||||
|
status_string="$(git status --branch --porcelain -z 2> /dev/null)"
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
# not a git repository
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
__CURRENT_GIT_STATUS=1
|
||||||
|
|
||||||
|
for status_line in ${(0)status_string}; do
|
||||||
|
if [[ "${status_line:0:2}" == '##' ]]; then
|
||||||
|
branch_description="${status_line:2}"
|
||||||
|
if [[ "$branch_description" == *'Initial commit on '* ]]; then
|
||||||
|
branch="${branch_description/#*'Initial commit on '/}"
|
||||||
|
elif [[ "$branch_description" == *'no branch'* ]]; then
|
||||||
|
get_tagname_or_hash
|
||||||
|
branch="$TAG_OR_HASH"
|
||||||
|
elif [[ "$branch_description" != *'...'* ]]; then
|
||||||
|
branch="${branch_description# }"
|
||||||
|
else
|
||||||
|
# local and remote branch info
|
||||||
|
branch_parts=(${(s:...:)branch_description})
|
||||||
|
branch="${branch_parts[1]# }"
|
||||||
|
if [[ $#branch_parts -ne 1 ]]; then
|
||||||
|
# ahead or behind
|
||||||
|
divergence="${(M)branch_parts[2]%\[*\]}"
|
||||||
|
divergence="${divergence#\[}"
|
||||||
|
divergence="${divergence%\]}"
|
||||||
|
for div in ${(s:, :)divergence}; do
|
||||||
|
if [[ "$div" == 'ahead '* ]]; then
|
||||||
|
ahead="${div#ahead }"
|
||||||
|
elif [[ "$div" == 'behind '* ]]; then
|
||||||
|
behind="${div#behind }"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
elif [[ "${status_line:0:2}" == '??' ]]; then
|
||||||
|
untracked=$((untracked + 1))
|
||||||
|
else
|
||||||
|
if [[ "${status_line:1:1}" == 'M' ]]; then
|
||||||
|
changed=$((changed + 1))
|
||||||
|
elif [[ "${status_line:0:1}" == 'U' ]]; then
|
||||||
|
conflict=$((conflict + 1))
|
||||||
|
elif [[ "${status_line:0:1}" != ' ' ]]; then
|
||||||
|
staged=$((staged + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
GIT_BRANCH="$branch"
|
||||||
|
GIT_AHEAD="$ahead"
|
||||||
|
GIT_BEHIND="$behind"
|
||||||
|
GIT_STAGED="$staged"
|
||||||
|
GIT_CONFLICTS="$conflict"
|
||||||
|
GIT_CHANGED="$changed"
|
||||||
|
GIT_UNTRACKED="$untracked"
|
||||||
}
|
}
|
||||||
|
|
||||||
git_super_status() {
|
git_super_status() {
|
||||||
precmd_update_git_vars
|
precmd_update_git_vars
|
||||||
if [ -n "$__CURRENT_GIT_STATUS" ]; then
|
if [ "$__CURRENT_GIT_STATUS" -eq 1 ]; then
|
||||||
STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}"
|
STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}"
|
||||||
if [ "$GIT_BEHIND" -ne "0" ]; then
|
if [ "$GIT_BEHIND" -ne "0" ]; then
|
||||||
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}"
|
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}"
|
||||||
|
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import shlex
|
|
||||||
from subprocess import Popen, PIPE, check_output
|
|
||||||
|
|
||||||
|
|
||||||
def get_tagname_or_hash():
|
|
||||||
"""return tagname if exists else hash"""
|
|
||||||
cmd = 'git log -1 --format="%h%d"'
|
|
||||||
output = check_output(shlex.split(cmd)).decode('utf-8').strip()
|
|
||||||
hash_, tagname = None, None
|
|
||||||
# get hash
|
|
||||||
m = re.search('\(.*\)$', output)
|
|
||||||
if m:
|
|
||||||
hash_ = output[:m.start()-1]
|
|
||||||
# get tagname
|
|
||||||
m = re.search('tag: .*[,\)]', output)
|
|
||||||
if m:
|
|
||||||
tagname = 'tags/' + output[m.start()+len('tag: '): m.end()-1]
|
|
||||||
|
|
||||||
if tagname:
|
|
||||||
return tagname
|
|
||||||
elif hash_:
|
|
||||||
return hash_
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
# `git status --porcelain --branch` can collect all information
|
|
||||||
# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
|
|
||||||
po = Popen(['git', 'status', '--porcelain', '--branch'], stdout=PIPE, stderr=PIPE)
|
|
||||||
stdout, sterr = po.communicate()
|
|
||||||
if po.returncode != 0:
|
|
||||||
sys.exit(0) # Not a git repository
|
|
||||||
|
|
||||||
# collect git status information
|
|
||||||
untracked, staged, changed, conflicts = [], [], [], []
|
|
||||||
ahead, behind = 0, 0
|
|
||||||
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_tagname_or_hash()
|
|
||||||
elif len(st[2].strip().split('...')) == 1:
|
|
||||||
branch = st[2].strip()
|
|
||||||
else:
|
|
||||||
# current and remote branch info
|
|
||||||
branch, rest = st[2].strip().split('...')
|
|
||||||
if len(rest.split(' ')) == 1:
|
|
||||||
# remote_branch = rest.split(' ')[0]
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# ahead or behind
|
|
||||||
divergence = ' '.join(rest.split(' ')[1:])
|
|
||||||
divergence = divergence.lstrip('[').rstrip(']')
|
|
||||||
for div in divergence.split(', '):
|
|
||||||
if 'ahead' in div:
|
|
||||||
ahead = int(div[len('ahead '):].strip())
|
|
||||||
elif 'behind' in div:
|
|
||||||
behind = int(div[len('behind '):].strip())
|
|
||||||
elif st[0] == '?' and st[1] == '?':
|
|
||||||
untracked.append(st)
|
|
||||||
else:
|
|
||||||
if st[1] == 'M':
|
|
||||||
changed.append(st)
|
|
||||||
if st[0] == 'U':
|
|
||||||
conflicts.append(st)
|
|
||||||
elif st[0] != ' ':
|
|
||||||
staged.append(st)
|
|
||||||
|
|
||||||
out = ' '.join([
|
|
||||||
branch,
|
|
||||||
str(ahead),
|
|
||||||
str(behind),
|
|
||||||
str(len(staged)),
|
|
||||||
str(len(conflicts)),
|
|
||||||
str(len(changed)),
|
|
||||||
str(len(untracked)),
|
|
||||||
])
|
|
||||||
print(out, end='')
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue