diff options
| author | Tim O'Brien <timo@t413.com> | 2015-09-14 15:39:18 -0700 | 
|---|---|---|
| committer | Tim O'Brien <timo@t413.com> | 2015-09-14 15:39:18 -0700 | 
| commit | e8639c700ebbf8aa416c0d14c8e3a292f1062dd7 (patch) | |
| tree | 7705714541cc8781a1be7e1d2343d34e5e8aa9b1 /plugins/git-prompt | |
| parent | 797e1f9a64c0d2775723bb28c76745b327f86d56 (diff) | |
| parent | 9c08641d7c2aae0c82fa5ad91f94c67b70115ba5 (diff) | |
| download | zsh-e8639c700ebbf8aa416c0d14c8e3a292f1062dd7.tar.gz zsh-e8639c700ebbf8aa416c0d14c8e3a292f1062dd7.tar.bz2 zsh-e8639c700ebbf8aa416c0d14c8e3a292f1062dd7.zip | |
Update to current robbyrussell/oh-my-zsh master
Diffstat (limited to 'plugins/git-prompt')
| -rw-r--r-- | plugins/git-prompt/git-prompt.plugin.zsh | 89 | ||||
| -rw-r--r-- | plugins/git-prompt/gitstatus.py | 146 | 
2 files changed, 136 insertions, 99 deletions
| diff --git a/plugins/git-prompt/git-prompt.plugin.zsh b/plugins/git-prompt/git-prompt.plugin.zsh index d868a5fe1..5175bf70f 100644 --- a/plugins/git-prompt/git-prompt.plugin.zsh +++ b/plugins/git-prompt/git-prompt.plugin.zsh @@ -1,57 +1,92 @@  # ZSH Git Prompt Plugin from:  # http://github.com/olivierverdier/zsh-git-prompt -# -export __GIT_PROMPT_DIR=$ZSH/plugins/git-prompt -# Allow for functions in the prompt. -setopt PROMPT_SUBST +__GIT_PROMPT_DIR="${0:A:h}" -## Enable auto-execution of functions. -typeset -ga preexec_functions -typeset -ga precmd_functions -typeset -ga chpwd_functions - -# Append git functions needed for prompt. -preexec_functions+='preexec_update_git_vars' -precmd_functions+='precmd_update_git_vars' -chpwd_functions+='chpwd_update_git_vars' +## Hook function definitions +function chpwd_update_git_vars() { +    update_current_git_vars +} -## Function definitions  function preexec_update_git_vars() {      case "$2" in -        git*) +        git*|hub*|gh*|stg*)          __EXECUTED_GIT_COMMAND=1          ;;      esac  }  function precmd_update_git_vars() { -    if [ -n "$__EXECUTED_GIT_COMMAND" ]; then +    if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ ! -n "$ZSH_THEME_GIT_PROMPT_CACHE" ]; then          update_current_git_vars          unset __EXECUTED_GIT_COMMAND      fi  } -function chpwd_update_git_vars() { -    update_current_git_vars -} +chpwd_functions+=(chpwd_update_git_vars) +precmd_functions+=(precmd_update_git_vars) +preexec_functions+=(preexec_update_git_vars) + +## Function definitions  function update_current_git_vars() {      unset __CURRENT_GIT_STATUS      local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py" -    _GIT_STATUS=`python ${gitstatus}` -    __CURRENT_GIT_STATUS=("${(f)_GIT_STATUS}") +    _GIT_STATUS=$(python ${gitstatus} 2>/dev/null) +     __CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}") +    GIT_BRANCH=$__CURRENT_GIT_STATUS[1] +    GIT_AHEAD=$__CURRENT_GIT_STATUS[2] +    GIT_BEHIND=$__CURRENT_GIT_STATUS[3] +    GIT_STAGED=$__CURRENT_GIT_STATUS[4] +    GIT_CONFLICTS=$__CURRENT_GIT_STATUS[5] +    GIT_CHANGED=$__CURRENT_GIT_STATUS[6] +    GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7]  } -function prompt_git_info() { +git_super_status() { +    precmd_update_git_vars      if [ -n "$__CURRENT_GIT_STATUS" ]; then -        echo "(%{${fg[red]}%}$__CURRENT_GIT_STATUS[1]%{${fg[default]}%}$__CURRENT_GIT_STATUS[2]%{${fg[magenta]}%}$__CURRENT_GIT_STATUS[3]%{${fg[default]}%})" +      STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}" +      if [ "$GIT_BEHIND" -ne "0" ]; then +          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}" +      fi +      if [ "$GIT_AHEAD" -ne "0" ]; then +          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD$GIT_AHEAD%{${reset_color}%}" +      fi +      STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR" +      if [ "$GIT_STAGED" -ne "0" ]; then +          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED%{${reset_color}%}" +      fi +      if [ "$GIT_CONFLICTS" -ne "0" ]; then +          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS%{${reset_color}%}" +      fi +      if [ "$GIT_CHANGED" -ne "0" ]; then +          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}" +      fi +      if [ "$GIT_UNTRACKED" -ne "0" ]; then +          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED%{${reset_color}%}" +      fi +      if [ "$GIT_CHANGED" -eq "0" ] && [ "$GIT_CONFLICTS" -eq "0" ] && [ "$GIT_STAGED" -eq "0" ] && [ "$GIT_UNTRACKED" -eq "0" ]; then +          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN" +      fi +      STATUS="$STATUS%{${reset_color}%}$ZSH_THEME_GIT_PROMPT_SUFFIX" +      echo "$STATUS"      fi  } +# Default values for the appearance of the prompt. +ZSH_THEME_GIT_PROMPT_PREFIX="(" +ZSH_THEME_GIT_PROMPT_SUFFIX=")" +ZSH_THEME_GIT_PROMPT_SEPARATOR="|" +ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}" +ZSH_THEME_GIT_PROMPT_STAGED="%{$fg[red]%}%{●%G%}" +ZSH_THEME_GIT_PROMPT_CONFLICTS="%{$fg[red]%}%{✖%G%}" +ZSH_THEME_GIT_PROMPT_CHANGED="%{$fg[blue]%}%{✚%G%}" +ZSH_THEME_GIT_PROMPT_BEHIND="%{↓%G%}" +ZSH_THEME_GIT_PROMPT_AHEAD="%{↑%G%}" +ZSH_THEME_GIT_PROMPT_UNTRACKED="%{…%G%}" +ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}%{✔%G%}" +  # Set the prompt. -#PROMPT='%B%m%~%b$(prompt_git_info) %# ' -# for a right prompt: -#RPROMPT='%b$(prompt_git_info)' -RPROMPT='$(prompt_git_info)' +RPROMPT='$(git_super_status)' diff --git a/plugins/git-prompt/gitstatus.py b/plugins/git-prompt/gitstatus.py index 256841432..a8eb8284b 100644 --- a/plugins/git-prompt/gitstatus.py +++ b/plugins/git-prompt/gitstatus.py @@ -1,82 +1,84 @@  #!/usr/bin/env python -# -*- coding: UTF-8 -*- -from subprocess import Popen, PIPE -import re +from __future__ import print_function -# change those symbols to whatever you prefer -symbols = { -    'ahead of': '↑', -    'behind': '↓', -    'staged': '♦', -    'changed': '‣', -    'untracked': '…', -    'clean': '⚡', -    'unmerged': '≠', -    'sha1': ':' -} +import sys +import re +import shlex +from subprocess import Popen, PIPE, check_output -output, error = Popen( -    ['git', 'status'], stdout=PIPE, stderr=PIPE, universal_newlines=True).communicate() -if error: -    import sys -    sys.exit(0) -lines = output.splitlines() +def get_tagname_or_hash(): +    """return tagname if exists else hash""" +    cmd = 'git log -1 --format="%h%d"' +    output = check_output(shlex.split(cmd)).decode('utf-8').strip() +    hash_, tagname = None, None +    # get hash +    m = re.search('\(.*\)$', output) +    if m: +        hash_ = output[:m.start()-1] +    # get tagname +    m = re.search('tag: .*[,\)]', output) +    if m: +        tagname = 'tags/' + output[m.start()+len('tag: '): m.end()-1] -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") +    if tagname: +        return tagname +    elif hash_: +        return hash_ +    return None -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) +# `git status --porcelain --branch` can collect all information +# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind +po = Popen(['git', 'status', '--porcelain', '--branch'], stdout=PIPE, stderr=PIPE) +stdout, sterr = po.communicate() +if po.returncode != 0: +    sys.exit(0)  # Not a git repository -def execute(*command): -    out, err = Popen(stdout=PIPE, stderr=PIPE, *command).communicate() -    if not err: -        nb = len(out.splitlines()) +# collect git status information +untracked, staged, changed, conflicts = [], [], [], [] +ahead, behind = 0, 0 +status = [(line[0], line[1], line[2:]) for line in stdout.decode('utf-8').splitlines()] +for st in status: +    if st[0] == '#' and st[1] == '#': +        if re.search('Initial commit on', st[2]): +            branch = st[2].split(' ')[-1] +        elif re.search('no branch', st[2]):  # detached status +            branch = get_tagname_or_hash() +        elif len(st[2].strip().split('...')) == 1: +            branch = st[2].strip() +        else: +            # current and remote branch info +            branch, rest = st[2].strip().split('...') +            if len(rest.split(' ')) == 1: +                # remote_branch = rest.split(' ')[0] +                pass +            else: +                # ahead or behind +                divergence = ' '.join(rest.split(' ')[1:]) +                divergence = divergence.lstrip('[').rstrip(']') +                for div in divergence.split(', '): +                    if 'ahead' in div: +                        ahead = int(div[len('ahead '):].strip()) +                    elif 'behind' in div: +                        behind = int(div[len('behind '):].strip()) +    elif st[0] == '?' and st[1] == '?': +        untracked.append(st)      else: -        nb = '?' -    return nb - -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'] - -remote = '' - -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] -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) +        if st[1] == 'M': +            changed.append(st) +        if st[0] == 'U': +            conflicts.append(st) +        elif st[0] != ' ': +            staged.append(st) -print('\n'.join([branch, remote, status])) +out = ' '.join([ +    branch, +    str(ahead), +    str(behind), +    str(len(staged)), +    str(len(conflicts)), +    str(len(changed)), +    str(len(untracked)), +]) +print(out, end='') | 
