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 29875 invoked from network); 23 Nov 2021 16:04:28 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 23 Nov 2021 16:04:28 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1637683468; b=LttttD+lswLb8o72nUQuCekD82cLOWZdAya/GvIdQobMJZw2PvJKYcViW4BDU7j3z9o9szhaTM ZCUfVdqPxoPfYShWg3GnYmy7Y+Fc8x1gCAPUxmt5gNlz7CyOHfv6lOmTf4+Npz126aIqjSQN8R ITNxqzCGwToyq91Aa7Xt3yyW7Pnk6sPvjonGOYW1SZRMcK7DiNYv/1OE8krEV5yyeqcf+l2nCS TZ3MH1Po3gjlLvZcRUc+WfhhhuQlLnBBxtJkIn8Z8pYOkMEcoNBKuIMYvtJm5YhyQDHNAimqfk Xya6hbiRUnaGbL1d3XLGvyq34jsJ1oYr62ZSbGbM9raRVg==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (mail-lf1-f42.google.com) smtp.remote-ip=209.85.167.42; dkim=pass header.d=gmail.com header.s=20210112 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-20210803; t=1637683468; bh=fbLXg2ZIJGMXW7/I7E6RMDThyxJ0p+1cu7oy1O1LU14=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Type:To:Subject:Message-ID:Date:From:In-Reply-To: References:MIME-Version:DKIM-Signature:DKIM-Signature; b=TqvF1YCJ+EwzMKKs6ML+PirZxqDBRalJTP2dMTfP9wMUvt1K5sYhvRzIW2r0ar50jABb49mLDf yjTbCaO90cA7Kx+dCoEZK0l36EdTQEqDS/hpdPAYEA2KDvWQHP9kiPYPltHsa0Di1bAas7D0sL BquoacwP9OgxOAOLS1U2aGvgv1nU9eSzV3UAPE3hNAe3cYzTmAsITN6qcpqMi0b39WT0CjV+hi wV5gJhXmY5d2SYhg8H5KPT5pHvGv+xzryHiITn2R4J6wONocu4scBISW7bV0OUwbmTAKvrOPOz NXMv98Jsir5+XSeaOMelTKn9iAiI/wzkBOz1Xf7qWH5v6w==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Content-Type:To:Subject:Message-ID: Date:From:In-Reply-To:References:MIME-Version:Reply-To:Cc: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=EZXGAbDnNi/P4jxjjVnP62yzS6O/vNloz+/a9kdhEKk=; b=IVvR8SSwjpCRUuUmne1a1VPfkE GReZAou/XT2pt3S3qeMoBxymwKjy/xjw7U14a68CP9xB3f+3+ao00k2kVQUcoOMHe3NbdKnLYLtcO iYZzt0kawCxHmDAMrxjGmAxkWYPhi2QDPx0CAN589LOCIxb5iYmM1KFKB96JhSqQgZTvuKXBDKqjG JvyBF042cF0GcVtzQIE79Nf4wD1PPIrO7Tchv65TwBAlJzay95rp2a/ztouJJ++fllEsavCIa4Wb+ g/zt4TWULwsIjR1Mo3zVQ+IObSGnvDtsbTu246/2m0eUdNtULqlQC6CHMrw6AR0jUzD1sjOaJpdY/ qdyhI0wA==; Received: from authenticated user by zero.zsh.org with local id 1mpYHT-000Ijq-9K; Tue, 23 Nov 2021 16:04:27 +0000 Authentication-Results: zsh.org; iprev=pass (mail-lf1-f42.google.com) smtp.remote-ip=209.85.167.42; dkim=pass header.d=gmail.com header.s=20210112 header.a=rsa-sha256; dmarc=pass header.from=gmail.com; arc=none Received: from mail-lf1-f42.google.com ([209.85.167.42]:38668) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_128_GCM_SHA256:128) id 1mpYGv-000IUA-G4; Tue, 23 Nov 2021 16:03:54 +0000 Received: by mail-lf1-f42.google.com with SMTP id bi37so92264992lfb.5 for ; Tue, 23 Nov 2021 08:03:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=EZXGAbDnNi/P4jxjjVnP62yzS6O/vNloz+/a9kdhEKk=; b=ch9QepZgTD+Ge3XI9ipN6OrFFNrDqWX/9ViOFIoEAG7UhbqOBBtF6y7QHzllxZSsoy rxKB2ugghvEqlB6+KCIBLxVw9ZWRZeNhIgzVcJOa/wrMpe1nm+KqTBxnRbXRJPVyzPt0 yu9u84uqzW9JTw2sBFXfXQb1UG4LeE7YSypN+55gyrqLH71JafQhslGQSlT+0GLW1hed SChEnDgAbVweoMLadlBmx0cNnCqyROyJLsBxyQ+QT7QdMVX3RP8Ty0HmpTinU+2Vro48 jBYj+UQLPgqLqr80JeUIKf1Y/+knKJMBHpuB+LzR52mCsPCNVgFiCFuEDKym+nTd3chP yXTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=EZXGAbDnNi/P4jxjjVnP62yzS6O/vNloz+/a9kdhEKk=; b=tHmtots9N6W4l3TLE5ePsVTA+CVIQNFkalrNffs2I7hdyhqPYyiaes8ovXplQhnqrp 3IgAfEbDGq1vaZwzv81j2Za1zcf3RNX/PlMdiKT1SKrKYVpcSpxBZRmIsLkqNTMbHIED TkzE07XhcO7+H5IUFuf4Qn0kmyRNIUTbJYFu23Anag0omy3lLGqkfdiGJ3yKl5BcvSfw FZyKJtEcUYuPq/7XyMNk/jsX18JuVuFVeNEfZVC9KOu2mZFqPPLu6oFGwjlIijUPMS7f 6SXkV0ONsYBgYDg8kHk6s5j3GWTXI+oPN2eb9uz+SDh44e8SUtTDYkd6WfXzfz1NH+yY gonQ== X-Gm-Message-State: AOAM531H0EaO/Nq1MlLlXZfHVBW46HyLwHpAsOUSnBzn/29j8AuNdhaZ zc33toVamagcXXH4a6NpWA1isN3LN8iTkO/mJQ6A7zzdEnE= X-Google-Smtp-Source: ABdhPJzj3XFjGkTTA5pq29w4YsQXVQJKvO6mFIMzQK1n8oQYckfCpZFjlal1PpDwAjl4OR9WU7qDToFoRdFT+rGcXsI= X-Received: by 2002:ac2:53ad:: with SMTP id j13mr5945912lfh.511.1637683430750; Tue, 23 Nov 2021 08:03:50 -0800 (PST) MIME-Version: 1.0 References: <20210604061421.172899-1-mezin.alexander@gmail.com> In-Reply-To: <20210604061421.172899-1-mezin.alexander@gmail.com> From: Aleksandr Mezin Date: Tue, 23 Nov 2021 22:03:39 +0600 Message-ID: Subject: Re: [PATCH v5] vcs_info: choose backend by basedir To: zsh-workers@zsh.org, Daniel Shahaf Content-Type: text/plain; charset="UTF-8" X-Seq: 49599 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: Ping On Fri, Jun 4, 2021 at 12:14 PM Aleksandr Mezin wrote: > > 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. > > Signed-off-by: Aleksandr Mezin > --- > v4: back to boolean zstyle, keep old behavior by default, documentation > v5: described expected vcs_info[basedir] use in a comment, addressed Daniel's > questions in comments. > > Completion/Zsh/Command/_zstyle | 1 + > Doc/Zsh/contrib.yo | 41 ++++++++++++++++++++++ > Functions/VCS_Info/vcs_info | 62 +++++++++++++++++++++++++++++++--- > 3 files changed, 100 insertions(+), 4 deletions(-) > > diff --git a/Completion/Zsh/Command/_zstyle b/Completion/Zsh/Command/_zstyle > index 9d06076e4..b7a73c5a2 100644 > --- a/Completion/Zsh/Command/_zstyle > +++ b/Completion/Zsh/Command/_zstyle > @@ -193,6 +193,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 a972f08d6..67823716a 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/vcs_info b/Functions/VCS_Info/vcs_info > index 786b61918..85f7ca0ab 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 > @@ -64,6 +64,9 @@ vcs_info () { > # vcs_comm is used internally for passing values among VCS_INFO_* functions. > # It is not part of the public API. > # > + # VCS_INFO_detect_* functions should set vcs_comm[basedir] to the path to > + # the root of the working copy. > + # > # hook_com, backend_misc, and user_data are public API; see zshcontrib(1) > # and Misc/vcs_info-examples. > local -A vcs_comm hook_com backend_misc user_data > @@ -114,7 +117,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 +129,59 @@ vcs_info () { > fi > vcs_comm=() > VCS_INFO_get_cmd > - VCS_INFO_detect_${vcs} && (( found = 1 )) && break > + if VCS_INFO_detect_${vcs}; then > + # Most backends already set vcs_comm[basedir] to an absolute path > + # with symlinks resolved: > + # > + # * Backends using VCS_INFO_bydir_detect: > + # bzr, cdv, darcs, fossil, hg, mtn, p4, svn > + # > + # * cvs - custom logic, but uses :P too > + # > + # * git - $(git rev-parse --show-toplevel) resolves symlinks and > + # returns an absolute path > + # > + # * for tla (GNU Arch) I can't find any online documentation or > + # packages (seems to be dead) > + # > + # * svk doesn't use :P modifier and returns the path as is from > + # the config file (as far as I understand) > + # > + # So I'm not sure whether to modify the backends or just resolve > + # the path here to be sure. VCS_INFO_get_data_* usually reads > + # vcs_comm[basedir] too. In particular, I'm not sure if it's safe to > + # resolve symlinks in vcs_comm[basedir] for svk. > + # > + # Because most backends already do :P substitution, I expect all > + # the info needed to resolve the path to be cached in memory by the > + # OS (so it shouldn't cause performance issues). > + basedir_realpath="${vcs_comm[basedir]:P}" > + > + zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" choose-closest-backend > + choose_first_available=$? > + > + [[ "${PWD:P}/" == "${basedir_realpath}"/* ]] || [[ "${basedir_realpath}" == "/" ]] || choose_first_available=1 > + > + # If choose_first_available is 0 at this point, all basedir_realpaths > + # (and thus chosen_basedir_realpath) are parents (and thus prefixes) > + # of PWD:P. So comparing their lengths is enough to figure out which > + # one is closer to PWD. > + 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.31.1 >