Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [PATCH] vcs_info: add 'find-deepest' zstyle
- X-seq: zsh-workers 47519
- From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
- To: Frank Terbeck <ft@xxxxxxx>
- Subject: Re: [PATCH] vcs_info: add 'find-deepest' zstyle
- Date: Wed, 4 Nov 2020 08:42:16 +0000
- Archived-at: <https://zsh.org/workers/47519>
- Archived-at: <http://www.zsh.org/sympa/arcsearch_id/zsh-workers/2020-11/20201104084216.31fd5317%40tarpaulin.shahaf.local2>
- Authentication-results: zsh.org; iprev=pass (out3-smtp.messagingengine.com) smtp.remote-ip=66.111.4.27; dkim=pass header.d=daniel.shahaf.name header.s=fm1 header.a=rsa-sha256; dkim=pass header.d=messagingengine.com header.s=fm1 header.a=rsa-sha256; dmarc=none header.from=daniel.shahaf.name; arc=none
- Cc: zsh-workers@xxxxxxx
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= daniel.shahaf.name; h=date:from:to:cc:subject:message-id :in-reply-to:references:mime-version:content-type :content-transfer-encoding; s=fm1; bh=hJL4GLD9ZzR0lRSwRBLiQzeUvD TlK7/MI/d2JQzxrpI=; b=b/+oWemH1sb5DzcwrYiEAhiyRGJKXcnpn7Gi+BiTBX T7b7eKVKcscVkezr4BdLG0yfFTM2omUMsnDFMcjAQe637Dg5fHeBvHc5EhdGK5Ft F6zXAqUi8CgN9thTbQXjque2uiVCZ5OwCL3o8GI72BkyCzrrsvMlHeKIm30KyxYC ZHy81/5r+nJ/neG3XUmOrukpAdMxpVSnOR+cHiBRk5AzPJcLakOzixEdbzL8v2QU kc6U8ClZxr0EoE9qrZiuL/tLtqoIvZJ4xmsIbUNm0PV3TaQjv7fJ5CXEB6IPUOz/ Qq0U7MY1VIWZNV0EnbT/CYd9F5Rc2obHioYz6mQ3CLyw==
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; bh=hJL4GLD9ZzR0lRSwRBLiQzeUvDTlK7/MI/d2JQzxr pI=; b=ckR5QZltEgS6HBv+hjrWHizwnxCliJ6rxfL9ZIv49DYe5CUNeefTTiCr+ iV3PE3QUTA2jl/6aApkhn0MAP50qdfATZaaobW2OmwggQlee9Xkz63vh+pizcpMb 95Bhl/LX9KnD/GQPvv5OQKkFP70ncixE8xIGoow190lwWKqwqoYbauPOB3BmcIqK MH3FQAEAVjVWal46jDji8+Jc2zQSv7qGsSrfzh5nlCaGX36uDzfWEAfUEzYUcfgA 4YxB1RWw7V6VRIknTQT8DkbK1dMuLHwxjpen5bOmdCO0bUXTT6EbpOO0LbLeNcpH MkyPBWqeCXfXCx2QxMs2vSqE/coCQ==
- In-reply-to: <87v9ewjxbz.fsf@ft.bewatermyfriend.org>
- List-archive: <http://www.zsh.org/sympa/arc/zsh-workers>
- List-help: <mailto:sympa@zsh.org?subject=help>
- List-id: <zsh-workers.zsh.org>
- List-owner: <mailto:zsh-workers-request@zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-subscribe: <mailto:sympa@zsh.org?subject=subscribe%20zsh-workers>
- List-unsubscribe: <mailto:sympa@zsh.org?subject=unsubscribe%20zsh-workers>
- References: <20201023083444.1565608-1-mezin.alexander@gmail.com> <20201023234855.5a0c6290@tarpaulin.shahaf.local2> <87mu0clbw2.fsf@ft.bewatermyfriend.org> <37168-1603506679.130606@RR8o.26Eg.GGvC> <20201025195401.3c54c6a2@tarpaulin.shahaf.local2> <878sbtlx0o.fsf@ft.bewatermyfriend.org> <56643e6c-0f7c-49f0-8089-4d4a42008dae@www.fastmail.com> <87v9ewjxbz.fsf@ft.bewatermyfriend.org>
- Sender: zsh-workers-request@xxxxxxx
(Sorry again for the late/out-of-order replies.)
Frank Terbeck wrote on Tue, 27 Oct 2020 02:01 +0100:
> Daniel Shahaf wrote:
> > Frank Terbeck wrote on Sun, 25 Oct 2020 23:13 +00:00:
> >> Daniel Shahaf wrote:
> […]
> >> > +1, primarily because git is much more stateful (e.g., interrupted
> >> > rebases).
> >>
> >> I think it's mostly because git is a decentralised system, where more
> >> information is available without having to touch a networked system,
> >> like the central server in centralised systems. The latter will kill
> >> latency dependant use cases, such as prompts.
> >
> > I don't see how vcs_info's admittedly increased usefulness under Git
> > follows from Git's being decentralized and from more information being
> > available locally.
>
> The fact that the system *can* do things *locally* enables things like
> notifying the user about differences in tracked files — like staged and
> unstaged changes.
(The language "do things" is rather imprecise.)
The ability to show staged/unstaged mods has nothing to do with the
entire history being available locally and everything to do with the
data model sporting three trees: the latest commit, the change the user
is about to commit, and the user's worktree.
Git calls these HEAD, index, and worktree. Subversion calls these BASE,
WORKING, and ACTUAL (the last term is not part of the public API).
The three Git trees work just fine in a «git clone --depth=1» worktree.
That's part of the reason vcs_info is as useful in such worktrees as
in other Git worktrees, despite the shallowness.
Across the pond, in Subversion it's possible to have differences between
BASE and WORKING (e.g., through any use of the add/rm/mkdir/cp/mv/prop*
subcommands), and I think it would be reasonable for the svn backend to
have stagedstr shown in those cases (namely, if «svn status | grep -E
'^[AD]|^.M'» is non-empty).
> > On the other hand, consider «git rebase -i» which I cited as an example.
> > There is no conceptual problem with implementing the equivalent of that
> > feature in Subversion — and if that were done, showing state in the
> > prompt would become much more useful under that backend.
>
> Certainly — I don't doubt features being present in the git-backend that
> are not applicable with other systems.
>
> I was merely stating my impression. I don't think it's a coincidence
> that the two most feature-rich backends are the ones for git and mercu-
> rial. I think the low-latency nature of local information enables this.
>
That would depend on what you mean by "local information".
Git, for instance, is stateful (e.g., «git merge --no-commit»,
interrupted rebases, etc). The state is local (and hence is low
latency). So is the entire history. However:
- vcs_info queries only the state, not the history, so the history's
latency is a red herring.
- State information would be local (and hence low latency) in Subversion
too.
I do agree that the low-latency nature of the information that vcs_info
_does_ query is important. However, vcs_info wouldn't actually care
that much if .git/objects/**/*(md+7) were mounted on a slow network
disk, would it?
> That is not to say that other factors cannot play a role, but this is
> the one that I always considered the “obvious” reason. Clearly only for
> some values of “obvious”. :)
:)
> > Furthermore, under Subversion I use hooks to display some additional
> > information I find useful: a list of changelist names and the
> > modified/switched/partial-depth indications from `svnversion` output.
> > None of these states is inherent to Subversion's centralized
> > nature: there's nothing stopping git and hg from implementing the
> > equivalents of «svn changelist», «svn switch» and «svn update
> > --set-depth=exclude». (To be clear, I'm not saying they should. I'm
> > just saying those features are orthogonal to centralization/decentralization.)
>
> Sure. I wonder however, how long this takes.
[...]
> Not having to access the network enables using this sort of
> information because you get to it quicker.
The changelist names and switched/partial-depth indications are local
SQLite queries. The 'modified' information (unavoidably) requires
a local disk crawl, so it's conditional on the check-for-changes style.
None of these require network access.
> My experience with subversion was always that any time I had to hit
> the network, and you need to for basically everything, latency was
> unbearable for use in prompts. Even with servers in the same
> building.
What information did you want to show in the prompt that required
a network round-trip?
As to the latency, the report is not very concrete, but feel free to hit
users@svn (or me offlist) with more details, if needed.
> > P.S. Speaking of my hooks, I've got some other ones that might be of
> > independent interest: I have my svn prompts show the `svnversion`
> > output's revision range, e.g., "42:100", rather than just whatever `svn
> > info --show-item=revision ./` happens to be;
>
> Sounds useful. But I always thought svnversion also had to hit the net-
> work,
svnversion doesn't hit the network, ever:
% ldd =svnversion | grep libsvn_ra
%
> to figure out if the working copy has local modifications.
No. Subversion can determine local modifications without accessing the
server. Were you perhaps thinking of CVS?
> Does this run in finite time […]?
I'm sure it does, and when my test run finishes, I'll let you know how
long it took. :-)
Seriously, though, as I mentioned, just does a SQLite database query
(plus a disk crawl if that's been opted in to). More precisely, it
makes a dummy propmod, calls svnversion(1), and reverts the propmod.
(The write operations are conditional on another opt-in knob.) That's
in order to ensure svnversion(1) doesn't fall back to a disk crawl when
check-for-changes is unset.
The dummy propmod design does mean I don't get an indication of local
mods when there are legitimate tree/property changes in the tree.
It'd be easy to add a --never-do-a-disk-crawl flag to svnversion(1)
itself to remove the need for the dummy propmod. (It'd just be a matter
of revving svn_wc_revision_status2() with an additional boolean
parameter.)
> > I print the topmost patch
> > in quilt addon mode, and the commit being rebased in interrupted
> > rebases; and I indicate presence of GIT_* envvars and per-repository
> > addons (e.g., git-annex(1), vcsh(1)).
>
> This sounds interesting. Care to share? :)
Sure, enclosed.
I wonder whether the $pc/.snap check should be upgraded to a patch. It seems
to work fine so far, at least.
Cheers,
Daniel
_git_config_setting_exists() {
git config --get-all --null -- "$1" >/dev/null
}
zstyle ':vcs_info:*+gen-applied-string:*' hooks gen-applied-string
+vi-gen-applied-string() {
# Arguments: $1 is the topmost patch;
# the value of each parameter is as though by [in git terms] --pretty="%H %s"
local H s
H=${1%% *}
s=${1#* }
s=${s/#$'\x5bPATCH '/$'\x5b'} # s#[PATCH 3/8]#[3/8]#
# Truncate the hash, if the VCS uses hashes for revision numbers.
# Under quilt, $H is the patch filename.
#
# cf the 'enable' style.
if [[ $vcs == (git|hg|bzr) ]] && ! (( $+funcstack[(r)VCS_INFO_quilt] )); then
H=$H[1,12]
fi
if [[ $vcs == git && $H == <0-> ]]; then
# git-am(1)
#
# ${patchdir} is set by VCS_INFO_get_data_git
# That's an implementation detail twice over, but $ZSHRC_COMMIT_BEING_REBASED is shown interactively before it's used, so *shrug*
local new_value
printf -v new_value "%s/%04d" "${patchdir}" "$H"
H=${new_value##*/}
typeset -g ZSHRC_COMMIT_BEING_REBASED=${new_value}
else
typeset -g ZSHRC_COMMIT_BEING_REBASED=$H
fi
print -Pr -- >&2 "zshrc: setting ZSHRC_COMMIT_BEING_REBASED=%B${(qq)new_value//'%'/%%}%b"
# (Actually, I name the global variable just «$y» for convenience, but I changed that for posting.)
## Change ASCII ellipsis (added by VCS_INFO-set-patch-format) to Unicode ellipsis, to save columns
if [[ $s =~ [.][.][.]$ ]]; then
s[-3,-1]=…
fi
## Try harder to get meaningful information
if [[ $s == '?' ]] && (( $+funcstack[(r)VCS_INFO_quilt] )); then
# By now, VCS_INFO_quilt will have run quilt commands, so we needn't worry about ${QUILT_PATCHES}
if quilt top >/dev/null; then
# Silence stderr because of "Warning: more recent patches modify files in patch $H"
# Silence stderr because of "Patch debian/patches/foo.diff is not applied"
local -a files_touched; files_touched=( ${(f)"$(quilt diff -P "$H" -p0 2>/dev/null | lsdiff)"} )
if (( $#files_touched == 1 )); then
s="(${files_touched[1]})"
else
s="(${#files_touched}:`quilt diff -P "$H" -p0 2>/dev/null | wc -l` files:ΔLoC)"
fi
fi
fi
# Under quilt, add an indicator of whether a `quilt snapshot` exists
local stagedstr=
if (( $+funcstack[(r)VCS_INFO_quilt] )) && [[ -d $pc/.snap ]]; then
zstyle -s "${context}" stagedstr stagedstr
fi
## Set [applied-string] to the original value of $1, plus $stagedstr, plus coloring.
hook_com[applied-string]="%F{yellow}${H//'%'/'%%'}%f${stagedstr} ${terminfo[dim]}${s//'%'/%%}${terminfo[sgr0]}"
## Tell vcs_info to use our value.
ret=1
}
zstyle -e ':vcs_info:git+set-message:*' hooks 'reply=( ${${(k)functions[(I)[+]vi-git-set-message*]}#+vi-} )'
+vi-git-set-message_git-annex() {
(( $1 == 0 )) || return 0
# If this is a git-annex repository, then display "/annex" when working on the master
# branch, and a Big Red Warning when the special "git-annex" (sic) branch is checked out.
if _git_config_setting_exists 'annex.uuid'; then
if [[ ${hook_com[branch_orig]} == *git-annex* ]]; then
hook_com[branch]='%F{red}%B'${hook_com[branch]//'%'/%%}'%f%b'
else
hook_com[branch]+="%f/annex" # %f ends coloring
fi
fi
return 0
}
+vi-git-set-message_vcsh_and_git_dir() {
(( $1 == 0 )) || return 0
# If this is a vcsh repository, then display "/vcsh:foo" where 'foo' is
# the repository basename (from $GIT_DIR, $VCSH_DIRECTORY, $VCSH_REPO_NAME).
#
# Else, if $GIT_DIR is set, then warn about it.
if _git_config_setting_exists 'vcsh.vcsh'; then
hook_com[branch]+="%f/vcsh${GIT_DIR:+":${${GIT_DIR:t}%.git}"}" # %f ends coloring
elif [[ ${(t)GIT_DIR} == *'export'* ]]; then
# TODO: simplify?
if [[ $GIT_DIR == $PWD(/.git|) ]]; then
# nothing
elif
# silence errors when not inside a git dir
[[ $GIT_DIR != `unset GIT_DIR; git rev-parse --git-dir 2>/dev/null` ]]
then
hook_com[branch]+="%f%B%F{yellow}@${(q-)${${GIT_DIR%.git}%/}:t}%f%b"
fi
fi
return 0
}
# Show in the prompt names and values of ${GIT_*} variables.
# TODO: only show exported ones
+vi-git-set-message_git_others() {
local GIT_DIR
unset GIT_DIR # handled by +vi-git-set-message_vcsh_and_git_dir
local -a gits=( "${(k@)parameters[(I)GIT*]}" )
for 1 in $gits; do
hook_com[branch]+=";%U${(q-)1}%u%F{white}=${(Pq-)1//'%'/%%}%f"
done
return 0
}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author