1## vim:ft=zsh 2## git support by: Frank Terbeck <ft@bewatermyfriend.org> 3## Distributed under the same BSD-ish license as zsh itself. 4 5setopt localoptions extendedglob NO_shwordsplit 6local gitdir gitbase gitbranch gitaction gitunstaged gitstaged gitsha1 7local stgitpatch stgitunapplied 8local -A hook_com 9 10VCS_INFO_git_getaction () { 11 local gitdir=$1 12 local tmp 13 14 for tmp in "${gitdir}/rebase-apply" \ 15 "${gitdir}/rebase" \ 16 "${gitdir}/../.dotest" ; do 17 if [[ -d ${tmp} ]] ; then 18 if [[ -f "${tmp}/rebasing" ]] ; then 19 gitaction="rebase" 20 elif [[ -f "${tmp}/applying" ]] ; then 21 gitaction="am" 22 else 23 gitaction="am/rebase" 24 fi 25 return 0 26 fi 27 done 28 29 for tmp in "${gitdir}/rebase-merge/interactive" \ 30 "${gitdir}/.dotest-merge/interactive" ; do 31 if [[ -f "${tmp}" ]] ; then 32 gitaction="rebase-i" 33 return 0 34 fi 35 done 36 37 for tmp in "${gitdir}/rebase-merge" \ 38 "${gitdir}/.dotest-merge" ; do 39 if [[ -d "${tmp}" ]] ; then 40 gitaction="rebase-m" 41 return 0 42 fi 43 done 44 45 if [[ -f "${gitdir}/MERGE_HEAD" ]] ; then 46 gitaction="merge" 47 return 0 48 fi 49 50 if [[ -f "${gitdir}/BISECT_LOG" ]] ; then 51 gitaction="bisect" 52 return 0 53 fi 54 55 if [[ -f "${gitdir}/CHERRY_PICK_HEAD" ]] ; then 56 if [[ -d "${gitdir}/sequencer" ]] ; then 57 gitaction=cherry-seq 58 else 59 gitaction=cherry 60 fi 61 return 0 62 fi 63 64 return 1 65} 66 67VCS_INFO_git_getbranch () { 68 local gitdir=$1 tmp actiondir 69 local gitsymref="${vcs_comm[cmd]} symbolic-ref HEAD" 70 71 actiondir='' 72 for tmp in "${gitdir}/rebase-apply" \ 73 "${gitdir}/rebase" \ 74 "${gitdir}/../.dotest"; do 75 if [[ -d ${tmp} ]]; then 76 actiondir=${tmp} 77 break 78 fi 79 done 80 if [[ -n ${actiondir} ]]; then 81 gitbranch="$(${(z)gitsymref} 2> /dev/null)" 82 [[ -z ${gitbranch} ]] && [[ -r ${actiondir}/head-name ]] \ 83 && gitbranch="$(< ${actiondir}/head-name)" 84 85 elif [[ -f "${gitdir}/MERGE_HEAD" ]] ; then 86 gitbranch="$(${(z)gitsymref} 2> /dev/null)" 87 [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/MERGE_HEAD)" 88 89 elif [[ -d "${gitdir}/rebase-merge" ]] ; then 90 gitbranch="$(< ${gitdir}/rebase-merge/head-name)" 91 92 elif [[ -d "${gitdir}/.dotest-merge" ]] ; then 93 gitbranch="$(< ${gitdir}/.dotest-merge/head-name)" 94 95 else 96 gitbranch="$(${(z)gitsymref} 2> /dev/null)" 97 98 if [[ $? -ne 0 ]] ; then 99 gitbranch="refs/tags/$(${vcs_comm[cmd]} describe --exact-match HEAD 2>/dev/null)" 100 101 if [[ $? -ne 0 ]] ; then 102 gitbranch="${${"$(< $gitdir/HEAD)"}[1,7]}..." 103 fi 104 fi 105 fi 106 107 return 0 108} 109 110gitdir=${vcs_comm[gitdir]} 111VCS_INFO_git_getbranch ${gitdir} 112if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision ; then 113 gitsha1=$(${vcs_comm[cmd]} rev-parse --quiet --verify HEAD) 114else 115 gitsha1='' 116fi 117gitbranch="${gitbranch##refs/[^/]##/}" 118 119if [[ -z ${gitdir} ]] || [[ -z ${gitbranch} ]] ; then 120 return 1 121fi 122 123if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "check-for-changes" && \ 124 [[ "$(${vcs_comm[cmd]} rev-parse --is-inside-git-dir 2> /dev/null)" != 'true' ]] && \ 125 ${vcs_comm[cmd]} rev-parse --quiet --verify HEAD &> /dev/null ; then 126 # Default: off - these are potentially expensive on big repositories 127 ${vcs_comm[cmd]} diff --no-ext-diff --ignore-submodules --quiet --exit-code || 128 gitunstaged=1 129 ${vcs_comm[cmd]} diff-index --cached --quiet --ignore-submodules HEAD 2> /dev/null 130 (( $? && $? != 128 )) && gitstaged=1 131fi 132 133VCS_INFO_adjust 134VCS_INFO_git_getaction ${gitdir} 135gitbase=$( ${vcs_comm[cmd]} rev-parse --show-toplevel ) 136rrn=${gitbase:t} 137 138local patchdir=${gitdir}/patches/${gitbranch} 139if [[ -d $patchdir ]] && [[ -f $patchdir/applied ]] \ 140 && [[ -f $patchdir/unapplied ]] 141then 142 local -a stgit_applied stgit_unapplied stgit_all 143 144 stgit_applied=(${(f)"$(< "${patchdir}/applied")"}) 145 stgit_applied=( ${(Oa)stgit_applied} ) 146 stgit_unapplied=(${(f)"$(< "${patchdir}/unapplied")"}) 147 stgit_unapplied=( ${(oa)stgit_unapplied} ) 148 stgit_all=( ${(Oa)stgit_applied} ${stgit_unapplied} ) 149 150 if VCS_INFO_hook 'gen-applied-string' "${stgit_applied[@]}"; then 151 if (( ${#stgit_applied} )); then 152 stgitpatch=${stgit_applied[1]} 153 else 154 stgitpatch="" 155 fi 156 else 157 stgitpatch=${hook_com[patch-string]} 158 fi 159 hook_com=() 160 if VCS_INFO_hook 'gen-unapplied-string' "${stgit_unapplied[@]}"; then 161 stgitunapplied=${#stgit_unapplied} 162 else 163 stgitunapplied=${hook_com[unapplied-string]} 164 fi 165 166 if (( ${#stgit_applied} )); then 167 zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" patch-format stgitmsg || stgitmsg="%p (%n applied)" 168 else 169 zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" nopatch-format stgitmsg || stgitmsg="no patch applied" 170 fi 171 hook_com=( applied "${stgitpatch}" unapplied "${stgitunapplied}" 172 applied-n ${#stgit_applied} unapplied-n ${#stgit_unapplied} all-n ${#stgit_all} ) 173 if VCS_INFO_hook 'set-patch-format' "${stgitmsg}"; then 174 zformat -f stgitmsg "${stgitmsg}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \ 175 "n:${#stgit_applied}" "c:${#stgit_unapplied}" "a:${#stgit_all}" 176 else 177 stgitmsg=${hook_com[patch-replace]} 178 fi 179 hook_com=() 180else 181 stgitmsg='' 182fi 183 184backend_misc[patches]="${stgitmsg}" 185VCS_INFO_formats "${gitaction}" "${gitbranch}" "${gitbase}" "${gitstaged}" "${gitunstaged}" "${gitsha1}" "${stgitmsg}" 186return 0 187