1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-23 04:30:24 +02:00

Seth House, Simon Ruderich and myself: 27948: various vcs_info changes

Here's a diff-stat:

 Doc/Zsh/contrib.yo                                |  506 ++++++++++++++-------
 Functions/VCS_Info/.distfiles                     |    1 +
 Functions/VCS_Info/Backends/VCS_INFO_detect_hg    |   14 +-
 Functions/VCS_Info/Backends/VCS_INFO_get_data_git |   35 +-
 Functions/VCS_Info/Backends/VCS_INFO_get_data_hg  |  295 +++++++++----
 Functions/VCS_Info/VCS_INFO_formats               |   26 +-
 Functions/VCS_Info/VCS_INFO_hook                  |   10 +-
 Functions/VCS_Info/VCS_INFO_quilt                 |  190 ++++++++
 Functions/VCS_Info/vcs_info                       |   30 +-
 Misc/.distfiles                                   |    1 +
 Misc/vcs_info-examples                            |  496 ++++++++++++++++++++
 11 files changed, 1303 insertions(+), 301 deletions(-)

The major changes are vast improvements for the mercurial (hg) backend
(which was done almost entirely by Seth); improved documentation (mostly
done by Simon and again Seth); quilt support (as an addon and stand
alone, see the manual for details); a number of new hooks and a fair
share of bugfixes.
This commit is contained in:
Frank Terbeck 2010-05-10 10:46:48 +00:00
parent 144a06bf95
commit 0501efc54a
12 changed files with 1326 additions and 312 deletions

View file

@ -11,6 +11,7 @@ vcs_info_lastmsg
VCS_INFO_maxexports
VCS_INFO_nvcsformats
vcs_info_printsys
VCS_INFO_quilt
VCS_INFO_realpath
VCS_INFO_reposub
VCS_INFO_set

View file

@ -4,9 +4,17 @@
setopt localoptions NO_shwordsplit
[[ $1 == '--flavours' ]] && return 1
[[ $1 == '--flavours' ]] && { print -l hg-git hg-hgsubversion hg-hgsvn; return 0 }
VCS_INFO_check_com ${vcs_comm[cmd]} || return 1
vcs_comm[detect_need_file]=store
VCS_INFO_bydir_detect '.hg'
return $?
VCS_INFO_bydir_detect '.hg' || return 1
if [[ -d ${vcs_comm[basedir]}/.hg/svn ]] ; then
vcs_comm[overwrite_name]='hg-hgsubversion'
elif [[ -d ${vcs_comm[basedir]}/.hgsvn ]] ; then
vcs_comm[overwrite_name]='hg-hgsvn'
elif [[ -e ${vcs_comm[basedir]}/.hg/git-mapfile ]] ; then
vcs_comm[overwrite_name]='hg-git'
fi
return 0

View file

@ -3,7 +3,7 @@
## Distributed under the same BSD-ish license as zsh itself.
setopt localoptions extendedglob NO_shwordsplit
local gitdir gitbase gitbranch gitaction gitunstaged gitstaged gitsha1 gitmisc
local gitdir gitbase gitbranch gitaction gitunstaged gitstaged gitsha1
local stgitpatch stgitunapplied
local -xA hook_com
@ -139,33 +139,40 @@ if [[ -d $patchdir ]] ; then
stgit_unapplied=(${(f)"$(< "${patchdir}/unapplied")"})
stgit_unapplied=( ${(oa)stgit_applied} )
if VCS_INFO_hook 'gen-stgit-patch-string' "${stgit_applied[@]}"; then
if VCS_INFO_hook 'gen-applied-string' "${stgit_applied[@]}"; then
if (( ${#stgit_applied} )); then
stgitpatch=${stgit_applied[1]}
else
stgitpatch="no patch applied"
stgitpatch=""
fi
else
stgitpatch=${hook_com[stgit-patch-string]}
stgitpatch=${hook_com[patch-string]}
fi
if VCS_INFO_hook 'gen-stgit-unapplied-string' "${stgit_unapplied[@]}"; then
hook_com=()
if VCS_INFO_hook 'gen-unapplied-string' "${stgit_unapplied[@]}"; then
stgitunapplied=${#stgit_unapplied}
else
stgitunapplied=${hook_com[stgit-unapplied-string]}
stgitunapplied=${hook_com[unapplied-string]}
fi
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" stgitformat stgitmsg || stgitmsg=" %p (%c)"
hook_com=( patch "${stgitpatch}" unapplied "${stgitunapplied}" )
if VCS_INFO_hook 'set-stgit-format' "${stgitformat}"; then
zformat -f stgitmsg "${stgitmsg}" "p:${hook_com[patch]}" "c:${hook_com[unapplied]}"
gitmisc=${stgitmsg}
if (( ${#stgit_applied} )); then
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" patch-format stgitmsg || stgitmsg="%p (%n applied)"
else
gitmisc=${hook_com[stgit-replace]}
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" nopatch-format stgitmsg || stgitmsg="no patch applied"
fi
hook_com=( applied "${stgitpatch}" unapplied "${stgitunapplied}"
applied-n ${#stgit_applied} unapplied-n ${#stgit_unapplied} )
if VCS_INFO_hook 'set-patch-format' "${stgitmsg}"; then
zformat -f stgitmsg "${stgitmsg}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
"n:${#stgit_applied}" "c:${#stgit_unapplied}"
else
stgitmsg=${hook_com[patch-replace]}
fi
hook_com=()
else
gitmisc=''
stgitmsg=''
fi
VCS_INFO_formats "${gitaction}" "${gitbranch}" "${gitbase}" "${gitstaged}" "${gitunstaged}" "${gitsha1}" "${gitmisc}"
backend_misc[patches]="${stgitmsg}"
VCS_INFO_formats "${gitaction}" "${gitbranch}" "${gitbase}" "${gitstaged}" "${gitunstaged}" "${gitsha1}" "${stgitmsg}"
return 0

View file

@ -1,128 +1,239 @@
## vim:ft=zsh
## mercurial support by: Frank Terbeck <ft@bewatermyfriend.org>
## with large contributions by Seth House <seth@eseth.com>
## Distributed under the same BSD-ish license as zsh itself.
setopt localoptions NO_shwordsplit
local file hgbranch hgbranch_name hgbase hghash hglrev hgmqstring \
r_branch hgchanges revformat bookmarks r_bmhash r_bmname hgbmstring
local -i getbookmarks
local -a hgbm mqpatches hgmisc_args
setopt localoptions extendedglob NO_shwordsplit
local hgbase bmfile branchfile rebasefile dirstatefile mqseriesfile \
mqstatusfile mqguardsfile patchdir mergedir \
r_csetid r_lrev r_branch i_bmhash i_bmname \
revformat branchformat hgactionstring hgchanges \
hgbmstring hgmqstring applied_string unapplied_string guards_string
local -a hgid_args defrevformat defbranchformat \
hgbmarks mqpatches mqseries mqguards mqunapplied hgmisc \
i_patchguards i_negguards i_posguards
local -xA hook_com
hgbase=${vcs_comm[basedir]}
rrn=${hgbase:t}
r_csetid='' # changeset id (long hash)
r_lrev='' # local revision
patchdir="${hgbase}/.hg/patches"
mergedir="${hgbase}/.hg/merge/"
bmfile="${hgbase}/.hg/bookmarks"
branchfile="${hgbase}/.hg/branch"
rebasefile="${hgbase}/.hg/rebasestate"
dirstatefile="${hgbase}/.hg/dirstate"
mqstatusfile="${patchdir}/status" # currently applied patches
mqseriesfile="${patchdir}/series" # all patches
mqguardsfile="${patchdir}/guards"
file="${hgbase}/.hg/branch"
if [[ -r ${file} ]] ; then
hgbranch_name=$(< ${file})
else
hgbranch_name="default"
fi
# Look for any --flavours
VCS_INFO_adjust
hghash=''
hglrev=''
hgbm=()
bookmarks="${hgbase}/.hg/bookmarks"
# Calling the 'hg' program is quite a bit too slow for prompts.
# Disabled by default anyway, so no harm done.
if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision ; then
# Calling the 'hg' program is quite a bit too slow for prompts.
# If there's a way around that, I'd be interested.
# Disabled by default anyway, so no harm done.
local HGRCPATH
if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" \
"check-for-changes" ; then
HGRCPATH="/dev/null" ${vcs_comm[cmd]} id --debug -i -n -b \
| read -r hghash hglrev r_branch
# Are there uncommitted-changes?
if [[ $hglrev[-1] == + ]] ; then
hgchanges=1
fi
# Remove uncommitted-changes marker, if any
hglrev=${hglrev/+/}
hghash=${hghash/+/}
# Calling hexdump is (much) faster than hg but doesn't get the local rev
if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" use-simple \
&& ( VCS_INFO_check_com hexdump ) && [[ -r ${dirstatefile} ]] ; then
r_csetid=$(hexdump -n 20 -e '1/1 "%02x"' ${dirstatefile})
else
HGRCPATH="/dev/null" ${vcs_comm[cmd]} \
parents --template="{node} {rev} {branches}\n" \
| read -r hghash hglrev r_branch
fi
hgid_args=( --debug id -i -n -b )
if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "get-bookmarks" \
&& getbookmarks=1 || getbookmarks=0
# Looking for changes is a tad bit slower since the dirstate cache must
# first be refreshed before being read
zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" \
"check-for-changes" || hgid_args+=( -r. )
if (( getbookmarks )) && [[ -r "${bookmarks}" ]] ; then
while read -r r_bmhash r_bmname ; do
if [[ $hghash == $r_bmhash ]] ; then
hgbm=( "$r_bmname" ${hgbm} )
fi
done < ${bookmarks}
local HGRCPATH
HGRCPATH="/dev/null" ${vcs_comm[cmd]} ${(z)hgid_args} \
| read -r r_csetid r_lrev r_branch
fi
if [[ -n ${hglrev} ]] ; then
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" hgrevformat revformat || revformat="%r:%h"
hook_com=( localrev "${hglrev}" "hash" "${hghash}" )
if VCS_INFO_hook 'set-hgrev-format' "${revformat}"; then
zformat -f hglrev "${revformat}" "r:${hook_com[localrev]}" "h:${hook_com[hash]}"
else
hglrev=${hook_com[rev-replace]}
fi
hook_com=()
if (( getbookmarks )) ; then
if VCS_INFO_hook 'gen-hg-bookmark-string' "${hgbm[@]}"; then
hgbmstring=${(j.;.)hgbm}
else
hgbmstring=${hook_com[hg-bookmark-string]}
fi
hook_com=()
fi
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat hgbranch || hgbranch="%b:%r"
hook_com=( branch "${hgbranch_name}" revision "${hglrev}" )
if VCS_INFO_hook 'set-branch-format' "${hgbranch}"; then
zformat -f hgbranch "${hgbranch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
else
hgbranch=${hook_com[branch-replace]}
fi
hook_com=()
fi
else
hgbranch="${hgbranch_name}"
fi
local patchdir=${hgbase}/.hg/patches/
# If the user doesn't opt to invoke hg we can still get the current branch
if [[ -z ${r_branch} && -r ${branchfile} ]] ; then
r_branch=$(< ${branchfile})
else
r_branch="default"
fi
if [[ -d $patchdir ]] ; then
local -a mqpatches
if [[ -e "${patchdir}/status" ]]; then
# The working dir has uncommitted-changes if the revision ends with a +
if [[ $r_lrev[-1] == + ]] ; then
hgchanges=1
r_lrev=${r_lrev%+}
r_csetid=${r_csetid%+}
fi
# This directory only exists during a merge
[[ -d $mergedir ]] && hgactionstring="merging"
# This file only exists during a rebase
[[ -e $rebasefile ]] && hgactionstring="rebasing"
### Build the current revision display
[[ -n ${r_csetid} ]] && defrevformat+=( "%h" )
[[ -n ${r_lrev} ]] && defrevformat+=( "%r" )
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" \
"hgrevformat" revformat || revformat=${(j/:/)defrevformat}
hook_com=( localrev "${r_lrev}" "hash" "${r_csetid}" )
if VCS_INFO_hook 'set-hgrev-format' "${revformat}"; then
zformat -f r_lrev "${revformat}" \
"r:${hook_com[localrev]}" "h:${hook_com[hash]}"
else
r_lrev=${hook_com[rev-replace]}
fi
hook_com=()
### Build the branch display
[[ -n ${r_branch} ]] && defbranchformat+=( "%b" )
[[ -n ${r_lrev} ]] && defbranchformat+=( "%r" )
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" \
branchformat branchformat || branchformat=${(j/:/)defbranchformat}
hook_com=( branch "${r_branch}" revision "${r_lrev}" )
if VCS_INFO_hook 'set-branch-format' "${branchformat}"; then
zformat -f branchformat "${branchformat}" \
"b:${hook_com[branch]}" "r:${hook_com[revision]}"
else
branchformat=${hook_com[branch-replace]}
fi
hook_com=()
### Look for current Bookmarks (this requires knowing the changeset id)
if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-bookmarks \
&& [[ -r "${bmfile}" ]] && [[ -n "$r_csetid" ]] ; then
while read -r i_bmhash i_bmname ; do
# Compare hash in bookmarks file with changeset id
[[ $r_csetid == $i_bmhash ]] && hgbmarks+=( $i_bmname )
done < ${bmfile}
if VCS_INFO_hook 'gen-hg-bookmark-string' "${hgbmarks[@]}"; then
hgbmstring=${(j:, :)hgbmarks}
else
hgbmstring=${hook_com[hg-bookmark-string]}
fi
hook_com=()
fi
### Look for any applied Mercurial Queue patches
if zstyle -T ":vcs_info:${vcs}:${usercontext}:${rrn}" get-mq \
&& [[ -d $patchdir ]] ; then
if [[ -e $mqstatusfile ]]; then
mqpatches=( ${${(f)"$(< "${patchdir}/status")"}/(#s)[a-f0-9]##:/} )
mqpatches=( ${(Oa)mqpatches} )
else
mqpatches=( )
fi
if VCS_INFO_hook 'gen-mq-patch-string' "${mqpatches[@]}"; then
if (( ${#mqpatches} )); then
hgmqstring=${mqpatches[1]}
else
hgmqstring="no patch applied"
if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-unapplied \
&& [[ -r ${mqseriesfile} ]]; then
# Okay, here's a little something that assembles a list of unapplied
# patches that takes into account if mq-guards are active or not.
# Collect active guards
if [[ -r ${mqguardsfile} ]]; then
mqguards=( ${(f)"$(< "${mqguardsfile}")"} )
mqguards=( ${(oa)mqguards} )
fi
else
hgbmstring=${hook_com[hg-mqpatch-string]}
while read -r i_patch i_patchguards ; do
# Skip commented lines
[[ ${i_patch} == [[:space:]]#"#"* ]] && continue
# Keep list of all patches
mqseries+=( $i_patch )
# Separate negative and positive guards to more easily find the
# intersection of active guards with patch guards
i_patchguards=( ${(s: :)i_patchguards} )
i_negguards=( ${${(M)i_patchguards:#*"#-"*}/(#s)\#-/} )
i_posguards=( ${${(M)i_patchguards:#*"#+"*}/(#s)\#+/} )
# Patch with any negative guards is never pushed if guard is active
if [[ ${#i_negguards} -gt 0
&& ${#${(@M)mqguards:#${(~j,|,)i_negguards}}} -gt 0 ]] ; then
continue
fi
# Patch with positive guards is only pushed if guard is active
if [[ ${#i_posguards} -gt 0 ]] ; then
if [[ ${#${(@M)mqguards:#${(~j,|,)i_posguards}}} -gt 0 ]] ; then
mqunapplied+=( $i_patch )
fi
continue
fi
# If we made it this far the patch isn't guarded and should be pushed
mqunapplied+=( $i_patch )
done < ${mqseriesfile}
fi
if VCS_INFO_hook 'gen-applied-string' "${mqpatches[@]}"; then
(( ${#mqpatches} )) && applied_string=${mqpatches[1]}
else
applied_string=${hook_com[applied-string]}
fi
hook_com=()
if VCS_INFO_hook 'gen-unapplied-string' "${mqunapplied[@]}"; then
unapplied_string=${#mqunapplied}
else
unapplied_string=${hook_com[unapplied-string]}
fi
hook_com=()
if VCS_INFO_hook 'gen-mqguards-string' "${mqguards[@]}"; then
guards_string=${(j:,:)mqguards}
else
guards_string=${hook_com[guards-string]}
fi
if (( ${#mqpatches} )); then
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" patch-format \
hgmqstring || hgmqstring="%p (%n applied)"
else
zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" nopatch-format \
hgmqstring || hgmqstring="no patch applied"
fi
hook_com=( applied "${applied_string}" unapplied "${unapplied_string}"
applied-n ${#mqpatches} unapplied-n ${#mqunapplied}
guards "${guards_string}" guards-n ${#mqguards} )
if VCS_INFO_hook 'set-patch-format' ${qstring}; then
zformat -f hgmqstring "${hgmqstring}" \
"p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
"n:${#mqpatches}" "c:${#mqunapplied}" \
"g:${hook_com[guards]}" "G:${#mqguards}"
else
hgmqstring=${hook_com[patch-replace]}
fi
hook_com=()
else
hgmqstring=''
fi
if [[ -z "${hgmqstring}" ]] && [[ -z "${hgbmstring}" ]]; then
hgmisc_args=( '' ) # make sure there's at least *one* misc argument
elif [[ -z "${hgmqstring}" ]]; then
hgmisc_args=( "${hgmqstring}" )
elif [[ -z "${hgbmstring}" ]]; then
hgmisc_args=( "${hgbmstring}" )
else
hgmisc_args=( "${hgmqstring}" "${hgbmstring}" )
fi
VCS_INFO_formats '' "${hgbranch}" "${hgbase}" '' "${hgchanges}" "${hglrev}" "${hgmisc_args[@]}"
### Build the misc string
hgmisc+=( ${hgmqstring} )
hgmisc+=( ${hgbmstring} )
backend_misc[patches]="${hgmqstring}"
backend_misc[bookmarks]="${hgbmstring}"
VCS_INFO_formats "${hgactionstring}" "${branchformat}" "${hgbase}" '' "${hgchanges}" "${r_lrev}" "${(j:;:)hgmisc}"
return 0

View file

@ -22,21 +22,18 @@ hook_com=(
unstaged_orig "$5"
revision "$6"
revision_orig "$6"
misc "$7"
misc_orig "$7"
vcs "${vcs}"
vcs_orig "${vcs}"
)
shift 6
i=0
for tmp in "$@"; do
hook_com[misc$((i++))]="${tmp}"
done
hook_com[misc]=${(j:,:)argv}
hook_com[misc_orig]=${hook_com[misc]}
hook_com[base-name]="${${hook_com[base]}:t}"
hook_com[base-name_orig]="${hook_com[base_name]}"
hook_com[subdir]="$(VCS_INFO_reposub ${hook_com[base]})"
hook_com[subdir_orig]="${hook_com[subdir]}"
VCS_INFO_hook 'post-backend'
## description:
# action: a string that signals a certain non-default condition in the
# repository (like 'rebase-i' in git). If this in non-empty,
@ -46,8 +43,7 @@ hook_com[subdir_orig]="${hook_com[subdir]}"
# staged: non-empty if the repository contains staged changes.
# unstaged: non-empty if the repository contains unstaged changes.
# revision: an identifier of the currently checked out revision.
# misc0..N: a set of strings that may contain anything the author likes.
# the backends should document what they put in it and when.
# misc: a string that may contain anything the backend author likes.
#
# If an argument has no valid value for a given backend, an empty value
# should be provided. eg:
@ -71,6 +67,15 @@ if [[ -n ${hook_com[unstaged]} ]] ; then
[[ -z ${tmp} ]] && hook_com[unstaged]='U' || hook_com[unstaged]=${tmp}
fi
if [[ ${quiltmode} != 'standalone' ]] && VCS_INFO_hook "pre-addon-quilt"; then
local -x REPLY
VCS_INFO_quilt addon
hook_com[quilt]="${REPLY}"
unset REPLY
elif [[ ${quiltmode} == 'standalone' ]]; then
hook_com[quilt]=${hook_com[misc]}
fi
(( ${#msgs} > maxexports )) && msgs[$(( maxexports + 1 )),-1]=()
for i in {1..${#msgs}} ; do
if VCS_INFO_hook "set-message" $(( $i - 1 )) "${msgs[$i]}"; then
@ -83,6 +88,7 @@ for i in {1..${#msgs}} ; do
r:${hook_com[base-name]} \
s:${hook_com[vcs]} \
u:${hook_com[unstaged]} \
Q:${hook_com[quilt]} \
R:${hook_com[base]} \
S:${hook_com[subdir]}
msgs[$i]=${msg}
@ -90,4 +96,6 @@ for i in {1..${#msgs}} ; do
msgs[$i]=${hook_com[message]}
fi
done
hook_com=()
backend_misc=()
return 0

View file

@ -20,8 +20,11 @@ if (( debug )); then
fi
zstyle -a "${context}" hooks hooks || return 0
# protect some internal variables in hooks
typeset -r vcs rrn usercontext maxexports msgs vcs_comm
# Protect some internal variables in hooks. The `-g' parameter to
# typeset does *not* make the parameters global here (they are already
# "*-local-export). It prevents typeset from creating *new* *local*
# parameters in this function's scope.
typeset -g -r vcs rrn usercontext maxexports msgs vcs_comm
for hook in ${hooks} ; do
func="+vi-${hook}"
if (( ${+functions[$func]} == 0 )); then
@ -29,6 +32,7 @@ for hook in ${hooks} ; do
continue
fi
(( debug )) && printf ' + Running function: "%s"\n' "${func}"
true
${func} "$@"
case $? in
(0)
@ -38,5 +42,5 @@ for hook in ${hooks} ; do
;;
esac
done
typeset +r vcs rrn usercontext maxexports msgs vcs_comm
typeset -g +r vcs rrn usercontext maxexports msgs vcs_comm
return $ret

View file

@ -0,0 +1,190 @@
## vim:ft=zsh:foldmethod=marker
function VCS_INFO_quilt-match() {
emulate -L zsh
setopt extendedglob
local d mode="$1" param="$2"
local -a list
case ${mode} in
(assoc) list=( ${(kOP)param} );;
(array) : "${foo[@]}" ${(t)foo}; list=( ${(OP)param} );;
(*) return 1;;
esac
for d in "${list[@]}"; do
if [[ ${PWD} == ${d%/##}(|/*) ]]; then
print "$d"
return 0
fi
done
return 1
}
function VCS_INFO_quilt-standalone-detect() {
emulate -L zsh
setopt extendedglob
local param
local -i ret
zstyle -s "${context}" quilt-standalone param || return 1
[[ "${param}" == 'never' ]] && return 1
[[ "${param}" == 'always' ]] && return 0
if (( ${+functions[$param]} )); then
${param}
return $?
fi
case ${(Pt)param} in
*association*)
local m
local -A A
m="$(VCS_INFO_quilt-match assoc ${param})"
A=(${(kvP)param})
(( $? == 0 )) && [[ ${A[$m]} == "true" ]] && return 0
return 1
;;
*array*)
typeset -gU ${param}
VCS_INFO_quilt-match array ${param} > /dev/null
return $?
;;
*scalar*)
[[ "${(P)param}" == 'always' ]] && return 0
[[ "${(P)param}" == 'never' ]] && return 1
;;
esac
# If nothing hit yet, it just wasn't meant to be.
return 1
}
function VCS_INFO_quilt-dirfind() {
# This is a wrapper around VCS_INFO_bydir_detect(). It makes sure
# that $vcs_comm[] is unchanged. Currently, changing anything in it
# should not be an issue, but this makes sure the code can safely
# be called elsewhere, too - if needed.
emulate -L zsh
setopt extendedglob
local dir="$1" file="$2"; shift $#
local ret oldfile olddir
olddir=${vcs_comm[basedir]}
vcs_comm[basedir]=''
if [[ -n "${file}" ]]; then
oldfile=${vcs_comm[detect_need_file]}
vcs_comm[detect_need_file]=${file}
fi
VCS_INFO_bydir_detect ${dir}
ret=$?
[[ -n "${file}" ]] && vcs_comm[detect_need_file]=${oldfile}
printf '%s' ${vcs_comm[basedir]}
vcs_comm[basedir]="${olddir}"
return ${ret}
}
function VCS_INFO_quilt() {
emulate -L zsh
setopt extendedglob
local mode="$1"
local patches pc tmp qstring root
local -i ret
local -x context
local -a applied unapplied applied_string unapplied_string quiltcommand
local -Ax hook_com
context=":vcs_info:${vcs}.quilt-${mode}:${usercontext}:${rrn}"
zstyle -t "${context}" use-quilt || return 1
case ${mode} in
(standalone)
VCS_INFO_quilt-standalone-detect || return 1
;;
(addon)
;;
(*)
printf 'Invalid mode: `%s'\''\n' "$1"
return 2
;;
esac
zstyle -s "${context}" quilt-patch-dir patches || patches="${QUILT_PATCHES}"
if [[ "${patches}" != /* ]]; then
tmp=${patches:-patches}
patches="$(VCS_INFO_quilt-dirfind "${tmp}")"
ret=$?
(( ret )) && return ${ret}
patches=${patches}/${tmp}
else
[[ -d ${patches} ]] || return 1
fi
pc="$(VCS_INFO_quilt-dirfind .pc .version)"
ret=$?
if (( ret == 0 )); then
[[ ${quiltmode} == 'standalone' ]] && root=${pc}
pc=${pc}/.pc
if [[ -e ${pc}/applied-patches ]]; then
applied=( ${(f)"$(<$pc/applied-patches)"} )
# throw away empty entries
applied=( ${applied:#} )
applied=( ${(Oa)applied} )
else
applied=()
fi
fi
if zstyle -t "${context}" get-unapplied; then
# This zstyle call needs to be moved further up if `quilt' needs
# to be run in more places than this one.
zstyle -s "${context}" quiltcommand quiltcommand || quiltcommand='quilt'
unapplied=( ${(f)"$(QUILT_PATCHES=$patches $quiltcommand --quiltrc /dev/null unapplied 2> /dev/null)"} )
unapplied=( ${unapplied:#} )
else
unapplied=()
fi
if VCS_INFO_hook 'gen-applied-string' "${applied[@]}"; then
if (( ${#applied} )); then
applied_string=${applied[1]}
else
applied_string=""
fi
else
applied_string=${hook_com[applied-string]}
fi
hook_com=()
if VCS_INFO_hook 'gen-unapplied-string' "${unapplied[@]}"; then
unapplied_string="${#unapplied}"
else
unapplied_string=${hook_com[unapplied-string]}
fi
if (( ${#applied} )); then
zstyle -s "${context}" patch-format qstring || qstring="%p (%n applied)"
else
zstyle -s "${context}" nopatch-format qstring || qstring="no patch applied"
fi
hook_com=( applied "${applied_string}" unapplied "${unapplied_string}"
applied-n ${#applied} unapplied-n ${#unapplied} )
if VCS_INFO_hook 'set-patch-format' ${qstring}; then
zformat -f qstring "${qstring}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
"n:${#applied}" "c:${#unapplied}"
else
qstring=${hook_com[patch-replace]}
fi
hook_com=()
case ${mode} in
(standalone)
VCS_INFO_formats '' '' "${root}" '' '' '' "${qstring}"
VCS_INFO_set
;;
(addon)
# When VCS_INFO_quilt() is called with "addon" a "local -x REPLY" variable
# should be in place. That variable can be unset after it's being used.
REPLY="${qstring}"
;;
esac
VCS_INFO_hook 'post-quilt' ${mode} ${patches} ${pc:-\\-nopc-}
}
VCS_INFO_quilt "$@"

View file

@ -21,6 +21,7 @@ static_functions=(
VCS_INFO_hook
VCS_INFO_maxexports
VCS_INFO_nvcsformats
VCS_INFO_quilt
VCS_INFO_realpath
VCS_INFO_reposub
VCS_INFO_set
@ -45,12 +46,12 @@ vcs_info () {
[[ -r . ]] || return 0
local pat
local -i found
local -i found retval
local -a enabled disabled dps
local -x usercontext vcs rrn LC_MESSAGES
local -x usercontext vcs rrn quiltmode LC_MESSAGES
local -ix maxexports
local -ax msgs
local -Ax vcs_comm
local -Ax vcs_comm hook_com backend_misc user_data
LC_MESSAGES=C
if [[ -n ${LC_ALL} ]]; then
@ -58,9 +59,18 @@ vcs_info () {
LANG=${LC_ALL}
local -x LC_ALL
fi
vcs='-init-'; rrn='-all-'
vcs='-init-'; rrn='-all-'; quiltmode='addon'
usercontext=${1:-default}
VCS_INFO_hook "start-up"
retval=$?
if (( retval == 1 )); then
return 0
elif (( retval == 2 )); then
VCS_INFO_set --nvcs
return 0
fi
zstyle -a ":vcs_info:${vcs}:${usercontext}:${rrn}" "enable" enabled
(( ${#enabled} == 0 )) && enabled=( all )
@ -99,10 +109,20 @@ vcs_info () {
done
(( found == 0 )) && {
VCS_INFO_set --nvcs
vcs='-quilt-'; quiltmode='standalone'
VCS_INFO_quilt standalone || VCS_INFO_set --nvcs
return 0
}
VCS_INFO_hook "pre-get-data"
retval=$?
if (( retval == 1 )); then
return 0
elif (( retval == 2 )); then
VCS_INFO_set --nvcs
return 0
fi
VCS_INFO_get_data_${vcs} || {
VCS_INFO_set --nvcs
return 1