]> git.madduck.net Git - etc/git.git/blob - .zsh/zshrc/parts.d/50-git

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

include merge commits in rebase
[etc/git.git] / .zsh / zshrc / parts.d / 50-git
1 #
2 # Git shell integration
3 #
4 # Copyright © 2018 martin f. krafft <madduck@madduck.net>
5 # Released under the terms of the Artistic Licence 2.0
6 #
7 # Source repository: http://git.madduck.net/v/etc/zsh.git
8 #
9
10 __is_git_repo()
11 {
12   emulate -L zsh
13   git rev-parse --is-inside-work-tree >/dev/null 2>&1
14 }
15
16 __git_get_reporoot()
17 {
18   emulate -L zsh
19   # return the full path to the root of the current git repository
20   [ -d "$GIT_DIR" ] && echo "$GIT_DIR" && return 0
21   local dir; dir="$PWD/$(git rev-parse --show-cdup)"
22   # do not use --show-toplevel because it resolves symlinks
23   echo $dir:a
24 }
25
26 __git_get_branch()
27 {
28   emulate -L zsh
29   # use oh-my-zsh prompt info function if it exists
30   $(command -v git_prompt_info) && return
31
32   # return the name of the git branch we're on
33   local ref gitdir
34   gitdir="$(git rev-parse --git-dir)"
35   ref=$(git --git-dir="$gitdir" symbolic-ref -q HEAD 2>/dev/null \
36      || git --git-dir="$gitdir" name-rev --name-only HEAD 2>/dev/null) || return 1
37   echo "${ref#refs/heads/}"
38 }
39
40 __git_set_prompt_variable() {
41   __is_git_repo || return
42
43   local reporoot="$(__git_get_reporoot)" ||
44     { zerror "could not determine git repository root"; return 1 }
45   local branch="$(__git_get_branch)" ||
46     { zerror "could not determine git branch"; return 1 }
47   if [ -n "$VCSH_REPO_NAME" ]; then
48     # if vcsh is used to get a subshell, then the repo root is the home
49     # directory, but we want to indicate the vcsh context too:
50     eval set -- $(__vcs_get_prompt_path_components "$HOME" "$branch")
51     set -- "vcsh:$VCSH_REPO_NAME" "$2" "$1${3:+/$3}"
52   else
53     eval set -- $(__vcs_get_prompt_path_components "$reporoot" "$branch")
54     if [ -d "$GIT_DIR" ]; then
55       set -- "${(D)GIT_DIR}" "$2" "${${1#$_D}%/}"
56     fi
57   fi
58   psvar[4]="$1${2:+|%B$2%b|}${3:-}"
59 }
60 add-zsh-hook chpwd __git_set_prompt_variable
61 __git_set_prompt_variable
62
63 __git_print_preprompt()
64 {
65   [[ $? -eq 0 ]] || return
66   emulate -L zsh
67   __is_git_repo || return
68   [ "$(git config --get core.bare)" = false ] || return
69   __on_networkfs && return
70
71   local COLUMNS=${COLUMNS:-80}
72   local LINES=${LINES:-25}
73
74   function output() {
75     emulate -L zsh
76     local title="$@"
77     local output; output=(${(f)"$(cat)"})
78
79     [[ ${#output} -ge 1 ]] || return
80
81     local statl="$(echo ${output[-1]} | sed -re 's@^\s*([0-9]+)[^,]+(, ([0-9]+) [^(]+\(([-+])\))(, ([0-9]+) [^(]+\(([-+])\))?@\1/\4\3/\7\6@')"
82
83     if [[ ${output[-2]## } = '...' ]]; then
84       print "${title} (${statl%/}, abbrev.):"
85       print "${(F)output[1,-3]}"
86       print " …"
87     else
88       print "${title} (${statl%/}):"
89       print "${(F)output[1,-2]}"
90     fi
91   }
92
93   function gitdiffstat() {
94     emulate -L zsh
95     local common_options="--stat=$((COLUMNS/2-1)),$((COLUMNS/4-2)),$(($LINES/3)) --relative"
96     eval git diff $common_options "$@" 2>/dev/null
97   }
98
99   local cached; cached=(${(f)"$(gitdiffstat --cached | output cached)"})
100   local changed; changed=(${(f)"$(gitdiffstat | output changed)"})
101
102   local max=${#changed}
103   [[ $max -lt ${#cached} ]] && max=${#cached}
104
105   ((max == 0)) && return
106
107   local width=$(((COLUMNS-3)/2))
108
109   if (( ${#cached} > 0 && ${#changed} > 0 )); then
110     local i
111     for (( i=1 ; i <= max ; i++ )) do
112       printf "%-${width}s │ %-${width}s\n" "${cached[$i]}" "${changed[$i]}"
113     done
114   else
115     print ${(F)cached}${(F)changed}
116   fi
117 }
118 add-zsh-hook precmd __git_print_preprompt
119
120 # vim:ft=zsh