daabe2a0089ac4f0c3646b5ea92c9efe06cd7ccb
- Author
- Robby Russell <robby@planetargon.com>
- Committer
- Robby Russell <robby@planetargon.com>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/plugins/git-prompt/git-prompt.plugin.zsh b/plugins/git-prompt/git-prompt.plugin.zsh
2index d868a5fe1d1bf6b6117db674b093d1a632f5d0d7..5175bf70f91d0fafddebfd72a74eea5435131213 100644
3--- a/plugins/git-prompt/git-prompt.plugin.zsh
4+++ b/plugins/git-prompt/git-prompt.plugin.zsh
5@@ -1,57 +1,92 @@
6 # ZSH Git Prompt Plugin from:
7 # http://github.com/olivierverdier/zsh-git-prompt
8-#
9-export __GIT_PROMPT_DIR=$ZSH/plugins/git-prompt
10
11-# Allow for functions in the prompt.
12-setopt PROMPT_SUBST
13+__GIT_PROMPT_DIR="${0:A:h}"
14
15-## Enable auto-execution of functions.
16-typeset -ga preexec_functions
17-typeset -ga precmd_functions
18-typeset -ga chpwd_functions
19-
20-# Append git functions needed for prompt.
21-preexec_functions+='preexec_update_git_vars'
22-precmd_functions+='precmd_update_git_vars'
23-chpwd_functions+='chpwd_update_git_vars'
24+## Hook function definitions
25+function chpwd_update_git_vars() {
26+ update_current_git_vars
27+}
28
29-## Function definitions
30 function preexec_update_git_vars() {
31 case "$2" in
32- git*)
33+ git*|hub*|gh*|stg*)
34 __EXECUTED_GIT_COMMAND=1
35 ;;
36 esac
37 }
38
39 function precmd_update_git_vars() {
40- if [ -n "$__EXECUTED_GIT_COMMAND" ]; then
41+ if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ ! -n "$ZSH_THEME_GIT_PROMPT_CACHE" ]; then
42 update_current_git_vars
43 unset __EXECUTED_GIT_COMMAND
44 fi
45 }
46
47-function chpwd_update_git_vars() {
48- update_current_git_vars
49-}
50+chpwd_functions+=(chpwd_update_git_vars)
51+precmd_functions+=(precmd_update_git_vars)
52+preexec_functions+=(preexec_update_git_vars)
53+
54
55+## Function definitions
56 function update_current_git_vars() {
57 unset __CURRENT_GIT_STATUS
58
59 local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py"
60- _GIT_STATUS=`python ${gitstatus}`
61- __CURRENT_GIT_STATUS=("${(f)_GIT_STATUS}")
62+ _GIT_STATUS=$(python ${gitstatus} 2>/dev/null)
63+ __CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}")
64+ GIT_BRANCH=$__CURRENT_GIT_STATUS[1]
65+ GIT_AHEAD=$__CURRENT_GIT_STATUS[2]
66+ GIT_BEHIND=$__CURRENT_GIT_STATUS[3]
67+ GIT_STAGED=$__CURRENT_GIT_STATUS[4]
68+ GIT_CONFLICTS=$__CURRENT_GIT_STATUS[5]
69+ GIT_CHANGED=$__CURRENT_GIT_STATUS[6]
70+ GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7]
71 }
72
73-function prompt_git_info() {
74+git_super_status() {
75+ precmd_update_git_vars
76 if [ -n "$__CURRENT_GIT_STATUS" ]; then
77- echo "(%{${fg[red]}%}$__CURRENT_GIT_STATUS[1]%{${fg[default]}%}$__CURRENT_GIT_STATUS[2]%{${fg[magenta]}%}$__CURRENT_GIT_STATUS[3]%{${fg[default]}%})"
78+ STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}"
79+ if [ "$GIT_BEHIND" -ne "0" ]; then
80+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}"
81+ fi
82+ if [ "$GIT_AHEAD" -ne "0" ]; then
83+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD$GIT_AHEAD%{${reset_color}%}"
84+ fi
85+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR"
86+ if [ "$GIT_STAGED" -ne "0" ]; then
87+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED%{${reset_color}%}"
88+ fi
89+ if [ "$GIT_CONFLICTS" -ne "0" ]; then
90+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS%{${reset_color}%}"
91+ fi
92+ if [ "$GIT_CHANGED" -ne "0" ]; then
93+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}"
94+ fi
95+ if [ "$GIT_UNTRACKED" -ne "0" ]; then
96+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED%{${reset_color}%}"
97+ fi
98+ if [ "$GIT_CHANGED" -eq "0" ] && [ "$GIT_CONFLICTS" -eq "0" ] && [ "$GIT_STAGED" -eq "0" ] && [ "$GIT_UNTRACKED" -eq "0" ]; then
99+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN"
100+ fi
101+ STATUS="$STATUS%{${reset_color}%}$ZSH_THEME_GIT_PROMPT_SUFFIX"
102+ echo "$STATUS"
103 fi
104 }
105diff --git a/plugins/git-prompt/gitstatus.py b/plugins/git-prompt/gitstatus.py
106index 2568414320a79140ab387ad4fe788d8cd78367fd..a8eb8284b7ad8ed601890d84f0ffbfe92f6c00a1 100644
107--- a/plugins/git-prompt/gitstatus.py
108+++ b/plugins/git-prompt/gitstatus.py
109@@ -1,82 +1,84 @@
110 #!/usr/bin/env python
111-# -*- coding: UTF-8 -*-
112-from subprocess import Popen, PIPE
113-import re
114+from __future__ import print_function
115
116-# change those symbols to whatever you prefer
117-symbols = {
118- 'ahead of': '↑',
119- 'behind': '↓',
120- 'staged': '♦',
121- 'changed': '‣',
122- 'untracked': '…',
123- 'clean': '⚡',
124- 'unmerged': '≠',
125- 'sha1': ':'
126-}
127+import sys
128+import re
129+import shlex
130+from subprocess import Popen, PIPE, check_output
131
132-output, error = Popen(
133- ['git', 'status'], stdout=PIPE, stderr=PIPE, universal_newlines=True).communicate()
134
135-if error:
136- import sys
137- sys.exit(0)
138-lines = output.splitlines()
139+def get_tagname_or_hash():
140+ """return tagname if exists else hash"""
141+ cmd = 'git log -1 --format="%h%d"'
142+ output = check_output(shlex.split(cmd)).decode('utf-8').strip()
143+ hash_, tagname = None, None
144+ # get hash
145+ m = re.search('\(.*\)$', output)
146+ if m:
147+ hash_ = output[:m.start()-1]
148+ # get tagname
149+ m = re.search('tag: .*[,\)]', output)
150+ if m:
151+ tagname = 'tags/' + output[m.start()+len('tag: '): m.end()-1]
152
153-behead_re = re.compile(
154- r"^# Your branch is (ahead of|behind) '(.*)' by (\d+) commit")
155-diverge_re = re.compile(r"^# and have (\d+) and (\d+) different")
156+ if tagname:
157+ return tagname
158+ elif hash_:
159+ return hash_
160+ return None
161
162-status = ''
163-staged = re.compile(r'^# Changes to be committed:$', re.MULTILINE)
164-changed = re.compile(r'^# Changed but not updated:$', re.MULTILINE)
165-untracked = re.compile(r'^# Untracked files:$', re.MULTILINE)
166-unmerged = re.compile(r'^# Unmerged paths:$', re.MULTILINE)
167
168+# `git status --porcelain --branch` can collect all information
169+# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
170+po = Popen(['git', 'status', '--porcelain', '--branch'], stdout=PIPE, stderr=PIPE)
171+stdout, sterr = po.communicate()
172+if po.returncode != 0:
173+ sys.exit(0) # Not a git repository
174
175-def execute(*command):
176- out, err = Popen(stdout=PIPE, stderr=PIPE, *command).communicate()
177- if not err:
178- nb = len(out.splitlines())
179+# collect git status information
180+untracked, staged, changed, conflicts = [], [], [], []
181+ahead, behind = 0, 0
182+status = [(line[0], line[1], line[2:]) for line in stdout.decode('utf-8').splitlines()]
183+for st in status:
184+ if st[0] == '#' and st[1] == '#':
185+ if re.search('Initial commit on', st[2]):
186+ branch = st[2].split(' ')[-1]
187+ elif re.search('no branch', st[2]): # detached status
188+ branch = get_tagname_or_hash()
189+ elif len(st[2].strip().split('...')) == 1:
190+ branch = st[2].strip()
191+ else:
192+ # current and remote branch info
193+ branch, rest = st[2].strip().split('...')
194+ if len(rest.split(' ')) == 1:
195+ # remote_branch = rest.split(' ')[0]
196+ pass
197+ else:
198+ # ahead or behind
199+ divergence = ' '.join(rest.split(' ')[1:])
200+ divergence = divergence.lstrip('[').rstrip(']')
201+ for div in divergence.split(', '):
202+ if 'ahead' in div:
203+ ahead = int(div[len('ahead '):].strip())
204+ elif 'behind' in div:
205+ behind = int(div[len('behind '):].strip())
206+ elif st[0] == '?' and st[1] == '?':
207+ untracked.append(st)
208 else: