gitstatus.py 2.32 KB
Newer Older
ncanceill's avatar
ncanceill committed
1
#!/usr/bin/env python2
2
# -*- coding: UTF-8 -*-
3
4
from subprocess import Popen, PIPE
import re
5
6

# change those symbols to whatever you prefer
7
8
9
10
11
12
13
14
15
16
symbols = {
    'ahead of': '↑',
    'behind': '↓',
    'staged': '♦',
    'changed': '‣',
    'untracked': '…',
    'clean': '⚡',
    'unmerged': '≠',
    'sha1': ':'
}
17

18
output, error = Popen(
Paweł Tomak's avatar
Paweł Tomak committed
19
    ['git', 'status'], stdout=PIPE, stderr=PIPE, universal_newlines=True).communicate()
20
21

if error:
22
23
    import sys
    sys.exit(0)
24
25
lines = output.splitlines()

26
27
behead_re = re.compile(
    r"^# Your branch is (ahead of|behind) '(.*)' by (\d+) commit")
28
29
30
31
32
33
34
35
diverge_re = re.compile(r"^# and have (\d+) and (\d+) different")

status = ''
staged = re.compile(r'^# Changes to be committed:$', re.MULTILINE)
changed = re.compile(r'^# Changed but not updated:$', re.MULTILINE)
untracked = re.compile(r'^# Untracked files:$', re.MULTILINE)
unmerged = re.compile(r'^# Unmerged paths:$', re.MULTILINE)

36

37
def execute(*command):
38
39
40
41
42
43
    out, err = Popen(stdout=PIPE, stderr=PIPE, *command).communicate()
    if not err:
        nb = len(out.splitlines())
    else:
        nb = '?'
    return nb
44
45

if staged.search(output):
46
47
48
    nb = execute(
        ['git', 'diff', '--staged', '--name-only', '--diff-filter=ACDMRT'])
    status += '%s%s' % (symbols['staged'], nb)
49
if unmerged.search(output):
50
51
    nb = execute(['git', 'diff', '--staged', '--name-only', '--diff-filter=U'])
    status += '%s%s' % (symbols['unmerged'], nb)
52
if changed.search(output):
53
54
    nb = execute(['git', 'diff', '--name-only', '--diff-filter=ACDMRT'])
    status += '%s%s' % (symbols['changed'], nb)
55
if untracked.search(output):
56
    status += symbols['untracked']
57
if status == '':
58
    status = symbols['clean']
59
60
61
62
63

remote = ''

bline = lines[0]
if bline.find('Not currently on any branch') != -1:
64
65
66
67
68
    branch = symbols['sha1'] + Popen([
        'git',
        'rev-parse',
        '--short',
        'HEAD'], stdout=PIPE).communicate()[0][:-1]
69
else:
70
    branch = bline.split(' ')[-1]
71
72
73
74
75
76
77
78
79
80
    bstatusline = lines[1]
    match = behead_re.match(bstatusline)
    if match:
        remote = symbols[match.groups()[0]]
        remote += match.groups()[2]
    elif lines[2:]:
        div_match = diverge_re.match(lines[2])
        if div_match:
            remote = "{behind}{1}{ahead of}{0}".format(
                *div_match.groups(), **symbols)
81

82
print('\n'.join([branch, remote, status]))