summaryrefslogtreecommitdiff
path: root/Functions/VCS_Info
diff options
context:
space:
mode:
authorAxel Beckert <abe@deuxchevaux.org>2022-04-11 00:17:48 +0200
committerAxel Beckert <abe@deuxchevaux.org>2022-04-11 00:17:48 +0200
commitb09f4483416c54c1782824633dfabaf2ec0265b6 (patch)
tree304bc82642862525ae680c7fbaa249663b10ad57 /Functions/VCS_Info
parent12eb3e5356f2fc3351eed58ef1cef1b8fb83b504 (diff)
parent6e55c920503071e917619b8cb1a188cd35d772db (diff)
downloadzsh-b09f4483416c54c1782824633dfabaf2ec0265b6.tar.gz
zsh-b09f4483416c54c1782824633dfabaf2ec0265b6.zip
New upstream version 5.8.1.2-test
Diffstat (limited to 'Functions/VCS_Info')
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_cvs17
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_detect_git1
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr11
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs11
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_fossil1
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_git114
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_hg31
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_p411
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_svk10
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_svn20
-rw-r--r--Functions/VCS_Info/VCS_INFO_bydir_detect2
-rw-r--r--Functions/VCS_Info/VCS_INFO_patch2subject2
-rw-r--r--Functions/VCS_Info/VCS_INFO_quilt57
-rw-r--r--Functions/VCS_Info/VCS_INFO_set-branch-format24
-rw-r--r--Functions/VCS_Info/VCS_INFO_set-patch-format16
-rwxr-xr-xFunctions/VCS_Info/test-repo-git-rebase-apply59
-rwxr-xr-xFunctions/VCS_Info/test-repo-git-rebase-merge59
-rw-r--r--Functions/VCS_Info/vcs_info1
18 files changed, 345 insertions, 102 deletions
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs b/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs
index 7a5ee1eef..a57959ec9 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs
@@ -7,5 +7,18 @@ setopt localoptions NO_shwordsplit
[[ $1 == '--flavours' ]] && return 1
VCS_INFO_check_com ${vcs_comm[cmd]} || return 1
-[[ -d "./CVS" ]] && [[ -r "./CVS/Repository" ]] && return 0
-return 1
+if ! [[ -d "./CVS" ]] || ! [[ -r "./CVS/Repository" ]] ; then
+ return 1
+fi
+
+# Look for the most distant parent that still has a CVS subdirectory.
+local cvsbase="."
+cvsbase=${cvsbase:P}
+while [[ -d "${cvsbase:h}/CVS" ]]; do
+ cvsbase="${cvsbase:h}"
+ if [[ $cvsbase == '/' ]]; then
+ break
+ fi
+done
+
+vcs_comm[basedir]="${cvsbase}"
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_git b/Functions/VCS_Info/Backends/VCS_INFO_detect_git
index e4191f474..b7955de38 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_detect_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_git
@@ -7,6 +7,7 @@ setopt localoptions NO_shwordsplit
[[ $1 == '--flavours' ]] && { print -l git-p4 git-svn; return 0 }
if VCS_INFO_check_com ${vcs_comm[cmd]} && vcs_comm[gitdir]="$(${vcs_comm[cmd]} rev-parse --git-dir 2> /dev/null)" ; then
+ vcs_comm[basedir]="$( ${vcs_comm[cmd]} rev-parse --show-toplevel 2> /dev/null )"
if [[ -d ${vcs_comm[gitdir]}/svn ]] ; then vcs_comm[overwrite_name]='git-svn'
elif [[ -d ${vcs_comm[gitdir]}/refs/remotes/p4 ]] ; then vcs_comm[overwrite_name]='git-p4' ; fi
return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
index b30e0e12b..f1f5527e8 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
@@ -100,14 +100,7 @@ else
fi
rrn=${bzrbase:t}
-zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat bzrbr || bzrbr="%b:%r"
-hook_com=( branch "${bzrinfo[2]}" revision "${bzrinfo[1]}" )
-if VCS_INFO_hook 'set-branch-format' "${bzrbr}"; then
- zformat -f bzrbr "${bzrbr}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
-else
- bzrbr=${hook_com[branch-replace]}
-fi
-hook_com=()
-
+VCS_INFO_set-branch-format "${bzrinfo[2]}" "${bzrinfo[1]}" &&
+ bzrbr="${REPLY}"
VCS_INFO_formats '' "${bzrbr}" "${bzrbase}" '' "${bzr_changes}" "${bzrinfo[1]}" "${bzr_changes}"
return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs b/Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs
index 9b828bd11..bc0d5cfe5 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_cvs
@@ -5,17 +5,8 @@
setopt localoptions NO_shwordsplit
local cvsbranch cvsbase
-# Look for the most distant parent that still has a CVS subdirectory.
+cvsbase="${vcs_comm[basedir]}"
# VCS_INFO_detect_cvs ensured that ./CVS/Repository exists.
-cvsbase="."
-cvsbase=${cvsbase:P}
-while [[ -d "${cvsbase:h}/CVS" ]]; do
- cvsbase="${cvsbase:h}"
- if [[ $cvsbase == '/' ]]; then
- break
- fi
-done
-
cvsbranch=$(< ./CVS/Repository)
rrn=${cvsbase:t}
cvsbranch=${cvsbranch##${rrn}/}
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_fossil b/Functions/VCS_Info/Backends/VCS_INFO_get_data_fossil
index fd0f8389e..e84b3abc0 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_fossil
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_fossil
@@ -20,5 +20,6 @@ if [ -n "$merging" ]; then
action="merging"
fi
+rrn=${fsinfo[local_root]:t}
VCS_INFO_formats "$action" "${fsbranch}" "${fsinfo[local_root]}" '' "$changed" "${fshash}" "${fsinfo[repository]}"
return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
index ceb4f978a..e45eebc8e 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -132,13 +132,17 @@ VCS_INFO_git_handle_patches () {
VCS_INFO_set-patch-format 'git_patches_applied' 'git_applied_s' \
'git_patches_unapplied' 'git_unapplied_s' \
":vcs_info:${vcs}:${usercontext}:${rrn}" gitmsg \
- '' ''
+ '' '' ''
gitmisc=$REPLY
}
gitdir=${vcs_comm[gitdir]}
VCS_INFO_git_getbranch ${gitdir}
-gitbase=$( ${vcs_comm[cmd]} rev-parse --show-toplevel )
+gitbase=${vcs_comm[basedir]}
+if [[ -z ${gitbase} ]]; then
+ # Bare repository
+ gitbase=${gitdir:P}
+fi
rrn=${gitbase:t}
if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision ; then
gitsha1=$(${vcs_comm[cmd]} rev-parse --quiet --verify HEAD)
@@ -192,13 +196,19 @@ elif [[ -d "${gitdir}/rebase-merge" ]]; then
# 'git rebase -i'
patchdir="${gitdir}/rebase-merge"
local p
- [[ -f "${patchdir}/done" ]] &&
- for p in ${(f)"$(< "${patchdir}/done")"}; do
+ (( ${+functions[VCS_INFO_git_map_rebase_line_to_hash_and_subject]} )) ||
+ VCS_INFO_git_map_rebase_line_to_hash_and_subject() {
+ local p=$1
+ unset REPLY
# pick/edit/fixup/squash/reword: Add "$hash $subject" to $git_patches_applied.
# exec: Add "exec ${command}" to $git_patches_applied.
# (anything else): As 'exec'.
case $p in
- ((p|pick|e|edit|r|reword|f|fixup|s|squash)' '*)
+ ([#]*)
+ # Comment line. Skip.
+ return 0
+ ;;
+ (''(p|pick|e|edit|r|reword|f|fixup|s|squash)' '*)
# The line is of the form "pick $hash $subject".
# Just strip the verb and we're good to go.
p=${p#* }
@@ -221,11 +231,11 @@ elif [[ -d "${gitdir}/rebase-merge" ]]; then
p="${p%% *} ?"
fi
;;
- (x *)
+ (''(x|exec) *)
# The line is of the form 'exec foo bar baz' where 'foo bar
# baz' is a shell command. There's no way to map _that_ to
# "$hash $subject", but I hope this counts as making an effort.
- p=${p/x /exec }
+ p=${p/#x /exec }
;;
(*)
# Forward compatibility with not-yet-existing 'git rebase -i' verbs.
@@ -233,30 +243,74 @@ elif [[ -d "${gitdir}/rebase-merge" ]]; then
p+=" ?"
fi
esac
- git_patches_applied+=("$p")
- done
+ REPLY=$p
+ }
+ if [[ -f "${patchdir}/done" ]] ; then
+ for p in ${(f)"$(< "${patchdir}/done")"}; do
+ VCS_INFO_git_map_rebase_line_to_hash_and_subject "$p"
+ (( $+REPLY )) && git_patches_applied+=( "$REPLY" )
+ done
+ fi
if [[ -f "${patchdir}/git-rebase-todo" ]] ; then
- # TODO: Process ${patchdir}/git-rebase-todo lines like ${patchdir}/done lines are
- git_patches_unapplied=( ${${(f)${"$(<"${patchdir}/git-rebase-todo")"}}:#[#]*} )
+ for p in ${(f)"$(< "${patchdir}/git-rebase-todo")"}; do
+ VCS_INFO_git_map_rebase_line_to_hash_and_subject "$p"
+ (( $+REPLY )) && git_patches_unapplied+=( "$REPLY" )
+ done
fi
VCS_INFO_git_handle_patches
elif [[ -d "${gitdir}/rebase-apply" ]]; then
- # 'git rebase' without -i
+ # 'git rebase' without -i, or 'git am'
patchdir="${gitdir}/rebase-apply"
local next="${patchdir}/next"
+ local this_patch_file
if [[ -f $next ]]; then
local cur=$(< $next)
local p subject
- # Fake patch names for all but current patch
- for ((p = 1; p < cur; p++)); do
- printf -v "git_patches_applied[$p]" "%04d ?" "$p"
- done
+ # Compute patch names for patches "before" the current patch
+ if [[ -r ${patchdir}/rewritten ]]; then
+ if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" use-simple; then
+ git_patches_applied=( ${${(f)"$(<${patchdir}/rewritten)"}// */' ?'} )
+ else
+ git_patches_applied=(
+ ${(f)"$(${vcs_comm[cmd]} log --no-walk=unsorted --pretty='%h %s' ${${(f)"$(<${patchdir}/rewritten)"}%% *} --)"}
+ )
+ fi
+ else
+ # Compatibility with old git. In 2.11 and 2.24, at least,
+ # (( cur == 1 )), so the loop body would never run. However, both
+ # of these versions have original-commit and orig-head and would
+ # take the 'if' branch, rather than this 'else' branch.
+ for ((p = 1; p < cur; p++)); do
+ printf -v this_patch_file "%s/%04d" "${patchdir}" "${p}"
+ if [[ -f $this_patch_file ]]; then
+ VCS_INFO_patch2subject "${this_patch_file}"
+ git_patches_applied+=( "$p $REPLY" )
+ else
+ git_patches_applied+=( "$p ?" )
+ fi
+ done
+ fi
+ # Set $subject to the info for the current patch
if [[ -f "${patchdir}/msg-clean" ]]; then
subject="${$(< "${patchdir}/msg-clean")[(f)1]}"
- elif local this_patch_file
- printf -v this_patch_file "%s/%04d" "${patchdir}" "${cur}"
+ elif [[ -f "${patchdir}/final-commit" ]]; then
+ # This value is not rfc2047-encoded. It's also available via
+ # "${patchdir}/info".
+ subject="${$(< "${patchdir}/final-commit")[(f)1]}"
+ elif printf -v this_patch_file "%s/%04d" "${patchdir}" "${cur}"
[[ -f $this_patch_file ]]
then
+ # This branch is last for several reasons:
+ #
+ # - The "Subject" header will be MIME-encoded (rfc2047).
+ #
+ # - If the mail has full rfc822 headers (including "Received" and
+ # so on), we won't find the "Subject:" header, since
+ # VCS_INFO_patch2subject only checks the first few lines.
+ #
+ # - In --scissors mode, we may find the outer "Subject:" header,
+ # whereas the inner one (after the scissors line) will be used,
+ # if present.
() {
local REPLY
VCS_INFO_patch2subject "${this_patch_file}"
@@ -266,14 +320,32 @@ elif [[ -d "${gitdir}/rebase-apply" ]]; then
subject=${subject:-'?'}
if [[ -f "${patchdir}/original-commit" ]]; then
git_patches_applied+=("$(< ${patchdir}/original-commit) $subject")
+ elif [[ -f "${patchdir}/next" ]]; then
+ git_patches_applied+=("$(< ${patchdir}/next) $subject")
else
git_patches_applied+=("? $subject")
fi
- local last="$(< "${patchdir}/last")"
- if (( cur+1 <= last )); then
- git_patches_unapplied=( {$((cur+1))..$last} )
+ # Handle patches scheduled for after the current patch, if instructed to.
+ if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-unapplied; then
+ local last="$(< "${patchdir}/last")"
+ if [[ -r ${patchdir}/original-commit && -r ${patchdir}/orig-head ]] &&
+ ! zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" use-simple
+ then
+ git_patches_unapplied+=( ${(f)"$(${vcs_comm[cmd]} log --reverse --pretty="%h %s" "$(<${patchdir}/original-commit)..$(<${patchdir}/orig-head)")"} )
+ else
+ for ((p = cur+1; p <= last; p++)); do
+ printf -v this_patch_file "%s/%04d" "${patchdir}" "${p}"
+ if [[ -f $this_patch_file ]]; then
+ VCS_INFO_patch2subject "${this_patch_file}"
+ git_patches_unapplied+=( "$p $REPLY" )
+ else
+ git_patches_unapplied+=( "$p ?" )
+ fi
+ done
+ fi
fi
fi
+ unset this_patch_file
VCS_INFO_git_handle_patches
elif [[ -f "${gitdir}/MERGE_HEAD" ]]; then
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
index cd5ef321d..ea3798b81 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
@@ -5,7 +5,7 @@
setopt localoptions extendedglob NO_shwordsplit
-local hgbase bmfile branchfile rebasefile dirstatefile mqseriesfile \
+local hgbase bmfile branchfile topicfile rebasefile dirstatefile mqseriesfile \
curbmfile curbm \
mqstatusfile mqguardsfile patchdir mergedir \
r_csetid r_lrev r_branch i_bmhash i_bmname \
@@ -14,7 +14,7 @@ local hgbase bmfile branchfile rebasefile dirstatefile mqseriesfile \
local -a hgid_args defrevformat defbranchformat \
hgbmarks mqpatches mqguards mqunapplied hgmisc \
- i_patchguards i_negguards i_posguards
+ i_patch i_patchguards i_negguards i_posguards
local -A hook_com
@@ -27,6 +27,7 @@ mergedir="${hgbase}/.hg/merge/"
bmfile="${hgbase}/.hg/bookmarks"
curbmfile="${hgbase}/.hg/bookmarks.current"
branchfile="${hgbase}/.hg/branch"
+topicfile="${hgbase}/.hg/topic"
rebasefile="${hgbase}/.hg/rebasestate"
dirstatefile="${hgbase}/.hg/dirstate"
mqstatusfile="${patchdir}/status" # currently applied patches
@@ -48,27 +49,34 @@ if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision ; then
# Settling for a short (but unique!) hash because getting the full
# 40-char hash in addition to all the other info we want isn't
# available in a single hg invocation
- hgid_args=( id -i -n -b )
+ hgid_args=( id -i -n )
# 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. )
- local HGPLAIN
HGPLAIN=1 ${vcs_comm[cmd]} ${(z)hgid_args} 2> /dev/null \
- | read -r r_csetid r_lrev r_branch
+ | read -r r_csetid r_lrev
fi
fi
# If the user doesn't opt to invoke hg we can still get the current branch
-if [[ -z ${r_branch} && -r ${branchfile} ]] ; then
+if [[ -r ${branchfile} ]] ; then
r_branch=$(< ${branchfile})
fi
# If we still don't know the branch it's safe to assume default
[[ -n ${r_branch} ]] || r_branch="default"
+# Show topic if there is any (the UI for this experimental concept is not yet
+# final, but for a long time the convention has been to join the branch name
+# and the topic name by a colon)
+if [[ -f ${topicfile} && -r ${topicfile} && -s ${topicfile} ]] ; then
+ IFS= read -r REPLY < ${topicfile}
+ r_branch=${r_branch}:${REPLY}
+fi
+
# The working dir has uncommitted-changes if the revision ends with a +
if [[ $r_lrev[-1] == + ]] ; then
hgchanges=1
@@ -175,6 +183,9 @@ if zstyle -T ":vcs_info:${vcs}:${usercontext}:${rrn}" get-mq \
# Skip commented lines
[[ ${i_patch} == [[:space:]]#"#"* ]] && continue
+ # Skip applied patches
+ (( ${+mqpatches[(re)${i_patch}]} )) && continue
+
# Separate negative and positive guards to more easily find the
# intersection of active guards with patch guards
i_patchguards=( ${(s: :)i_patchguards} )
@@ -208,12 +219,16 @@ if zstyle -T ":vcs_info:${vcs}:${usercontext}:${rrn}" get-mq \
fi
local -A extra_hook_com=( guards "${guards_string}" guards-n ${#mqguards} )
- local -a extra_zformats=( "g:${extra_hook_com[guards]}" "G:${#mqguards}" )
+
+ (( ${+functions[VCS_INFO_hg_extra_zformats]} )) ||
+ VCS_INFO_hg_extra_zformats() {
+ reply=( "g:${hook_com[guards]}" "G:${#mqguards}" )
+ }
VCS_INFO_set-patch-format 'mqpatches' 'applied_string' \
'mqunapplied' 'unapplied_string' \
":vcs_info:${vcs}:${usercontext}:${rrn}" hgmqstring \
- extra_hook_com extra_zformats
+ extra_hook_com VCS_INFO_hg_extra_zformats ''
hgmqstring=$REPLY
fi
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4 b/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
index 329884982..e8a08a663 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
@@ -17,13 +17,8 @@ local p4branch change
# here down is synced as the revision.
# I suppose the following might be slow on a tortuous client view.
change="${${$(${vcs_comm[cmd]} changes -m 1 ...\#have)##Change }%% *}"
-zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat p4branch || p4branch="%b:%r"
-hook_com=( branch "${p4info[Client_name]}" revision "${change}" )
-if VCS_INFO_hook 'set-branch-format' "${p4branch}"; then
- zformat -f p4branch "${p4branch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
-else
- p4branch=${hook_com[branch-replace]}
-fi
-hook_com=()
+rrn=${p4base:t}
+VCS_INFO_set-branch-format "${p4info[Client_name]}" "${change}" &&
+ p4branch="${REPLY}"
VCS_INFO_formats '' "${p4branch}" "${p4base}" '' '' "$change" ''
return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
index 1d2d22ffb..149e30222 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
@@ -8,13 +8,7 @@ local -A hook_com
svkbase=${vcs_comm[basedir]}
rrn=${svkbase:t}
-zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat svkbranch || svkbranch="%b:%r"
-hook_com=( branch "${vcs_comm[branch]}" revision "${vcs_comm[revision]}" )
-if VCS_INFO_hook 'set-branch-format' "${svkbranch}"; then
- zformat -f svkbranch "${svkbranch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
-else
- svkbranch=${hook_com[branch-replace]}
-fi
-hook_com=()
+VCS_INFO_set-branch-format "${vcs_comm[branch]}" "${vcs_comm[revision]}" &&
+ svkbranch="${REPLY}"
VCS_INFO_formats '' "${svkbranch}" "${svkbase}" '' '' "${vcs_comm[revision]}" ''
return 0
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
index 21590addd..b33efc2fb 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
@@ -10,6 +10,7 @@ local -i rc
local -A svninfo parentinfo cwdinfo
local -A hook_com
integer -r SVN_ERR_WC_UPGRADE_REQUIRED=155036 # from /usr/local/include/subversion-1/svn_error_codes.h
+integer -r SVN_ERR_WC_UNSUPPORTED_FORMAT=155021
svnbase=".";
svninfo=()
@@ -22,7 +23,14 @@ rc=$?
if (( rc != 0 )) ; then
if (( rc == 1 )) && [[ -n ${(M)dat:#"svn: E${SVN_ERR_WC_UPGRADE_REQUIRED}: "*} ]]; then
hook_com=()
- VCS_INFO_formats '' '?' '?' '' '' '?' 'upgrade required'
+ # User should run 'svn upgrade'
+ VCS_INFO_formats '' '?' '?' '' '' '?' 'working copy upgrade required'
+ return $?
+ elif (( rc == 1 )) && [[ -n ${(M)dat:#"svn: E${SVN_ERR_WC_UNSUPPORTED_FORMAT}: "*} ]]; then
+ hook_com=()
+ # User probably needs to install a newer svn, but we're not sure, so point
+ # the user to svn's error message.
+ VCS_INFO_formats '' '?' '?' '' '' '?' 'svn error'
return $?
else
return 1
@@ -60,13 +68,7 @@ else
fi
rrn=${svnbase:t}
-zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat svnbranch || svnbranch="%b:%r"
-hook_com=( branch "${svninfo[URL]##*/}" revision "${cwdinfo[Revision]}" )
-if VCS_INFO_hook 'set-branch-format' "${svnbranch}"; then
- zformat -f svnbranch "${svnbranch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
-else
- svnbranch=${hook_com[branch-replace]}
-fi
-hook_com=()
+VCS_INFO_set-branch-format "${svninfo[URL]##*/}" "${cwdinfo[Revision]}" &&
+ svnbranch="${REPLY}"
VCS_INFO_formats '' "${svnbranch}" "${svnbase}" '' '' "${cwdinfo[Revision]}" ''
return 0
diff --git a/Functions/VCS_Info/VCS_INFO_bydir_detect b/Functions/VCS_Info/VCS_INFO_bydir_detect
index 29b261413..89b4d6503 100644
--- a/Functions/VCS_Info/VCS_INFO_bydir_detect
+++ b/Functions/VCS_Info/VCS_INFO_bydir_detect
@@ -36,4 +36,6 @@ done
[[ ${basedir} == "/" ]] && return 1
vcs_comm[basedir]=${basedir}
+# TODO: Would the following be correct? ---
+# rrn=${vcs_comm[basedir]:t}
return 0
diff --git a/Functions/VCS_Info/VCS_INFO_patch2subject b/Functions/VCS_Info/VCS_INFO_patch2subject
index a467edcdb..5aa9efd23 100644
--- a/Functions/VCS_Info/VCS_INFO_patch2subject
+++ b/Functions/VCS_Info/VCS_INFO_patch2subject
@@ -1,3 +1,5 @@
+## vim:ft=zsh
+#
# This function takes as an argument a filename of a patch and sets $REPLY to
# a single-line "subject", or unsets it if no subject could be extracted.
{
diff --git a/Functions/VCS_Info/VCS_INFO_quilt b/Functions/VCS_Info/VCS_INFO_quilt
index fef85964a..ce5b41f24 100644
--- a/Functions/VCS_Info/VCS_INFO_quilt
+++ b/Functions/VCS_Info/VCS_INFO_quilt
@@ -92,7 +92,7 @@ function VCS_INFO_quilt-patch2subject() {
emulate -L zsh
setopt extendedglob
local mode="$1"
- local patches pc tmp qstring root
+ local patches pc qstring root
local -i ret
local context
local -a applied unapplied applied_string unapplied_string quiltcommand quilt_env
@@ -113,9 +113,12 @@ function VCS_INFO_quilt-patch2subject() {
;;
esac
- VCS_INFO_quilt-dirfind .pc .version
- ret=$? pc=$REPLY
- if (( ret == 0 )); then
+ # Look for the patches directory.
+ #
+ # 1. Check if there's a .pc/.version file in a parent dir. If so, use the
+ # patches dir from the corresponding .pc/.quilt_patches.
+ if VCS_INFO_quilt-dirfind .pc .version; then
+ pc=$REPLY
[[ ${quiltmode} == 'standalone' ]] && root=${pc}
pc=${pc}/.pc
if [[ -e ${pc}/applied-patches ]]; then
@@ -128,33 +131,35 @@ function VCS_INFO_quilt-patch2subject() {
fi
patches=$(<$pc/.quilt_patches)
patches=`builtin cd -q "${pc:h}" && print -r - ${patches:P}`
+ # 2. Else, locate a patches dir using the style settings.
+ else
+ zstyle -s "${context}" quilt-patch-dir patches || patches="${QUILT_PATCHES}"
+ : ${patches:="patches"}
+ if [[ "${patches}" != /* ]]; then
+ if VCS_INFO_quilt-dirfind "${patches}"; then
+ patches=$REPLY/$patches
+ else
+ return $?
+ fi
+ else
+ [[ -d ${patches} ]] || return 1
+ fi
+ quilt_env+=(QUILT_PATCHES="$patches")
fi
+ # At this point, $patches is set and points to an existing directory.
+
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'
- quilt_env=(env)
- if [ -z "$patches" ]; then
- zstyle -s "${context}" quilt-patch-dir patches || patches="${QUILT_PATCHES}"
- if [[ "${patches}" != /* ]]; then
- tmp=${patches:-patches}
- VCS_INFO_quilt-dirfind "${tmp}"
- ret=$? patches=$REPLY
- (( ret )) && return ${ret}
- patches=${patches}/${tmp}
- else
- [[ -d ${patches} ]] || return 1
- fi
- quilt_env+=(QUILT_PATCHES="$patches")
- fi
- unapplied=( ${(f)"$(${quilt_env[@]} $quiltcommand --quiltrc /dev/null unapplied 2> /dev/null)"} )
+ unapplied=( ${(f)"$(if (( $+quilt_env[1] )); then export ${quilt_env[@]}; fi
+ $quiltcommand --quiltrc /dev/null unapplied 2> /dev/null)"} )
unapplied=( ${unapplied:#} )
else
unapplied=()
fi
- if [[ -n $patches ]]; then
- () {
+ {
local i
for ((i=1; i<=$#applied; i++)); do
if VCS_INFO_quilt-patch2subject "$patches/$applied[$i]" && (( $+REPLY ))
@@ -172,13 +177,17 @@ function VCS_INFO_quilt-patch2subject() {
unapplied[$i]+=" ?"
fi
done
- }
- fi
+ }
+
+ typeset -A quilt_extra_info=(
+ quilt-patches-dir ${patches}
+ ${pc:+"quilt-pc-dir"} $pc
+ )
VCS_INFO_set-patch-format 'applied' 'applied_string' \
'unapplied' 'unapplied_string' \
${context} qstring \
- '' ''
+ quilt_extra_info '' quilt_extra_info
qstring=$REPLY
case ${mode} in
diff --git a/Functions/VCS_Info/VCS_INFO_set-branch-format b/Functions/VCS_Info/VCS_INFO_set-branch-format
new file mode 100644
index 000000000..cbab60e29
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_set-branch-format
@@ -0,0 +1,24 @@
+## vim:ft=zsh
+#
+# A function for calling the branch-format hook
+#
+# Return the value to use in REPLY
+#
+# Parameters:
+readonly branch=$1
+readonly revision=$2
+#
+
+[[ -n $rrn ]] || return 1
+local -A hook_com
+local branchformat
+
+zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat branchformat || branchformat="%b:%r"
+hook_com=( branch "${branch}" revision "${revision}" )
+if VCS_INFO_hook 'set-branch-format' "${branchformat}"; then
+ zformat -f REPLY "${branchformat}" "b:${hook_com[branch]}" "r:${hook_com[revision]}"
+else
+ REPLY=${hook_com[branch-replace]}
+fi
+hook_com=()
+return 0
diff --git a/Functions/VCS_Info/VCS_INFO_set-patch-format b/Functions/VCS_Info/VCS_INFO_set-patch-format
index 917ebf6bf..1c774a7f6 100644
--- a/Functions/VCS_Info/VCS_INFO_set-patch-format
+++ b/Functions/VCS_Info/VCS_INFO_set-patch-format
@@ -1,3 +1,5 @@
+## vim:ft=zsh
+#
# This function is the common guts of the gen-applied-string /
# gen-unapplied-string / set-patch-format dance of several backends.
#
@@ -12,7 +14,9 @@
# $6 - name of a parameter to store a patch-format format string in
# $7 - name of an assoc parameter with extra $hook_com key-value pairs for the
# set-patch-format hook invocation, or '' for none
-# $8 - name of an array parameter with extra arguments for the patch-format zformat call, or '' for empty
+# $8 - name of a function that sets $reply to extra arguments for the patch-format zformat call, or '' for none
+# $9 - name of an assoc parameter with extra $hook_com key-value pairs for the
+# gen-applied-string & gen-unapplied-string hook invocations, or '' for none
#
# The expanded patch-format string is returned in $REPLY.
#
@@ -20,8 +24,10 @@
# - $hook_com is overwritten and the keys 'applied', 'applied-n',
# 'unapplied', 'unapplied-n', 'all-n' are set.
{
+ hook_com=()
+
local applied_needs_escaping='unknown'
- local unapplied_needs_escaping='unknown'
+ hook_com+=( ${9:+"${(@kvP)9}"} )
if VCS_INFO_hook 'gen-applied-string' "${(@P)1}"; then
if (( ${(P)#1} )); then
REPLY=${(P)1[1]}
@@ -35,6 +41,8 @@
: ${(P)2::=$REPLY}
hook_com=()
+ local unapplied_needs_escaping='unknown'
+ hook_com+=( ${9:+"${(@kvP)9}"} )
if VCS_INFO_hook 'gen-unapplied-string' "${(@P)3}"; then
REPLY=${(P)#3}
unapplied_needs_escaping='yes'
@@ -68,10 +76,12 @@
hook_com[unapplied]=${hook_com[unapplied]//'%'/%%}
fi
+ reply=()
+ [[ -n $8 ]] && "$8"
zformat -f REPLY "${(P)6}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
"n:${hook_com[applied-n]}" "c:${hook_com[unapplied-n]}" \
"a:${hook_com[all-n]}" \
- ${8:+"${(@P)8}"}
+ "${reply[@]}"
else
unset applied_needs_escaping unapplied_needs_escaping # the hook deals with escaping
REPLY=${hook_com[patch-replace]}
diff --git a/Functions/VCS_Info/test-repo-git-rebase-apply b/Functions/VCS_Info/test-repo-git-rebase-apply
new file mode 100755
index 000000000..ce49690cd
--- /dev/null
+++ b/Functions/VCS_Info/test-repo-git-rebase-apply
@@ -0,0 +1,59 @@
+#!/usr/local/bin/zsh -f
+#
+# This script creates a test repository for testing the git backend's behaviour during rebase-apply operations.
+#
+# It works in ./vcs-test/.
+#
+# Suggested zshrc settings:
+#
+# autoload vcs_info
+# precmd() { vcs_info; typeset -pm vcs\* }
+# zstyle ':vcs_info:*' actionformats %m
+# zstyle ':vcs_info:*' patch-format '[%n+%c=%a] [%p] [%u]'
+# zstyle :vcs_info:\*gen-applied-string\* hooks f1
+# +vi-f1() { typeset -p argv hook_com }
+# zstyle :vcs_info:\*gen-unapplied-string\* hooks f2
+# +vi-f2() { typeset -p argv hook_com }
+# zstyle :vcs_info:\* get-unapplied true
+#
+mkdir "vcs-test"
+cd "vcs-test"
+git init
+
+append_lines() { for 1; do echo line from r$1 >> iota && git commit -am "r$1: Append a line"; done }
+
+echo "This is the file 'iota'." > iota
+git add iota
+git commit -m "r1: Add iota"
+git tag rebase_onto_this HEAD
+
+# Make another change to iota
+append_lines 2
+git tag rebase_from_this HEAD
+
+# Make non-conflicting changes
+for 1 in 3 4 5 6; do
+ touch kappa$1
+ git add kappa$1
+ git commit -m "r${1}: non-conflicting change"
+done
+
+# Make more changes to iota
+append_lines 7 8 9
+
+# Specify a rebase that would create the history [1,3,4,5,6,7,8,9].
+# This will conflict because r7 depends on r2 which is not included.
+git checkout -b myref
+case $0:P in
+ (*/test-repo-git-rebase-apply)
+ git rebase --onto=rebase_onto_this rebase_from_this myref
+ ;;
+ (*/test-repo-git-rebase-merge)
+ git -c core.editor=true rebase -i --onto=rebase_onto_this rebase_from_this myref
+ ;;
+ (*)
+ echo >&2 "$0: unrecognized basename"
+ ;;
+esac
+
+
diff --git a/Functions/VCS_Info/test-repo-git-rebase-merge b/Functions/VCS_Info/test-repo-git-rebase-merge
new file mode 100755
index 000000000..ce49690cd
--- /dev/null
+++ b/Functions/VCS_Info/test-repo-git-rebase-merge
@@ -0,0 +1,59 @@
+#!/usr/local/bin/zsh -f
+#
+# This script creates a test repository for testing the git backend's behaviour during rebase-apply operations.
+#
+# It works in ./vcs-test/.
+#
+# Suggested zshrc settings:
+#
+# autoload vcs_info
+# precmd() { vcs_info; typeset -pm vcs\* }
+# zstyle ':vcs_info:*' actionformats %m
+# zstyle ':vcs_info:*' patch-format '[%n+%c=%a] [%p] [%u]'
+# zstyle :vcs_info:\*gen-applied-string\* hooks f1
+# +vi-f1() { typeset -p argv hook_com }
+# zstyle :vcs_info:\*gen-unapplied-string\* hooks f2
+# +vi-f2() { typeset -p argv hook_com }
+# zstyle :vcs_info:\* get-unapplied true
+#
+mkdir "vcs-test"
+cd "vcs-test"
+git init
+
+append_lines() { for 1; do echo line from r$1 >> iota && git commit -am "r$1: Append a line"; done }
+
+echo "This is the file 'iota'." > iota
+git add iota
+git commit -m "r1: Add iota"
+git tag rebase_onto_this HEAD
+
+# Make another change to iota
+append_lines 2
+git tag rebase_from_this HEAD
+
+# Make non-conflicting changes
+for 1 in 3 4 5 6; do
+ touch kappa$1
+ git add kappa$1
+ git commit -m "r${1}: non-conflicting change"
+done
+
+# Make more changes to iota
+append_lines 7 8 9
+
+# Specify a rebase that would create the history [1,3,4,5,6,7,8,9].
+# This will conflict because r7 depends on r2 which is not included.
+git checkout -b myref
+case $0:P in
+ (*/test-repo-git-rebase-apply)
+ git rebase --onto=rebase_onto_this rebase_from_this myref
+ ;;
+ (*/test-repo-git-rebase-merge)
+ git -c core.editor=true rebase -i --onto=rebase_onto_this rebase_from_this myref
+ ;;
+ (*)
+ echo >&2 "$0: unrecognized basename"
+ ;;
+esac
+
+
diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info
index 9f48bee75..786b61918 100644
--- a/Functions/VCS_Info/vcs_info
+++ b/Functions/VCS_Info/vcs_info
@@ -22,6 +22,7 @@ static_functions=(
VCS_INFO_hexdump
VCS_INFO_hook
VCS_INFO_set-patch-format
+ VCS_INFO_set-branch-format
VCS_INFO_maxexports
VCS_INFO_nvcsformats
VCS_INFO_patch2subject