]> git.alrj.org Git - zsh.d.git/blob - S60_git
256afc8c08ec9951e9cb3c1abfd52ad442937ea2
[zsh.d.git] / S60_git
1 #! /usr/bin/zsh
2
3 # Those can be used, for instance to construct the prompt:
4 __ZSH_GIT_BASEDIR=""
5 __ZSH_GIT_SUBDIR=""
6 __ZSH_GIT_BRANCH=""
7 __ZSH_GIT_ACTION=""
8 __ZSH_GIT_STATUS=""
9
10 __ZSH_GIT_VARS_INVALID=1
11 __ZSH_GIT_STATUS_INVALID=1
12
13
14 git_chpwd() {
15   # On cd, invalidate git status in prompt
16   __ZSH_GIT_VARS_INVALID=1
17 }
18
19
20 git_preexec() {
21   # On git command, invalidate git status in prompt
22   case "$1" in
23     git*)
24       __ZSH_GIT_VARS_INVALID=1
25       ;;
26   esac
27
28   # *any* command could invalidate the repository status (new file, ...)
29   __ZSH_GIT_STATUS_INVALID=1
30 }
31
32 git_get_status() {
33     # Return only git status
34     local gitstat gitstatus
35
36     gitstat=$(git status 2> /dev/null | grep '\(# Untracked\|# Changes\|# Changed but not updated:\)')
37     # 'fix for mcedit parser
38     gitstatus=""
39
40     if [[ $(echo ${gitstat} | grep -c "^# Changes to be committed:$") > 0 ]]; then
41       gitstatus='✚'
42     fi
43
44     if [[ $(echo ${gitstat} | grep -c "^\# Changed but not updated:$") > 0 || \
45           $(echo ${gitstat} | grep -c "^\# Changes not staged for commit:$") > 0 ]]; then
46       gitstatus="${gitstatus}✹"
47     fi
48
49     if [[ $(echo ${gitstat} | grep -c "^# Untracked files:$") > 0 ]]; then
50       gitstatus="${gitstatus}★"
51     fi
52
53     if [[ -z $gitstatus ]]; then
54       gitstatus="%{${fg_bold[green]}%}✔%{$reset_color%}"
55     else
56       gitstatus="%{${fg_bold[yellow]}%}$gitstatus%{$reset_color%}"
57     fi
58
59     echo $gitstatus
60 }
61
62
63 git_parse() {
64     local git_dir ref base_dir sub_dir action branch gitstat gitstatus
65
66     # If nothing has been invalidated
67     if [[ "${__ZSH_GIT_VARS_INVALID}" == "0" && "${__ZSH_GIT_STATUS_INVALID}" == "0" ]]; then
68       return
69     fi
70
71     # If only status has been invalidated
72     if [[ "${__ZSH_GIT_VARS_INVALID}" == "0" && "${__ZSH_GIT_STATUS_INVALID}" == "1" ]]; then
73       __ZSH_GIT_STATUS=$(git_get_status)
74       __ZSH_GIT_STATUS_INVALID=0
75       return
76     fi
77
78
79     # Git prompt variables are invalid. Update them.
80
81     git_dir=$(git rev-parse --git-dir 2> /dev/null) || return
82
83     if [[ "$(git rev-parse --is-bare-repository)" == "true" ]]; then
84       base_dir=${$(readlink -f "$git_dir")/$HOME/'~'}
85       sub_dir=${$(pwd)#$(readlink -f "$git_dir")}
86     else
87       base_dir=${$(readlink -f "$git_dir/..")/$HOME/'~'}
88       sub_dir=${$(pwd)#$(readlink -f "$git_dir/..")}
89     fi
90
91     sub_dir=${sub_dir#/}
92     ref=$(git symbolic-ref HEAD 2> /dev/null) || return
93
94     action=""
95
96     if [ -d "$git_dir/../.dotest" ]; then
97       if [ -f "$git_dir/../.dotest/rebasing" ]; then
98         action="-rebase"
99       elif [ -f "$git_dir/../.dotest/applying" ]; then
100         action="-am"
101       else
102         action="-am-rebase"
103       fi
104       branch="$ref"
105     elif [ -f "$git_dir/.dotest-merge/interactive" ]; then
106       action="-rebase-i"
107       branch="$(cat "$git_dir/.dotest-merge/head-name")"
108     elif [ -d "$git_dir/.dotest-merge" ]; then
109       action="-rebase-m"
110       branch="$(cat "$git_dir/.dotest-merge/head-name")"
111     elif [ -f "$git_dir/MERGE_HEAD" ]; then
112       action="-merge"
113       branch="$ref"
114     else
115       test -f "$git_dir/BISECT_LOG" && action="-bisect"
116       branch="$(git symbolic-ref HEAD 2>/dev/null)" || \
117         branch="$(git describe --exact-match HEAD 2>/dev/null)" || \
118         branch="$(cut -c1-7 "$git_dir/HEAD")..."
119     fi
120
121
122     __ZSH_GIT_BASEDIR="${base_dir}"
123     __ZSH_GIT_SUBDIR="${sub_dir}"
124     __ZSH_GIT_BRANCH="${branch#refs/heads/}"
125     __ZSH_GIT_ACTION="${action}"
126     __ZSH_GIT_STATUS=`git_get_status`
127
128     __ZSH_GIT_VARS_INVALID=0
129     __ZSH_GIT_STATUS_INVALID=0
130 }
131
132
133 chpwd_functions+='git_chpwd'
134 preexec_functions+='git_preexec'
135 precmd_functions+='git_parse'