Diff
1diff --git a/plugins/git-prompt/gitstatus.py b/plugins/git-prompt/gitstatus.py
2index 903ad474d4be0f4a7c1a6a3670d999f2cb2015e8..2f02e5fcc439acba56417bf8667b84479cac1ea2 100644
3--- a/plugins/git-prompt/gitstatus.py
4+++ b/plugins/git-prompt/gitstatus.py
5@@ -5,25 +5,40 @@ from __future__ import print_function
6 prehash = ':'
7
8 import sys
9-import subprocess
10 from subprocess import Popen, PIPE
11
12-branch, error = Popen(['git', 'symbolic-ref', 'HEAD'], stdout=PIPE, stderr=PIPE).communicate()
13
14-if 'fatal: Not a git repository' in error.decode('utf-8'):
15- sys.exit(0)
16+# `git status --porcelain -b` can collect all information
17+# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
18+po = Popen(['git', 'status', '--porcelain', '-b'], stdout=PIPE, stderr=PIPE)
19+stdout, sterr = po.communicate()
20+if po.returncode != 0:
21+ sys.exit(0) # Not a git repository
22
23-branch = branch.decode("utf-8").strip()[11:]
24-
25-# Get git status (staged, change, conflicts and untracked)
26-try:
27- res = subprocess.check_output(['git', 'status', '--porcelain'])
28-except subprocess.CalledProcessError:
29- sys.exit(0)
30-status = [(st[0], st[1], st[2:]) for st in res.splitlines()]
31+# collect git status information
32 untracked, staged, changed, conflicts = [], [], [], []
33+ahead, behind = 0, 0
34+status = [(line[0], line[1], line[2:]) for line in stdout.splitlines()]
35 for st in status:
36- if st[0] == '?' and st[1] == '?':
37+ if st[0] == '#' and st[1] == '#':
38+ if len(st[2].strip().split('...')) == 1:
39+ branch = st[2].strip()
40+ else:
41+ # current and remote branch info
42+ branch, rest = st[2].strip().split('...')
43+ if len(rest.split(' ')) == 1:
44+ # remote_branch = rest.split(' ')[0]
45+ pass
46+ else:
47+ # ahead or behind
48+ divergence = ' '.join(rest.split(' ')[1:])
49+ divergence = divergence.lstrip('[').rstrip(']')
50+ for div in divergence.split(', '):
51+ if 'ahead' in div:
52+ ahead = int(div[len('ahead '):].strip())
53+ elif 'behind' in div:
54+ behind = int(div[len('behind '):].strip())
55+ elif st[0] == '?' and st[1] == '?':
56 untracked.append(st)
57 else:
58 if st[1] == 'M':
59@@ -33,26 +48,6 @@ for st in status:
60 elif st[0] != ' ':
61 staged.append(st)
62
63-ahead, behind = 0,0
64-
65-if not branch: # not on any branch
66- branch = prehash + Popen(['git','rev-parse','--short','HEAD'], stdout=PIPE).communicate()[0].decode("utf-8")[:-1]
67-else:
68- remote_name = Popen(['git','config','branch.%s.remote' % branch], stdout=PIPE).communicate()[0].decode("utf-8").strip()
69- if remote_name:
70- merge_name = Popen(['git','config','branch.%s.merge' % branch], stdout=PIPE).communicate()[0].decode("utf-8").strip()
71- if remote_name == '.': # local
72- remote_ref = merge_name
73- else:
74- remote_ref = 'refs/remotes/%s/%s' % (remote_name, merge_name[11:])
75- revgit = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % remote_ref],stdout=PIPE, stderr=PIPE)
76- revlist = revgit.communicate()[0]
77- if revgit.poll(): # fallback to local
78- revlist = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % merge_name],stdout=PIPE, stderr=PIPE).communicate()[0]
79- behead = revlist.decode("utf-8").splitlines()
80- ahead = len([x for x in behead if x[0]=='>'])
81- behind = len(behead) - ahead
82-
83 out = ' '.join([
84 branch,
85 str(ahead),