diff options
Diffstat (limited to 'plugins/git-prompt/gitstatus.py')
| -rw-r--r-- | plugins/git-prompt/gitstatus.py | 123 | 
1 files changed, 53 insertions, 70 deletions
| diff --git a/plugins/git-prompt/gitstatus.py b/plugins/git-prompt/gitstatus.py index 256841432..d944fd4ed 100644 --- a/plugins/git-prompt/gitstatus.py +++ b/plugins/git-prompt/gitstatus.py @@ -1,82 +1,65 @@  #!/usr/bin/env python -# -*- coding: UTF-8 -*- -from subprocess import Popen, PIPE -import re - -# change those symbols to whatever you prefer -symbols = { -    'ahead of': '↑', -    'behind': '↓', -    'staged': '♦', -    'changed': '‣', -    'untracked': '…', -    'clean': '⚡', -    'unmerged': '≠', -    'sha1': ':' -} +from __future__ import print_function -output, error = Popen( -    ['git', 'status'], stdout=PIPE, stderr=PIPE, universal_newlines=True).communicate() +# change this symbol to whatever you prefer +prehash = ':' -if error: -    import sys -    sys.exit(0) -lines = output.splitlines() +from subprocess import Popen, PIPE -behead_re = re.compile( -    r"^# Your branch is (ahead of|behind) '(.*)' by (\d+) commit") -diverge_re = re.compile(r"^# and have (\d+) and (\d+) different") +import sys +gitsym = Popen(['git', 'symbolic-ref', 'HEAD'], stdout=PIPE, stderr=PIPE) +branch, error = gitsym.communicate() -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) +error_string = error.decode('utf-8') +if 'fatal: Not a git repository' in error_string: +	sys.exit(0) -def execute(*command): -    out, err = Popen(stdout=PIPE, stderr=PIPE, *command).communicate() -    if not err: -        nb = len(out.splitlines()) -    else: -        nb = '?' -    return nb +branch = branch.decode("utf-8").strip()[11:] -if staged.search(output): -    nb = execute( -        ['git', 'diff', '--staged', '--name-only', '--diff-filter=ACDMRT']) -    status += '%s%s' % (symbols['staged'], nb) -if unmerged.search(output): -    nb = execute(['git', 'diff', '--staged', '--name-only', '--diff-filter=U']) -    status += '%s%s' % (symbols['unmerged'], nb) -if changed.search(output): -    nb = execute(['git', 'diff', '--name-only', '--diff-filter=ACDMRT']) -    status += '%s%s' % (symbols['changed'], nb) -if untracked.search(output): -    status += symbols['untracked'] -if status == '': -    status = symbols['clean'] +res, err = Popen(['git','diff','--name-status'], stdout=PIPE, stderr=PIPE).communicate() +err_string = err.decode('utf-8') +if 'fatal' in err_string: +	sys.exit(0) +changed_files = [namestat[0] for namestat in res.decode("utf-8").splitlines()] +staged_files = [namestat[0] for namestat in Popen(['git','diff', '--staged','--name-status'], stdout=PIPE).communicate()[0].splitlines()] +nb_changed = len(changed_files) - changed_files.count('U') +nb_U = staged_files.count('U') +nb_staged = len(staged_files) - nb_U +staged = str(nb_staged) +conflicts = str(nb_U) +changed = str(nb_changed) +nb_untracked = len([0 for status in Popen(['git','status','--porcelain',],stdout=PIPE).communicate()[0].decode("utf-8").splitlines() if status.startswith('??')]) +untracked = str(nb_untracked) -remote = '' +ahead, behind = 0,0 -bline = lines[0] -if bline.find('Not currently on any branch') != -1: -    branch = symbols['sha1'] + Popen([ -        'git', -        'rev-parse', -        '--short', -        'HEAD'], stdout=PIPE).communicate()[0][:-1] +if not branch: # not on any branch +	branch = prehash + Popen(['git','rev-parse','--short','HEAD'], stdout=PIPE).communicate()[0].decode("utf-8")[:-1]  else: -    branch = bline.split(' ')[-1] -    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) +	remote_name = Popen(['git','config','branch.%s.remote' % branch], stdout=PIPE).communicate()[0].decode("utf-8").strip() +	if remote_name: +		merge_name = Popen(['git','config','branch.%s.merge' % branch], stdout=PIPE).communicate()[0].decode("utf-8").strip() +		if remote_name == '.': # local +			remote_ref = merge_name +		else: +			remote_ref = 'refs/remotes/%s/%s' % (remote_name, merge_name[11:]) +		revgit = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % remote_ref],stdout=PIPE, stderr=PIPE) +		revlist = revgit.communicate()[0] +		if revgit.poll(): # fallback to local +			revlist = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % merge_name],stdout=PIPE, stderr=PIPE).communicate()[0] +		behead = revlist.decode("utf-8").splitlines() +		ahead = len([x for x in behead if x[0]=='>']) +		behind = len(behead) - ahead + +out = ' '.join([ +	branch, +	str(ahead), +	str(behind), +	staged, +	conflicts, +	changed, +	untracked, +	]) +print(out, end='') -print('\n'.join([branch, remote, status])) | 
