summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordana <dana@dana.is>2025-05-10 22:30:41 -0500
committerdana <dana@dana.is>2025-11-16 10:45:46 -0600
commit1a3c753ae87d9123578141b2b46460eeec7163fd (patch)
tree9b4381292d2cbe0e29d93b9ca9c8ec8dc6a08214
parent53964 (+ tiny change): improve the description of parameter RANDOM (diff)
downloadzsh-1a3c753ae87d9123578141b2b46460eeec7163fd.tar
zsh-1a3c753ae87d9123578141b2b46460eeec7163fd.tar.gz
zsh-1a3c753ae87d9123578141b2b46460eeec7163fd.tar.bz2
zsh-1a3c753ae87d9123578141b2b46460eeec7163fd.tar.lz
zsh-1a3c753ae87d9123578141b2b46460eeec7163fd.tar.xz
zsh-1a3c753ae87d9123578141b2b46460eeec7163fd.tar.zst
zsh-1a3c753ae87d9123578141b2b46460eeec7163fd.zip
53577: _git: improve max-verbose, other descriptions
- add ability to style specific ref types - significantly improve performance of resolving unambiguous ref names - fix display of ref names without descriptions - make branch and commit descriptions more consistent - improve format of alias descriptions
-rw-r--r--ChangeLog5
-rw-r--r--Completion/Unix/Command/_git58
2 files changed, 53 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index d63dbf75a..a5caf0b30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2025-11-16 dana <dana@dana.is>
+
+ * 53577: Completion/Unix/Command/_git: improve max-verbose,
+ other descriptions
+
2025-11-13 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
* 53964 (+ tiny change): Doc/Zsh/params.yo: mention zsh/random
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 1bede1e69..93275124d 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -36,6 +36,17 @@
# use the `use-fallback' style like this:
#
# % zstyle ':completion:*:*:git*:*' use-fallback false
+#
+# To show verbose descriptions for certain refs (the messages associated with
+# branch HEADs and other commits), set the `max-verbose` style:
+#
+# % zstyle ':completion:*:*:git*:*' max-verbose 99
+#
+# The value specifies the number of matches already added for completion after
+# which descriptions should not be provided. You can also disable descriptions
+# for specific ref types by specifying a tag:
+#
+# % zstyle ':completion:*:*:git*:remote-branch-names-noprefix' max-verbose 0
# TODO: There is still undocumented configurability in here.
@@ -6358,14 +6369,38 @@ __git_describe_branch () {
local __desc=$3
shift 3
- integer maxverbose
- if zstyle -s :completion:$curcontext: max-verbose maxverbose &&
- (( ${compstate[nmatches]} <= maxverbose )); then
- local __c
- local -a __commits
- for __c in ${(P)__commits_in}; do
- __commits+=("${__c}:${$(_call_program describe git rev-list -1 --oneline $__c)//:/\\:}")
- done
+ integer __maxverbose
+ if zstyle -s :completion:$curcontext:$__tag max-verbose __maxverbose &&
+ (( ${compstate[nmatches]} <= __maxverbose )); then
+ local __x __y
+ local -a __cin __revs __descs __commits
+
+ # Calling git rev-list for each individual ref can be slow. We can pass them
+ # all at once instead, but it combines all refs that point to the same rev
+ # into one line in the output, making it difficult to match the results back
+ # to the input. To work around this, we first build a list of individual
+ # revisions that each ref refers to. Then we have rev-list include the full
+ # revision in its output, and we loop through and match everything up
+ __cin=( ${(P)__commits_in} )
+ __revs=( ${(f)"$( _call_program revs git rev-parse ${(q)__cin} )"} )
+
+ if (( $#__revs == $#__cin )); then
+ __descs=( ${${(f)"$( _call_program describe-full-hash \
+ git rev-list --no-walk=unsorted --pretty='"format:%H [%h] %s"' ${(q)__cin}
+ )"}:#commit *} )
+ for __x __y in ${__cin:^__revs}; do
+ __commits+=( $__x:${${__descs[(r)$__y *]}#* } )
+ done
+ # If the above didn't work, the ref names were ambiguous, probably 'bare'
+ # remote branch names. Fall back to the slower method. This won't resolve
+ # anything that rev-parse didn't, but it'll return what it could
+ else
+ for __x in $__cin; do
+ __y=$(_call_program describe git rev-list -1 --format='"[%h] %s"' $__x)
+ __y=${__y#*$'\n'} # Strip off commit header
+ __commits+=("${__x}${__y:+:$__y}")
+ done
+ fi
_describe -t $__tag $__desc __commits "$@"
else
local expl
@@ -6645,7 +6680,7 @@ __git_extract_aliases () {
local -a tmp
tmp=(${${(0)"$(_call_program aliases "git config -z --get-regexp '^alias\.'")"}#alias.})
if (( ${#tmp} > 0 )); then
- aliases=(${^tmp/$'\n'/:alias for \'}\')
+ aliases=(${${tmp/$'\n'/:alias for: }//[[:space:]]##/ })
else
aliases=()
fi
@@ -7236,7 +7271,10 @@ __git_recent_branches() {
# 4. Obtain log messages for all of them in one shot.
# TODO: we'd really like --sort=none here... but git doesn't support such a thing.
local z=$'\0'
- descriptions=( "${(0)"$(_call_program all-descriptions "git --no-pager for-each-ref --format='%(refname)%00%(subject)'" refs/heads/${(q)^branches} "--")"//$'\n'/$z}" )
+ descriptions=( "${(0)"$(_call_program all-descriptions \
+ "git --no-pager for-each-ref --format='%(refname)%00[%(objectname:short)] %(subject)'" \
+ refs/heads/${(q)^branches} "--"
+ )"//$'\n'/$z}" )
# 5. Synthesize the data structure _describe wants.
local -a branches_colon_descriptions