## vim:ft=zsh ## git support by: Frank Terbeck ## Distributed under the same BSD-ish license as zsh itself. setopt localoptions extendedglob NO_shwordsplit local gitdir gitbase gitbranch gitaction gitunstaged gitstaged gitsha1 VCS_INFO_git_getaction () { local gitaction='' gitdir=$1 local tmp for tmp in "${gitdir}/rebase-apply" \ "${gitdir}/rebase" \ "${gitdir}/../.dotest" ; do if [[ -d ${tmp} ]] ; then if [[ -f "${tmp}/rebasing" ]] ; then gitaction="rebase" elif [[ -f "${tmp}/applying" ]] ; then gitaction="am" else gitaction="am/rebase" fi printf '%s' ${gitaction} return 0 fi done for tmp in "${gitdir}/rebase-merge/interactive" \ "${gitdir}/.dotest-merge/interactive" ; do if [[ -f "${tmp}" ]] ; then printf '%s' "rebase-i" return 0 fi done for tmp in "${gitdir}/rebase-merge" \ "${gitdir}/.dotest-merge" ; do if [[ -d "${tmp}" ]] ; then printf '%s' "rebase-m" return 0 fi done if [[ -f "${gitdir}/MERGE_HEAD" ]] ; then printf '%s' "merge" return 0 fi if [[ -f "${gitdir}/BISECT_LOG" ]] ; then printf '%s' "bisect" return 0 fi return 1 } VCS_INFO_git_getbranch () { local gitbranch gitdir=$1 local gitsymref="${vcs_comm[cmd]} symbolic-ref HEAD" if [[ -d "${gitdir}/rebase-apply" ]] \ || [[ -d "${gitdir}/rebase" ]] \ || [[ -d "${gitdir}/../.dotest" ]] \ || [[ -f "${gitdir}/MERGE_HEAD" ]] ; then gitbranch="$(${(z)gitsymref} 2> /dev/null)" [[ -z ${gitbranch} ]] && [[ -r ${gitdir}/rebase-apply/head-name ]] \ && gitbranch="$(< ${gitdir}/rebase-apply/head-name)" elif [[ -f "${gitdir}/rebase-merge/interactive" ]] \ || [[ -d "${gitdir}/rebase-merge" ]] ; then gitbranch="$(< ${gitdir}/rebase-merge/head-name)" elif [[ -f "${gitdir}/.dotest-merge/interactive" ]] \ || [[ -d "${gitdir}/.dotest-merge" ]] ; then gitbranch="$(< ${gitdir}/.dotest-merge/head-name)" else gitbranch="$(${(z)gitsymref} 2> /dev/null)" if [[ $? -ne 0 ]] ; then gitbranch="refs/tags/$(${vcs_comm[cmd]} describe --exact-match HEAD 2>/dev/null)" if [[ $? -ne 0 ]] ; then gitbranch="${${"$(< $gitdir/HEAD)"}[1,7]}..." fi fi fi printf '%s' "${gitbranch}" return 0 } VCS_INFO_git_get_stgit_top_patch () { local patchdir=$1 if [[ -d "$patchdir" ]]; then local -a patches patches=(${(f)"$(< "${patchdir}/applied")"}) printf '%s' $patches[-1] return 0 fi return 1 } VCS_INFO_git_get_stgit_unapplied() { local patchdir=$1 if [[ -d "$patchdir" ]]; then local -a patches patches=(${(f)"$(< "${patchdir}/unapplied")"}) if [[ -z $patches[@] ]]; then printf 0 else printf '%d' $#patches fi return 0 fi return 1 } gitdir=${vcs_comm[gitdir]} gitbranch="$(VCS_INFO_git_getbranch ${gitdir})" if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision && \ [[ ${gitbranch} == refs/* ]] && \ [[ -r "${gitdir}/${gitbranch}" ]] ; then gitsha1="${"$(< $gitdir/$gitbranch)"}" else gitsha1='' fi gitbranch="${gitbranch##refs/[^/]##/}" if [[ -z ${gitdir} ]] || [[ -z ${gitbranch} ]] ; then return 1 fi if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "check-for-changes" ; then # Default: off - these are potentially expensive on big repositories ${vcs_comm[cmd]} diff --no-ext-diff --ignore-submodules --quiet --exit-code || gitunstaged=1 ${vcs_comm[cmd]} diff-index --cached --quiet --ignore-submodules HEAD || gitstaged=1 fi VCS_INFO_adjust gitaction="$(VCS_INFO_git_getaction ${gitdir})" gitbase=${PWD%/${$( ${vcs_comm[cmd]} rev-parse --show-prefix )%/##}} rrn=${gitbase:t} local patchdir=${gitdir}/patches/${gitbranch} if [[ -d $patchdir ]] ; then stgitpatch=$(VCS_INFO_git_get_stgit_top_patch "${patchdir}") stgitunapplied=$(VCS_INFO_git_get_stgit_unapplied "${patchdir}") stgitpatch=${stgitpatch:-"no patch applied"} zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" stgitformat stgitmsg || stgitmsg=" %p (%c)" zformat -f stgitmsg "${stgitmsg}" "p:${stgitpatch}" "c:${stgitunapplied}" gitmisc=${stgitmsg} else gitmisc='' fi VCS_INFO_formats "${gitaction}" "${gitbranch}" "${gitbase}" "${gitstaged}" "${gitunstaged}" "${gitsha1}" "${gitmisc}" return 0