94007f7db2d47f3e13e4aac878f0e780a479f628

Author
Kentaro Wada <www.kentaro.wada@gmail.com>
Committer
Marc Cornellà <marc.cornella@live.com>
Date

Message

git-prompt: collect all git status information by one cmd

This commit uses the `git status --porcelain -b` format to gather the
number of ahead and behind commits related to the remote branch.

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),