Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] vcs_info: add 'find-deepest' zstyle



Currently, vcs_info iterates over enabled VCS backends and outputs repository
status from the first backend that works (i.e. first backend that can find a
repository).

But I prefer a different behavior: I want to see the status of the repository
closest to the current working directory. For example: if there is a Mercurial
repository inside a Git repository, and I 'cd' into the Mercurial repository,
I want to see the status of Mercurial repo, even if 'git' comes before 'hg' in
the 'enable' list.

Because some people, apparently, want the old behavior of vcs_info, I made it
configurable, and, by default, old behavior is kept. To enable new behavior,
enable 'find-deepest' zstyle:

    zstyle ':vcs_info:*' find-deepest yes

After this change, vcs_info will try all enabled backends, and choose the one
that returns the deepest basedir path. Usually it will be the repository
closest to the current directory - if all basedirs are ancestors of the
current directory. I do not care about cases when a basedir isn't an ancestor
(for example, if GIT_WORK_TREE is pointing to an unrelated directory).

Also, this patch adjusts VCS_INFO_detect_git and VCS_INFO_detect_cvs to make
them set vcs_comm[basedir]. They were the only VCS_INFO_detect_* functions not
setting it.

Signed-off-by: Aleksandr Mezin <mezin.alexander@xxxxxxxxx>
---
 Doc/Zsh/contrib.yo                            |  9 +++++++
 .../VCS_Info/Backends/VCS_INFO_detect_cvs     |  2 +-
 .../VCS_Info/Backends/VCS_INFO_detect_git     |  1 +
 .../VCS_Info/Backends/VCS_INFO_get_data_git   |  2 +-
 Functions/VCS_Info/vcs_info                   | 25 ++++++++++++++++---
 5 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 00f693664..88d00c0ac 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -1238,6 +1238,14 @@ of unapplied patches (for example with Mercurial Queue patches).
 
 Used by the tt(quilt), tt(hg), and tt(git) backends.
 )
+kindex(find-deepest)
+item(tt(find-deepest))(
+By default, tt(vcs_info) tries backends in the order of 'enable' list, and
+returns the output of the first backend that can find a repository. When
+tt(find-deepest) is set to tt(true), tt(vcs_info) will try all enabled backends,
+and will choose the one that returns the deepest tt(basedir) path. Usually it
+will be the repository closest to the current directory.
+)
 enditem()
 
 The default values for these styles in all contexts are:
@@ -1272,6 +1280,7 @@ sitem(tt(quiltcommand))(quilt)
 sitem(tt(patch-format))(var(backend dependent))
 sitem(tt(nopatch-format))(var(backend dependent))
 sitem(tt(get-unapplied))(false)
+sitem(tt(find-deepest))(false)
 endsitem()
 
 In normal tt(formats) and tt(actionformats) the following replacements are
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs b/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs
index 7a5ee1eef..491219c16 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs
+++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_cvs
@@ -7,5 +7,5 @@ setopt localoptions NO_shwordsplit
 [[ $1 == '--flavours' ]] && return 1
 
 VCS_INFO_check_com ${vcs_comm[cmd]} || return 1
-[[ -d "./CVS" ]] && [[ -r "./CVS/Repository" ]] && return 0
+[[ -d "./CVS" ]] && [[ -r "./CVS/Repository" ]] && vcs_comm[basedir]=.(:P) && return 0
 return 1
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_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
index 79429c8e0..eb04d4b41 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -138,7 +138,7 @@ VCS_INFO_git_handle_patches () {
 
 gitdir=${vcs_comm[gitdir]}
 VCS_INFO_git_getbranch ${gitdir}
-gitbase=$( ${vcs_comm[cmd]} rev-parse --show-toplevel 2> /dev/null )
+gitbase=${vcs_comm[basedir]}
 if [[ -z ${gitbase} ]]; then
     # Bare repository
     gitbase=${gitdir:P}
diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info
index 786b61918..53e0f9416 100644
--- a/Functions/VCS_Info/vcs_info
+++ b/Functions/VCS_Info/vcs_info
@@ -54,7 +54,7 @@ vcs_info () {
     [[ -r . ]] || return 0
 
     local pat
-    local -i found retval
+    local -i retval
     local -a enabled disabled dps
     local usercontext vcs rrn quiltmode
     local -x LC_MESSAGES
@@ -114,7 +114,9 @@ vcs_info () {
 
     VCS_INFO_maxexports
 
-    (( found = 0 ))
+    local -A deepest_vcs_comm deepest_backend_misc
+    local deepest_vcs find_first
+
     for vcs in ${enabled} ; do
         [[ -n ${(M)disabled:#${vcs}} ]] && continue
         if (( ${+functions[VCS_INFO_detect_${vcs}]} == 0 )) ; then
@@ -124,10 +126,25 @@ vcs_info () {
         fi
         vcs_comm=()
         VCS_INFO_get_cmd
-        VCS_INFO_detect_${vcs} && (( found = 1 )) && break
+        if VCS_INFO_detect_${vcs}; then
+            zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" find-deepest
+            find_first=$?
+
+            if (( find_first )) || (( ${#vcs_comm[basedir]//[!\/]} > ${#deepest_vcs_comm[basedir]//[!\/]} )) ; then
+                deepest_vcs="${vcs}"
+                deepest_vcs_comm=("${(kv)vcs_comm[@]}")
+                deepest_backend_misc=("${(kv)backend_misc[@]}")
+
+                (( find_first )) && break
+            fi
+        fi
     done
 
-    (( found == 0 )) && {
+    vcs="${deepest_vcs}"
+    vcs_comm=("${(kv)deepest_vcs_comm[@]}")
+    backend_misc=("${(kv)deepest_backend_misc[@]}")
+
+    [ -z "${vcs}" ] && {
         vcs='-quilt-'; quiltmode='standalone'
         VCS_INFO_quilt standalone || VCS_INFO_set --nvcs
         return 0
-- 
2.29.0





Messages sorted by: Reverse Date, Date, Thread, Author