diff --git a/git-prompt/gitstatus.py b/git-prompt/gitstatus.py new file mode 100755 index 000000000..657db4634 --- /dev/null +++ b/git-prompt/gitstatus.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +from __future__ import print_function + +# change those symbols to whatever you prefer +symbols = {'ahead of': '↑', 'behind': '↓', 'prehash':':'} + +from subprocess import Popen, PIPE + +import sys +gitsym = Popen(['git', 'symbolic-ref', 'HEAD'], stdout=PIPE, stderr=PIPE) +branch, error = gitsym.communicate() + +error_string = error.decode('utf-8') + +if 'fatal: Not a git repository' in error_string: + sys.exit(0) + +branch = branch.strip()[11:] + +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.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(Popen(['git','ls-files','--others','--exclude-standard'],stdout=PIPE).communicate()[0].splitlines()) +untracked = str(nb_untracked) +if not nb_changed and not nb_staged and not nb_U and not nb_untracked: + clean = '1' +else: + clean = '0' + +remote = '' + +if not branch: # not on any branch + branch = symbols['prehash']+ Popen(['git','rev-parse','--short','HEAD'], stdout=PIPE).communicate()[0][:-1] +else: + remote_name = Popen(['git','config','branch.%s.remote' % branch], stdout=PIPE).communicate()[0].strip() + if remote_name: + merge_name = Popen(['git','config','branch.%s.merge' % branch], stdout=PIPE).communicate()[0].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.splitlines() + ahead = len([x for x in behead if x[0]=='>']) + behind = len(behead) - ahead + if behind: + remote += '%s%s' % (symbols['behind'], behind) + if ahead: + remote += '%s%s' % (symbols['ahead of'], ahead) + +out = '\n'.join([ + str(branch), + remote, + staged, + conflicts, + changed, + untracked, + clean]) +print(out) + diff --git a/git-prompt/zshrc.sh b/git-prompt/zshrc.sh new file mode 100644 index 000000000..497cef5fa --- /dev/null +++ b/git-prompt/zshrc.sh @@ -0,0 +1,92 @@ +# To install source this file from your .zshrc file + +# Change this to reflect your installation directory +export __GIT_PROMPT_DIR=~/.oh-my-zsh/git-prompt +# Initialize colors. +autoload -U colors +colors + +# Allow for functions in the prompt. +setopt PROMPT_SUBST + +autoload -U add-zsh-hook + +add-zsh-hook chpwd chpwd_update_git_vars +add-zsh-hook preexec preexec_update_git_vars +add-zsh-hook precmd precmd_update_git_vars + +## Function definitions +function preexec_update_git_vars() { + case "$2" in + git*|'g '*|'cp '*|'mv '*|'rm '*|vim|'vim '*|fg|'fg '*) + __EXECUTED_GIT_COMMAND=1 + ;; + esac +} + +function precmd_update_git_vars() { + if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ -n "$ZSH_THEME_GIT_PROMPT_NOCACHE" ]; then + update_current_git_vars + unset __EXECUTED_GIT_COMMAND + fi +} + +function chpwd_update_git_vars() { + update_current_git_vars +} + +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_BRANCH=$__CURRENT_GIT_STATUS[1] + GIT_REMOTE=$__CURRENT_GIT_STATUS[2] + GIT_STAGED=$__CURRENT_GIT_STATUS[3] + GIT_CONFLICTS=$__CURRENT_GIT_STATUS[4] + GIT_CHANGED=$__CURRENT_GIT_STATUS[5] + GIT_UNTRACKED=$__CURRENT_GIT_STATUS[6] + GIT_CLEAN=$__CURRENT_GIT_STATUS[7] +} + + +git_super_status() { + precmd_update_git_vars + if [ -n "$__CURRENT_GIT_STATUS" ]; then + STATUS="$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH" + if [ -n "$GIT_REMOTE" ]; then + STATUS="$ZSH_THEME_GIT_PROMPT_SEPARATOR$STATUS" + STATUS="$ZSH_THEME_GIT_PROMPT_REMOTE$GIT_REMOTE$STATUS" + fi + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR" + if [ "$GIT_STAGED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED" + fi + if [ "$GIT_CONFLICTS" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS" + fi + if [ "$GIT_CHANGED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED" + fi + if [ "$GIT_UNTRACKED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED$GIT_UNTRACKED" + fi + if [ "$GIT_CLEAN" -eq "1" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN" + fi + echo "$ZSH_THEME_GIT_PROMPT_PREFIX$STATUS$ZSH_THEME_GIT_PROMPT_SUFFIX" + fi +} + +# Default values for the appearance of the prompt. Configure at will. +ZSH_THEME_GIT_PROMPT_PREFIX="%{$my_gray%}‹%{$reset_color%}" +ZSH_THEME_GIT_PROMPT_SUFFIX="%{$my_gray%}›%{$reset_color%}" +ZSH_THEME_GIT_PROMPT_SEPARATOR="%{$my_gray%}/" +ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}" +ZSH_THEME_GIT_PROMPT_REMOTE="%{$fg_bold[yellow]%}" +ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}○" +ZSH_THEME_GIT_PROMPT_STAGED="%{$fg_bold[green]%}●" +ZSH_THEME_GIT_PROMPT_CHANGED="%{$fg_bold[red]%}+" +ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg_bold[red]%}*" +ZSH_THEME_GIT_PROMPT_CONFLICTS="%{$fg_bold[red]%}×"