From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 13487 invoked from network); 14 Nov 2020 19:37:39 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 14 Nov 2020 19:37:39 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20200801; t=1605382659; b=ukrrzjNHbRrnlCjwKEOITHkvEu0HTtSmouwF0ey50URQ+yJj9RHDdwx6TYZJ+fHv7Bev69btGX SCvCv8LF1UxqkTXVAQqaHS8HJcn4mutZ51DQkCj6e65f4nVIZJbHhaR2X7e0KcDvtaXJV/yPZg ubGAcq1ibT+5bvS4TZXZjK8/7jl7TBYeO5O0jAcgp+E1iozznx3Lh00dGmLJg275d80Ui8+vsS /fLiqPFfpnYd9l21JcALrEVwCxsarx4FH2EcKPLeAIiFIuquP8Ku72enLpPud7TmJNEW+qRnXZ HE8dtiHtiQT543ng3DlwQNDh2Mfe80DqwcsvEOE94v+Iyg==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (mail-lj1-f178.google.com) smtp.remote-ip=209.85.208.178; dkim=pass header.d=gmail.com header.s=20161025 header.a=rsa-sha256; dmarc=pass header.from=gmail.com; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20200801; t=1605382659; bh=SiGWkHwLxex0bnJB7zCfdXQKcKhdxPZkig8QwoxmkFE=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Transfer-Encoding:MIME-Version:Message-ID:Date: Subject:Cc:To:From:DKIM-Signature:DKIM-Signature; b=nxOAdKalAEnoX4Gx8zusvj6+V7A8l3VbRazFkwFQ24Pd1lb+NaOaiGHMEyB9Floq1mvsGSa+me WvVusOJPyVNQCpXiN23W584qKDKYitfuwzNJaKlOilD7k8JUIuqCVCP2QHnYyw4rsvLqvo5UoM 8VMWQCBruckJZHHls8gcT6ru7t9OgEo5omj8fRUvoC7LVFKR2ol2svt8FD4nKjFirBZDWOCPIm Z8CDKZsi3uoyZA2nLNNjSTTPt1SxmpMi0lS+s6LewHHadtyR/ShlidiSBrYswhbxAiUNpZuEjd Wf2uTSYySbiLgO1ebOV7QixDzuNeny66qhbOZIK+lNjp2g==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20200801; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Content-Transfer-Encoding: MIME-Version:Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References; bh=CIV/e81siKeFq7L7yI0GqAFf+I1aDnlHhw81kFDmVzw=; b=WMSjPxAE2SLWtK10h4GIcYFUvN 1aMRpYO+5b1vCmDyRUY/vRSlt6yR3H6FuwP6bSVWjQpA0XYygzOXtMZnKj/cwsuFmThXir7n9uTJ2 g/9jSj6VMF6PkzAzhvzl0Ky+bMK+qyjBIAhI+b/6dus4bJumgmwtSzpLX9Oprgm8xi+bKLleJZdbZ qvdHkILpFCVuSjC+HhDzfZJg14iWc9vxI1S11+LwxdPf1SmWYmU7To/lzCpJEyQTDDkpUr275map/ rACNZ4dnwSiZdZmZt2V0ITQJxeoNwuOt6ggRQ4itSbWRsxtHsjI98ZYARIplnS+9h6qcX9nebNcb/ A73U/YNg==; Received: from authenticated user by zero.zsh.org with local id 1ke1Md-000GMe-Sm; Sat, 14 Nov 2020 19:37:36 +0000 Authentication-Results: zsh.org; iprev=pass (mail-lj1-f178.google.com) smtp.remote-ip=209.85.208.178; dkim=pass header.d=gmail.com header.s=20161025 header.a=rsa-sha256; dmarc=pass header.from=gmail.com; arc=none Received: from mail-lj1-f178.google.com ([209.85.208.178]:34621) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_128_GCM_SHA256:128) id 1ke1ML-000GDI-1S; Sat, 14 Nov 2020 19:37:17 +0000 Received: by mail-lj1-f178.google.com with SMTP id y16so15054849ljk.1 for ; Sat, 14 Nov 2020 11:37:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=CIV/e81siKeFq7L7yI0GqAFf+I1aDnlHhw81kFDmVzw=; b=GXJOm98x+PS/MMz6RKybU/OVTYbWdESI1Ff+3NfkBJy8opAwQnhbmE9lzkqBOjlI8+ pXmXQ4145mcv+XQ50e8fkMmznShrt6y0UyUF5Ct7gIVOPmp4d04rTrZVQMqnD6okKN7s 5lYHXTx1dsli/oxLayGOaL3AzVLx/eO4fhw3/NhVJ/sWVUAIda+X0WfK6XDEZaZaDJLS ZjmOcEtFpuC7YbUqjN8OM7aMPO2DHcMHh686Bk4FMB9WDbQGZcwEncMoINj1hQLpRMh1 QjC8I++wsz16PmSStbMhJLhNSqqJTqwbOfVgifMzo6xdyVaV8+61nRxbYxcMoeIjFcbN hgMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=CIV/e81siKeFq7L7yI0GqAFf+I1aDnlHhw81kFDmVzw=; b=GHsXuxMyVS50ZW+MJXYbCwwcpYhe+o3zBQihXYM+vqeyRrZoFPfJYpJLQDndVkQ+86 PEZmF6QYS9eHIraOKJSeOlr7vK+oeXIBJIZVldXVYryctPMaPk+d+N2CKO6cTpQOr3UH fNW7b3bFNEHXcti+sQWCjIJc9mTe/KiwA4eh1Tzdc8BntJ1x7bSV8czkZbcJzZz8UN8R loHG6JqQ/nZk4KCUjsoSyjWLZC0AM0VrhWhmdU1WMcbpyO7nExcRVv9DrJfpKyJ5aERv L5iTKxs/eo37Q+QTz7UwCiYlfIW75Mfolo6iwpC3VuEsstfDAr4dR3Rs9+IIj2N0At67 obiQ== X-Gm-Message-State: AOAM532Q+1rOYTO8YWMdq2OpkkwAMjeB0vNQAjFiGCnYTPqz9Rtl0Gkp 5XSxg/Hz1aVLRDkaQslxTsTOF2sVBPeZEWjy X-Google-Smtp-Source: ABdhPJyBOcQU0b9IWtjnGF+rhKxNu1rkWHSwLcQ8bZTPq5Jh/cUmFwFWYJYVFgOOn/WrYd+35vn9FQ== X-Received: by 2002:a2e:9848:: with SMTP id e8mr3491214ljj.353.1605382635741; Sat, 14 Nov 2020 11:37:15 -0800 (PST) Received: from trx40.lan ([2a02:2698:542a:1324::500]) by smtp.gmail.com with ESMTPSA id p24sm2066161lfh.241.2020.11.14.11.37.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Nov 2020 11:37:14 -0800 (PST) From: Aleksandr Mezin To: zsh-workers@zsh.org Cc: Aleksandr Mezin Subject: [PATCH v4] vcs_info: choose backend by basedir Date: Sun, 15 Nov 2020 01:37:03 +0600 Message-Id: <20201114193703.1428617-1-mezin.alexander@gmail.com> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Seq: 47561 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: Archived-At: Previously, vcs_info iterated over enabled VCS backends and output 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. This patch adds a new algorithm for vcs_info to choose the backend: 1. Among backends whose basedir isn't an ancestor of the current directory, old algorithm is used: whichever comes first in 'enable' list. 2. If all backends return basedirs that are ancestors of the current directory, the one with basedir closest to the current directory is chosen. As far as I know, unless the user has set basedir manually (GIT_WORK_TREE), all backend return basedirs that are ancestors of the current directory. Backends that return non-ancestor basedirs have higher priority to show the status of that manually-configured repository. The algorithm used by vcs_info can be configured using 'choose-closest-backend' zstyle: zstyle ':vcs_info:*' choose-closest-backend yes By default, old algorithm is used. It can also be configured per-backend: zstyle ':vcs_info:hg:*' choose-closest-backend no This effectively moves the backend into group (1), as if its basedir is never an ancestor of the current directory. Not sure how useful this is though. Also, this patch adjusts VCS_INFO_detect_git and VCS_INFO_detect_cvs to make them set vcs_comm[basedir], by moving basedir detection code from corresponding VCS_INFO_get_data_* functions. VCS_INFO_detect_git and VCS_INFO_detect_cvs were the only VCS_INFO_detect_* functions not setting it. Signed-off-by: Aleksandr Mezin --- v4: back to boolean zstyle, keep old behavior by default, documentation Completion/Zsh/Command/_zstyle | 1 + Doc/Zsh/contrib.yo | 41 +++++++++++++++++++ .../VCS_Info/Backends/VCS_INFO_detect_cvs | 17 +++++++- .../VCS_Info/Backends/VCS_INFO_detect_git | 1 + .../VCS_Info/Backends/VCS_INFO_get_data_cvs | 11 +---- .../VCS_Info/Backends/VCS_INFO_get_data_git | 2 +- Functions/VCS_Info/vcs_info | 30 ++++++++++++-- 7 files changed, 86 insertions(+), 17 deletions(-) diff --git a/Completion/Zsh/Command/_zstyle b/Completion/Zsh/Command/_zstyle index 75acde5f7..e094b3da8 100644 --- a/Completion/Zsh/Command/_zstyle +++ b/Completion/Zsh/Command/_zstyle @@ -192,6 +192,7 @@ styles=( quilt-standalone v:bool quilt-patch-dir v:_directories quiltcommand v:_command_names + choose-closest-backend v:bool chpwd z:bool progress z:progress diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 00f693664..c0b730850 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -1238,6 +1238,46 @@ of unapplied patches (for example with Mercurial Queue patches). Used by the tt(quilt), tt(hg), and tt(git) backends. ) +kindex(choose-closest-backend) +item(tt(choose-closest-backend))( +By default, tt(vcs_info) tries backends in the order given by the tt(enable) +style, and operates on the repository detected by the first backend to +successfully detect a repository. + +If this style (tt(choose-closest-backend)) is set to tt(true) for some (or all) +backends, all backends will be divided into two groups: + +1) Backends, for which this style is set to tt(true), that detect a +repository/working copy that is an ancestor of the current directory (including +the current directory itself). + +2) All other backends: backends with tt(choose-closest-backend) unset/set to +tt(false); and backends that detected a repository/working copy that's not an +ancestor of the current directory, even if tt(choose-closest-backend) is set to +tt(true) for them. + +First, tt(vcs_info) will try backends from the 2nd group in the order given by +the tt(enable) style, and operate on the repository detected by the first +backend to successfully detect a repository (the default behavior of +tt(vcs_info), only limited to backends from the 2nd group). + +If no backends from the 2nd group detected a repository (or if there are no +backends in that group), tt(vcs_info) will try backends from the 1st group. +tt(vcs_info) will then operate on the repository closest to the current working +directory. + +Usually, all VCS backends search for repositories only in ancestors of the +current directory, and choose the repository closest to the current directory. +So if tt(choose-closest-backend) is set to tt(true) globally for all backends, +tt(vcs_info) will effectively search for the repository closest to the current +directory. + +However, there is at least one backend that can detect a repository in an +arbitrary location - Git backend. tt(GIT_WORK_TREE) can be set to a path that +doesn't point to an ancestor of the current directory. In this case, even if +tt(choose-closest-backend) is set to tt(true) globally for all backends, +the repository/working copy pointed by tt(GIT_WORK_TREE) will be preferred. +) enditem() The default values for these styles in all contexts are: @@ -1272,6 +1312,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(choose-closest-backend))(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..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_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_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..0769bc877 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 chosen_vcs_comm chosen_backend_misc + local chosen_vcs basedir_realpath chosen_basedir_realpath choose_first_available + for vcs in ${enabled} ; do [[ -n ${(M)disabled:#${vcs}} ]] && continue if (( ${+functions[VCS_INFO_detect_${vcs}]} == 0 )) ; then @@ -124,10 +126,30 @@ vcs_info () { fi vcs_comm=() VCS_INFO_get_cmd - VCS_INFO_detect_${vcs} && (( found = 1 )) && break + if VCS_INFO_detect_${vcs}; then + basedir_realpath="${vcs_comm[basedir]:P}" + + zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" choose-closest-backend + choose_first_available=$? + + [[ "${PWD:P}/" == "${basedir_realpath}"/* ]] || choose_first_available=1 + + if (( choose_first_available )) || (( ${#basedir_realpath} > ${#chosen_basedir_realpath} )) ; then + chosen_vcs="${vcs}" + chosen_vcs_comm=("${(kv)vcs_comm[@]}") + chosen_backend_misc=("${(kv)backend_misc[@]}") + chosen_basedir_realpath="${basedir_realpath}" + + (( choose_first_available )) && break + fi + fi done - (( found == 0 )) && { + vcs="${chosen_vcs}" + vcs_comm=("${(kv)chosen_vcs_comm[@]}") + backend_misc=("${(kv)chosen_backend_misc[@]}") + + [ -z "${vcs}" ] && { vcs='-quilt-'; quiltmode='standalone' VCS_INFO_quilt standalone || VCS_INFO_set --nvcs return 0 -- 2.29.2