Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: update git completion
- X-seq: zsh-workers 42019
- From: Oliver Kiddle <okiddle@xxxxxxxxxxx>
- To: Zsh workers <zsh-workers@xxxxxxx>
- Subject: PATCH: update git completion
- Date: Mon, 13 Nov 2017 21:37:15 +0100
- Authentication-results: amavisd4.gkg.net (amavisd-new); dkim=pass (2048-bit key) header.d=yahoo.co.uk
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1510605439; bh=/Wlolt0NP9uvuNXlKNSEwuzPxIFm3SiYDQj6ogU2zj0=; h=From:To:Subject:Date:From:Subject; b=mi9azfZzRBhVQc3xmgJHrGjhSQdBjIIX0Rre5o7QzTZOk5dupPW+o6Q91MPi4FYg3Y6qPgdI81JkGyjqgsSd0iwr5YBWQzGAK4a1QfEs8IKS/RlaaPeG+wC4hRTHh8gPEffTEUa1A94GUPgelBHslyO7ZCuO2a73Xl3vRwgpR+BJnr3Z2yHnzblalVzYTjeT69wKczOG53R377uwWzyKTHt2yoRNW+TSvyqBgtAlpPGAJJjxoajQC3z1K33e1DlnL/EmruIA6ff0e4gYlcM0YFFOoxMW9QGRcdFKfEfbNMl+GOumxoCjRPJd1Lm8V3cPp8XA2cIgy/ikEM2U/BYtng==
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
This brings git option completion up to 2.15.
I also checked for other changes. git relink has gone at some point and
git interpret-trailers was added. In the past, for custom formats, you
needed git log --format=format:%... Now you can skip the format: part.
Completion for git tag/for-each-ref sort keys and formats is also
improved.
Oliver
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 10707b454..9ee2eba76 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -293,9 +293,8 @@ _git-branch () {
l='--color --no-color -r --remotes -a -v --verbose --abbrev --no-abbrev --list --points-at --sort'
c='-l --create-reflog -f --force -t --track --no-track -u --set-upstream --set-upstream-to --unset-upstream --contains --no-contains --merged --no-merged'
- m='-m --move -M'
+ m='-c --copy -C -m --move -M --edit-description'
d='-d --delete -D'
- e='--edit-description'
declare -a dependent_creation_args
if (( words[(I)(-r|--remotes)] == 0 )); then
@@ -325,37 +324,39 @@ _git-branch () {
fi
_arguments -S -s \
- "($c $m $d $e --no-color :)--color=-[turn on branch coloring]:: :__git_color_whens" \
- "($c $m $d $e : --color)--no-color[turn off branch coloring]" \
- "($c $m $d $e --no-column)"'--column=[display tag listing in columns]:column.branch option:((always\:"always show in columns" never\:"never show in columns" auto\:"show in columns if the output is to the terminal" column\:"fill columns before rows (default)" row\:"fill rows before columns" plain\:"show in one column" dense\:"make unequal size columns to utilize more space" nodense\:"make equal size columns"))' \
- "($c $m $d $e --column)"'--no-column[do not display in columns]' \
- "($c $m $d $e )*--list[list only branches matching glob]:pattern" \
- "($c $m $e -a)"{-r,--remotes}'[list or delete only remote-tracking branches]' \
- "($c $m $d $e: -r --remotes)-a[list both remote-tracking branches and local branches]" \
- "($c $m $d $e : -v -vv --verbose)"{-v,-vv,--verbose}'[show SHA1 and commit subject line for each head]' \
- "($c $m $d $e :)--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length" \
- "($c $m $d $e :)--no-abbrev[do not abbreviate sha1s]" \
- "($l $m $d $e)"{-l,--create-reflog}"[create the branch's reflog]" \
- "($l $m $d $e -f --force)"{-f,--force}"[force the creation of a new branch]" \
- "($l $m $d $e -t --track)"{-t,--track}"[set up configuration so that pull merges from the start point]" \
- "($l $m $d $e)--no-track[override the branch.autosetupmerge configuration variable]" \
- "($l $m $d $e -u --set-upstream --set-upstream-to --unset-upstream)"{-u+,--set-upstream-to=}"[set up configuration so that pull merges]:remote-branches:__git_remote_branch_names" \
- "($l $m $d $e -u --set-upstream --set-upstream-to --unset-upstream)--unset-upstream[remove upstream configuration]" \
- "($l $m $d $e)*--contains=[only list branches that contain the specified commit]: :__git_committishs" \
- "($l $m $d $e)*--no-contains=[only list branches that don't contain the specified commit]: :__git_committishs" \
- "($l $m $d $e)--merged=[only list branches that are fully contained by HEAD]: :__git_committishs" \
- "($l $m $d $e)--no-merged=[don't list branches that are fully contained by HEAD]: :__git_committishs" \
+ "($c $m $d --no-color :)--color=-[turn on branch coloring]:: :__git_color_whens" \
+ "($c $m $d : --color)--no-color[turn off branch coloring]" \
+ "($c $m $d --no-column)"'--column=[display tag listing in columns]:column.branch option:((always\:"always show in columns" never\:"never show in columns" auto\:"show in columns if the output is to the terminal" column\:"fill columns before rows (default)" row\:"fill rows before columns" plain\:"show in one column" dense\:"make unequal size columns to utilize more space" nodense\:"make equal size columns"))' \
+ "($c $m $d --column)--no-column[don't display in columns]" \
+ "($c $m $d )*--list[list only branches matching glob]:pattern" \
+ "($c $m -a)"{-r,--remotes}'[list or delete only remote-tracking branches]' \
+ "($c $m $d : -r --remotes)-a[list both remote-tracking branches and local branches]" \
+ "($c $m $d : -v -vv --verbose)"{-v,-vv,--verbose}'[show SHA1 and commit subject line for each head]' \
+ "($c $m $d :)--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length" \
+ "($c $m $d :)--no-abbrev[don't abbreviate sha1s]" \
+ "($l $m $d)"{-l,--create-reflog}"[create the branch's reflog]" \
+ "($l $m $d -f --force)"{-f,--force}'[force the creation of a new branch]' \
+ "($l $m $d -t --track)"{-t,--track}'[setup configuration so that pull merges from the start point]' \
+ "($l $m $d)--no-track[override the branch.autosetupmerge configuration variable]" \
+ "($l $m $d -u --set-upstream --set-upstream-to --unset-upstream)"{-u+,--set-upstream-to=}'[set up configuration so that pull merges]:remote-branches:__git_remote_branch_names' \
+ "($l $m $d -u --set-upstream --set-upstream-to --unset-upstream)--unset-upstream[remove upstream configuration]" \
+ "($l $m $d)*--contains=[only list branches that contain the specified commit]: :__git_committishs" \
+ "($l $m $d)*--no-contains=[only list branches that don't contain the specified commit]: :__git_committishs" \
+ "($l $m $d)--merged=[only list branches that are fully contained by HEAD]: :__git_committishs" \
+ "($l $m $d)--no-merged=[don't list branches that are fully contained by HEAD]: :__git_committishs" \
"($c $l $m $d)--edit-description[edit branch description]" \
$dependent_creation_args \
- "($l $c $d $m $e)"{-m,--move}"[rename a branch and the corresponding reflog]" \
- "($l $c $d $m $e)-M[rename a branch even if the new branch-name already exists]" \
+ "($l $c $d $m)"{-m,--move}"[rename a branch and the corresponding reflog]" \
+ "($l $c $d $m)-M[rename a branch even if the new branch-name already exists]" \
+ "($l $c $d $m)"{-c,--copy}"[copy a branch and the corresponding reflog]" \
+ "($l $c $d $m)-C[copy a branch even if the new branch-name already exists]" \
$dependent_modification_args \
- "($l $c $m $d $e)"{-d,--delete}"[delete a fully merged branch]" \
- "($l $c $m $d $e)-D[delete a branch]" \
+ "($l $c $m $d)"{-d,--delete}"[delete a fully merged branch]" \
+ "($l $c $m $d)-D[delete a branch]" \
{-q,--quiet}"[be more quiet]" \
'*--sort=[specify field to sort on]: :__git_ref_sort_keys' \
'--points-at=[only list tags of the given object]: :__git_commits' \
- "($c $m $d $e -i --ignore-case)"{-i,--ignore-case}'[sorting and filtering are case-insensitive]' \
+ "($c $m $d -i --ignore-case)"{-i,--ignore-case}'[sorting and filtering are case-insensitive]' \
$dependent_deletion_args
}
@@ -929,6 +930,7 @@ _git-format-patch () {
'--no-binary[do not output contents of changes in binary files, only note that they differ]' \
'--root[treat the revision argument as a range]' \
'--zero-commit[output all-zero hash in From header]' \
+ '--progress[show progress while generating patches]' \
': :->commit-or-commit-range' && ret=0
case $state in
@@ -1126,6 +1128,22 @@ _git-init () {
':: :_directories'
}
+(( $+functions[_git-interpret-trailers] )) ||
+_git-interpret-trailers() {
+ _arguments \
+ '--in-place[edit files in place]' \
+ '--trim-empty[trim empty trailers]' \
+ '--where[specify where to place the new trailer]' \
+ '--if-exists[specify action if trailer already exists]' \
+ '--if-missing[specify action if trailer is missing]' \
+ '--only-trailers[output only the trailers]' \
+ "--only-input[don't apply config rules]" \
+ '--unfold[join whitespace-continued values]' \
+ '--parse[set parsing options]' \
+ '--trailer[specify trailer(s) to add]' \
+ '*:file:_files'
+}
+
(( $+functions[_git-log] )) ||
_git-log () {
local curcontext=$curcontext state line ret=1
@@ -1189,6 +1207,8 @@ _git-merge () {
'--abort[restore the original branch and abort the merge operation]' \
'--continue[continue the current in-progress merge]' \
'--progress[force progress reporting]' \
+ '--signoff[add Signed-off-by:]' \
+ '--verify[verify commit-msg hook]' \
'*: : __git_commits -O expl:git_commit_opts'
}
@@ -1988,10 +2008,10 @@ _git-tag () {
"*--no-contains=[only list tags that don't contain the specified commit]: :__git_commits" \
'--merged=-[print only tags that are merged]:: :__git_commits' \
'--no-merged=-[print only tags that are not merged]:: :__git_commits' \
- '--sort=[specify how the tags should be sorted]:mode:((refname\:"lexicographic order"
- version\\\:refname\:"tag names are treated as version numbers"))' \
+ '--sort=[specify how the tags should be sorted]:field:__git_ref_sort_keys' \
'--points-at=[only list tags of the given object]: :__git_commits' \
- '--format=[specify format to use for the output]:format' \
+ '--format=[specify format to use for the output]:format:__git_format_ref' \
+ '--color=-[respect any colors specified in the format]::when:(always never auto)' \
'(-i --ignore-case)'{-i,--ignore-case}'[sorting and filtering are case-insensitive]' \
':: :_guard "^-*" pattern' \
- verification \
@@ -2186,6 +2206,7 @@ __git_config_option-or-value () {
advice.implicitIdentity:'show advice when identity is guessed from system settings::->bool:true'
advice.detachedHead:'show advice when entering detached-HEAD state::->bool:true'
advice.amWorkDir:'show the location of the patch file when git-am fails to apply it::->bool:true'
+ advice.rmHints:'show directions in case of failure in the output of git-rm(1)::->bool:true'
blame.blankboundary:'show blank SHA-1 for boundary commits::->bool:false'
blame.showroot:'show root commits as normal commits::->bool:false'
blame.date:'date format to use in output::__git_date_formats:iso'
@@ -3388,6 +3409,7 @@ _git-filter-branch () {
'--original[namespace where original commits will be stored]:namespace:_directories' \
'-d[temporary directory used for rewriting]: :_directories' \
'(-f --force)'{-f,--force}'[force operation]' \
+ '--state-branch[load mapping from old to new objects from specified branch]:branch:__git_branch_names' \
'*: :__git_commit_ranges'
}
@@ -3504,16 +3526,6 @@ _git-reflog () {
fi
}
-(( $+functions[_git-relink] )) ||
-_git-relink () {
- _arguments \
- '--safe[stop if two objects with the same hash exist but have different sizes]' \
- '(-)'{-h,--help}'[display usage information]' \
- ': :_directories' \
- ': :_directories' \
- '*: :_directories'
-}
-
(( $+functions[_git-remote] )) ||
_git-remote () {
local curcontext=$curcontext state line ret=1
@@ -3990,7 +4002,7 @@ _git-verify-tag () {
_arguments -S -s \
'(-v --verbose)'{-v,--verbose}'[print contents of the tag object before validating it]' \
'--raw[print raw gpg status output]' \
- '--format=[specify format to use for the output]:format' \
+ '--format=[specify format to use for the output]:format:__git_format_ref' \
'*: :__git_tags'
}
@@ -4915,7 +4927,8 @@ _git-for-each-ref () {
_arguments -S -s \
'--count=[maximum number of refs to iterate over]: :__git_guard_number "maximum number of refs"' \
'*--sort=[key to sort refs by]: :__git_ref_sort_keys' \
- '--format=-[output format of ref information]:format' \
+ '--format=-[output format of ref information]:format:__git_format_ref' \
+ '--color=-[respect any colors specified in the format]::when:(always never auto)' \
'*--points-at=[print only refs which point at the given object]:object:__git_commits' \
'*--merged=[print only refs that are merged]:object:__git_commits' \
'*--no-merged=[print only refs that are not merged]:object:__git_commits' \
@@ -5640,7 +5653,6 @@ _git_commands () {
pack-refs:'pack heads and tags for efficient repository access'
prune:'prune all unreachable objects from the object database'
reflog:'manage reflog information'
- relink:'hardlink common objects in local repositories'
remote:'manage set of tracked repositories'
repack:'pack unpacked objects in a repository'
replace:'create, list, delete refs to replace objects')
@@ -5654,6 +5666,7 @@ _git_commands () {
get-tar-commit-id:'extract commit ID from an archive created using git archive'
help:'display help information about git'
instaweb:'instantly browse your working repository in gitweb'
+ interpret-trailers:'add or parse structured information in commit messages'
merge-tree:'show three-way merge without touching index'
rerere:'reuse recorded resolution of conflicted merges'
rev-parse:'pick out and massage parameters for other git commands'
@@ -6026,17 +6039,80 @@ __git_reflog_entries () {
__git_ref_sort_keys () {
compset -P '-'
- local -a sort_keys
+ __git_ref_fields "$@"
+}
- # TODO: numparent is undocumented.
- sort_keys=(
- 'refname:the name of the ref'
+(( $+functions[__git_ref_fields] )) ||
+__git_ref_fields () {
+ # pass -a to complete all fields, otherwise only fields relevant to sorting
+ local match mbegin mend
+ local -a cfields fields append opts all
+
+ zparseopts -D -E -a opts x: X: J: V: a=all
+
+ if compset -P 1 '(#b)(*):'; then
+ case $match[1] in
+ push|upstream)
+ append=(
+ 'trackshort[show terse version: > (ahead) < (behind) = (in sync)]'
+ 'track[print gone whenever unknown upstream ref is encountered]'
+ 'track,nobracket[tracking information without brackets]'
+ )
+ ;&
+ refname|upstream|symref)
+ append+=(
+ {strip,lstrip}'[strip elements from the left]:elements to strip / -remain'
+ 'rstrip[strip elements from the right]:elements to strip / -remain'
+ 'short[strip to non-ambiguous short name]'
+ )
+ ;;
+ objectname)
+ append=(
+ 'short[strip to non-ambiguous short name]:length'
+ )
+ ;;
+ color)
+ _alternative \
+ 'colors::__git_colors' \
+ 'attributes::__git_color_attributes'
+ return
+ ;;
+ align)
+ append=(
+ 'width[specify width]:width'
+ 'position[specify alignment]:alignment:(left right middle)'
+ )
+ ;;
+ if) append=( {,not}'equals:string' ) ;;
+ contents) append=( subject body signature lines:lines ) ;;
+ tailers) append=( only unfold ) ;;
+ v|version)
+ append=(
+ 'refname[sort by versions]'
+ )
+ ;;
+ esac
+ (( $#append )) || return 1
+ _values 'interpolation modifier' $append
+ return
+ fi
+
+ cfields=(
+ 'refname:name of the ref'
+ 'objectname:object name (SHA-1)'
+ 'upstream:name of a local ref which can be considered “upstream” from the displayed ref'
+ 'push:name of a local ref which represents the @{push} location for the displayed ref'
+ 'symref:the ref which the given symbolic ref refers to'
+ 'contents:complete message'
+ 'trailers:structured information in commit messages'
+ )
+ fields=(
'objecttype:the type of the object'
'objectsize:the size of the object'
- 'objectname:the object name (SHA-1)'
+ 'HEAD:* if HEAD matches ref or space otherwise'
'tree:the tree header-field'
'parent:the parent header-field'
- 'numparent:undocumented'
+ 'numparent:number of parent objects'
'object:the object header-field'
'type:the type header-field'
'tag:the tag header-field'
@@ -6044,19 +6120,45 @@ __git_ref_sort_keys () {
'authorname:the name component of the author header-field'
'authoremail:the email component of the author header-field'
'authordate:the date component of the author header-field'
+ 'committer:the committer header-field'
'committername:the name component of the committer header-field'
'committeremail:the email component of the committer header-field'
'committerdate:the date component of the committer header-field'
+ 'tagger:the tagger header-field'
'taggername:the name component of the tagger header-field'
'taggeremail:the email component of the tagger header-field'
'taggerdate:the date component of the tagger header-field'
- 'creatorname:the name component of the creator header-field'
+ 'creator:the creator header-field'
'creatordate:the date component of the creator header-field'
'subject:the subject of the message'
'body:the body of the message'
- 'body:the contents of the message (subject and body)')
+ 'version\:refname:sort by versions'
+ )
+ if (( $#all )); then
+ cfields+=(
+ 'color:change output color'
+ 'align:set alignment'
+ 'if:conditional'
+ )
+ fields+=(
+ 'then:true branch'
+ 'else:false branch'
+ 'end:end if or align block'
+ )
+ fi
- _describe -t sort-keys 'sort key' sort_keys $*
+ _describe -t fields 'field' cfields -S : -r ':\\) \t\n\-' -- fields "$@"
+}
+
+(( $+functions[__git_format_ref] )) ||
+__git_format_ref() {
+ local expl
+ compset -P '(%\\\([^)]#\\\)|[^%]|%%|%[[:xdigit:]][[:xdigit:]])#'
+ if compset -P '%\\\((\*|)'; then
+ __git_ref_fields -S '\)' -a
+ else
+ _wanted -x formats expl format compadd -S '' '%('
+ fi
}
(( $+functions[__git_signoff_file] )) ||
@@ -6984,7 +7086,14 @@ __git_setup_diff_stage_options () {
__git_format_placeholders() {
local sep
local -a disp names placeholders expl
- if compset -P 'format:'; then
+ _describe -t formats format '( oneline:"commit-ids and subject of messages"
+ short:"few headers and only subject of messages"
+ medium:"most parts of messages"
+ full:"all parts of commit messages"
+ fuller:"like full and includes dates"
+ email:"use email headers like From and Subject"
+ raw:"the raw commits" )' -- '( format:"specify own format" )' -S ':' && return
+ compset -P 'format:'
compset -P '(%[^acgCG]|%?[^%]|[^%])#'
if compset -P '%C'; then
_wanted colors expl color compadd reset red green blue
@@ -7003,6 +7112,8 @@ __git_format_placeholders() {
gD:'reflog selector'
gd:'short reflog selector'
gn:'reflog identity'
+ ge:'reflog identity email'
+ gE:'reflog identity email (use .mailmap)'
gs:'reflog subject'
)
disp=( -l )
@@ -7026,8 +7137,8 @@ __git_format_placeholders() {
h:'abbreviated commit hash'
T:'tree hash'
t:'abbreviated tree hash'
- P:'parent hash'
- p:'abbreviated parent hash'
+ P:'parent hashes'
+ p:'abbreviated parent hashes'
a:'author details'
c:'committer details'
d:'ref name in brackets'
@@ -7058,15 +7169,6 @@ __git_format_placeholders() {
fi
_wanted placeholders expl placeholder \
compadd -p % -S '' "$disp[@]" "$@" - "$names[@]"
- else
- _describe -t formats format '( oneline:"commit-ids and subject of messages"
- short:"few headers and only subject of messages"
- medium:"most parts of messages"
- full:"all parts of commit messages"
- fuller:"like full and includes dates"
- email:"use email headers like From and Subject"
- raw:"the raw commits" )' -- '( format:"specify own format" )' -S ':'
- fi
}
(( $+functions[__git_setup_revision_options] )) ||
Messages sorted by:
Reverse Date,
Date,
Thread,
Author