summaryrefslogtreecommitdiff
path: root/Completion/Unix/Command/_git
diff options
context:
space:
mode:
authorAxel Beckert <abe@deuxchevaux.org>2015-08-22 01:55:58 +0200
committerAxel Beckert <abe@deuxchevaux.org>2015-08-22 01:55:58 +0200
commit02f6e25bfcd5feb9a093377dda0dd549cdf5c309 (patch)
tree9a25e61122b3fa0d0a1ff68b5ef05c775ff78b1e /Completion/Unix/Command/_git
parente04a19735ffc8523b93b33074f685ad4e2c92e0c (diff)
parent881474edcb223ac22a08d81a824809c33ca3a9c9 (diff)
downloadzsh-02f6e25bfcd5feb9a093377dda0dd549cdf5c309.tar.gz
zsh-02f6e25bfcd5feb9a093377dda0dd549cdf5c309.zip
Merge tag 'zsh-5.0.8-test-2' into debian
Diffstat (limited to 'Completion/Unix/Command/_git')
-rw-r--r--Completion/Unix/Command/_git312
1 files changed, 179 insertions, 133 deletions
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index b8edc109e..0d705a9da 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -132,7 +132,7 @@ _git-archive () {
declare -a backend_args
- if (( words[(I)--format=*] > 0 && words[(I)--format=*] < CURRENT )); then
+ if (( words[(b:CURRENT-1:I)--format=*] )); then
case ${words[$words[(I)--format=*]]#--format=} in
(zip)
backend_args=(
@@ -442,7 +442,7 @@ _git-checkout () {
'(-b -B -t --track --patch --detach)--orphan[create a new orphan branch based at given commit]: :__git_branch_names' \
'--ignore-skip-worktree-bits[ignores patterns and adds back any files in <paths>]' \
'(-q --quiet -f --force -m --merge --conflict --patch)'{-m,--merge}'[3way merge current branch, working tree and new branch]' \
- '(-q --quiet -f --force -m --merge --patch)--conflict[same as --merge, using given merge style]:style:(merge diff3)' \
+ '(-q --quiet -f --force -m --merge --patch)--conflict=[same as --merge, using given merge style]:style:(merge diff3)' \
'(-)'{-p,--patch}'[interactively select hunks in diff between given tree-ish and working tree]' \
'(-)--[start file arguments]' \
'*:: :->branch-or-tree-ish-or-file' && ret=0
@@ -456,14 +456,13 @@ _git-checkout () {
[[ $line[CURRENT] = -* ]] && return
if (( CURRENT == 1 )) && [[ -z $opt_args[(I)--] ]]; then
# TODO: Allow A...B
- local branch_arg='branches::__git_revisions' \
+ local branch_arg='' \
remote_branch_noprefix_arg='remote branches::__git_remote_branch_names_noprefix' \
tree_ish_arg='tree-ishs::__git_tree_ishs' \
file_arg='modified-files::__git_modified_files'
if [[ -n ${opt_args[(I)-b|-B|--orphan|--detach]} ]]; then
remote_branch_noprefix_arg=
- tree_ish_arg=
file_arg=
elif [[ -n $opt_args[(I)--track] ]]; then
branch_arg='remote-branches::__git_remote_branch_names'
@@ -471,7 +470,6 @@ _git-checkout () {
tree_ish_arg=
file_arg=
elif [[ -n ${opt_args[(I)--ours|--theirs|-m|--conflict|--patch]} ]]; then
- branch_arg=
remote_branch_noprefix_arg=
fi
@@ -924,7 +922,7 @@ _git-grep () {
# TODO: Need to implement -<num> as a shorthand for -C<num>
_arguments -C -A '-*' \
'(-O --open-files-in-pager --no-index)--cached[search blobs registered in index file instead of working tree]' \
- '(--cached)--no-index[search files in current directory, not just treacked files]' \
+ '(--cached)--no-index[search files in current directory, not just tracked files]' \
'(--exclude-standard)--no-exclude-standard[also search in ignored files]' \
'(--no-exclude-standard)--exclude-standard[exclude files standard ignore mechanisms]' \
'--untracked[search in untracked files]' \
@@ -950,7 +948,7 @@ _git-grep () {
'(-z --null)'{-z,--null}'[output \0 after filenames]' \
'(-c --count)'{-c,--count}'[show number of matching lines in files]' \
'( --no-color)--color=-[color matches]:: :__git_color_whens' \
- '(--color )---no-color[do not color matches]' \
+ '(--color )--no-color[do not color matches]' \
'--break[prefix the line number to matching lines]' \
'--heading[show the filename above the matches]' \
'(-A --after-context)'{-A,--after-context=}'[show <num> trailing lines, and separate groups of matches]: :__git_guard_number lines' \
@@ -1089,33 +1087,36 @@ _git-log () {
$revision_options \
'-L+[trace the evolution of a line range or regex within a file]:range' \
'(-)--[start file arguments]' \
- '*:: :->commit-range-or-file' && ret=0
+ '1: :->first-commit-ranges-or-files' \
+ '*: :->commit-ranges-or-files' && ret=0
case $state in
- (commit-range-or-file)
- case $CURRENT in
- (1)
- if [[ -n ${opt_args[(I)--]} ]]; then
- __git_cached_files && ret=0
- else
- _alternative \
- 'commit-ranges::__git_commit_ranges' \
- 'cached-files::__git_cached_files' && ret=0
- fi
- ;;
- (*)
- # TODO: Write a wrapper function that checks whether we have a
- # committish range or comittish and calls __git_tree_files
- # appropriately.
- if __git_is_committish_range $line[1]; then
- __git_tree_files ${PREFIX:-.} $(__git_committish_range_last $line[1]) && ret=0
- elif __git_is_committish $line[1]; then
- __git_tree_files ${PREFIX:-.} $line[1] && ret=0
- else
- __git_cached_files && ret=0
- fi
- ;;
- esac
+ (first-commit-ranges-or-files)
+ if [[ -n ${opt_args[(I)--]} ]]; then
+ __git_tree_files ${PREFIX:-.} HEAD && ret=0
+ else
+ _alternative \
+ 'commit-ranges::__git_commit_ranges' \
+ 'cached-files::__git_tree_files ${PREFIX:-.} HEAD' && ret=0
+ fi
+ ;;
+ (commit-ranges-or-files)
+ # Multiple revspecs are permitted.
+ if [[ -z ${opt_args[(I)--]} ]]; then
+ __git_commit_ranges "$@" && ret=0
+ fi
+
+ # TODO: Write a wrapper function that checks whether we have a
+ # committish range or comittish and calls __git_tree_files
+ # appropriately.
+ if __git_is_committish_range $line[1]; then
+ __git_tree_files ${PREFIX:-.} $(__git_committish_range_last $line[1]) && ret=0
+ elif __git_is_committish $line[1]; then
+ __git_tree_files ${PREFIX:-.} $line[1] && ret=0
+ else
+ __git_tree_files ${PREFIX:-.} HEAD && ret=0
+ fi
+ ;;
esac
return ret
@@ -1287,7 +1288,7 @@ _git-push () {
'(--verify)--no-verify[bybass the pre-push hook]' \
'--recurse-submodules=[submodule handling]:submodule handling:((check\:"refuse pushing of supermodule if submodule commit cannot be found on the remote"
on-demand\:"push all changed submodules"))' \
- ':: :__git_any_repositories' \
+ ': :__git_any_repositories' \
'*: :__git_ref_specs' && ret=0
case $state in
@@ -2925,7 +2926,6 @@ _git-config () {
(*)
# TODO: Do we need to set up a _requested/_next_label?
declare -a action
- local expl
_description values expl "$parts[2]"
eval "action=($parts[4])"
"$action[1]" "$expl[@]" "${(@)action[2,-1]}" && ret=0
@@ -4976,8 +4976,8 @@ __git_is_treeish () {
(( $+functions[__git_is_committish_range] )) ||
__git_is_committish_range () {
[[ $1 == *..(.|)* ]] || return 1
- local first=$(__git_committish_range_first $1)
- local last=$(__git_committish_range_last $1)
+ local first="$(__git_committish_range_first $1)"
+ local last="$(__git_committish_range_last $1)"
[[ $first != *..* && $last != *..* ]] && \
__git_is_committish $first && \
__git_is_committish $last
@@ -5025,7 +5025,16 @@ __git_ignore_line_inside_arguments () {
(( $+functions[_git_commands] )) ||
_git_commands () {
- local -a main_porcelain_commands
+ local -a cmdtypes
+ cmdtypes=( main_porcelain_commands user_commands
+ third_party_commands ancillary_manipulator_commands
+ ancillary_interrogator_commands interaction_commands
+ plumbing_manipulator_commands plumbing_interrogator_commands
+ plumbing_sync_commands plumbing_sync_helper_commands
+ plumbing_internal_helper_commands
+ )
+ local -a $cmdtypes
+
main_porcelain_commands=(
add:'add file contents to index'
am:'apply patches from a mailbox'
@@ -5064,7 +5073,6 @@ _git_commands () {
submodule:'initialize, update, or inspect submodules'
tag:'create, list, delete or verify tag object signed with GPG')
- local -a ancillary_manipulator_commands
ancillary_manipulator_commands=(
config:'get and set repository or global options'
fast-export:'data exporter'
@@ -5079,7 +5087,6 @@ _git_commands () {
repack:'pack unpacked objects in a repository'
replace:'create, list, delete refs to replace objects')
- local -a ancillary_interrogator_commands
ancillary_interrogator_commands=(
blame:'show what revision and author last modified each line of a file'
cherry:'find commits not merged upstream'
@@ -5097,7 +5104,6 @@ _git_commands () {
verify-tag:'check GPG signature of tags'
whatchanged:'show commit-logs and differences they introduce')
- local -a interaction_commands
interaction_commands=(
archimport:'import an Arch repository into git'
cvsexportcommit:'export a single commit to a CVS checkout'
@@ -5109,7 +5115,6 @@ _git_commands () {
send-email:'send collection of patches as emails'
svn:'bidirectional operation between a Subversion repository and git')
- local -a plumbing_manipulator_commands
plumbing_manipulator_commands=(
apply:'apply patch to files and/or to index'
checkout-index:'copy files from index to working directory'
@@ -5129,7 +5134,6 @@ _git_commands () {
update-ref:'update object name stored in a reference safely'
write-tree:'create tree from the current index')
- local -a plumbing_interrogator_commands
plumbing_interrogator_commands=(
cat-file:'provide content or type information for repository objects'
diff-files:'compare files in working tree and index'
@@ -5149,7 +5153,6 @@ _git_commands () {
var:'show git logical variable'
verify-pack:'validate packed git archive files')
- local -a plumbing_sync_commands
plumbing_sync_commands=(
daemon:'run a really simple server for git repositories'
fetch-pack:'receive missing objects from another repository'
@@ -5157,7 +5160,6 @@ _git_commands () {
send-pack:'push objects over git protocol to another repository'
update-server-info:'update auxiliary information file to help dumb servers')
- local -a plumbing_sync_helper_commands
plumbing_sync_helper_commands=(
http-fetch:'download from remote git repository via HTTP'
http-push:'push objects over HTTP/DAV to another repository'
@@ -5167,7 +5169,6 @@ _git_commands () {
upload-archive:'send archive back to git-archive'
upload-pack:'send objects packed back to git fetch-pack')
- local -a plumbing_internal_helper_commands
plumbing_internal_helper_commands=(
check-attr:'display gitattributes information'
check-ignore:'debug gitignore/exclude files'
@@ -5180,91 +5181,41 @@ _git_commands () {
patch-id:'compute unique ID for a patch'
stripspace:'filter out empty lines')
- local -a user_commands
zstyle -a :completion:$curcontext: user-commands user_commands
- local -a third_party_commands
local command
for command in $_git_third_party_commands; do
(( $+commands[git-${command%%:*}] )) && third_party_commands+=$command
done
- local -a aliases unique_aliases
+ local -a aliases
__git_extract_aliases
- local alias
- for alias in $aliases; do
- local name=${alias%%:*}
- (( main_porcelain_commands[(I)$name:*] ||
- user_commands[(I)$name:*] ||
- third_party_commands[(I)$name:*] ||
- ancillary_manipulator_commands[(I)$name:*] ||
- ancillary_interrogator_commands[(I)$name:*] ||
- interaction_commands[(I)$name:*] ||
- plumbing_manipulator_commands[(I)$name:*] ||
- plumbing_interrogator_commands[(I)$name:*] ||
- plumbing_sync_commands[(I)$name:*] ||
- plumbing_sync_helper_commands[(I)$name:*] ||
- plumbing_internal_helper_commands[(I)$name:*] )) || unique_aliases+=$alias
+ local cmdtype len dup sep
+ local -a allcmds allmatching alts disp expl
+
+ zstyle -s ":completion:${curcontext}:" list-separator sep || sep=--
+ for cmdtype in $cmdtypes aliases; do
+ if [[ $cmdtype = aliases ]]; then
+ for dup in ${${aliases%:*}:*allcmds}; do
+ aliases=( ${aliases:#$dup:*} )
+ done
+ fi
+ local -a ${cmdtype}_m
+ set -A ${cmdtype}_m ${(P)cmdtype%%:*}
+ allcmds+=( ${(P)${:-${cmdtype}_m}} )
done
-
- integer ret=1
-
- _tags \
- aliases \
- main-porcelain-commands \
- user-commands \
- third-party-commands \
- ancillary-manipulator-commands \
- ancillary-interrogator-commands \
- interaction-commands \
- plumbing-manipulator-commands \
- plumbing-interrogator-commands \
- plumbing-sync-commands \
- plumbing-sync-helper-commands \
- plumbing-internal-helper-commands
-
- while _tags; do
-
- _requested aliases && \
- _describe -t aliases 'alias' unique_aliases && ret=0
-
- _requested main-porcelain-commands && \
- _describe -t main-porcelain-commands 'main porcelain command' main_porcelain_commands && ret=0
-
- _requested user-commands && \
- _describe -t user-commands 'user command' user_commands && ret=0
-
- _requested third-party-commands && \
- _describe -t third-party-commands 'third-party command' third_party_commands && ret=0
-
- _requested ancillary-manipulator-commands && \
- _describe -t ancillary-manipulator-commands 'ancillary manipulator command' ancillary_manipulator_commands && ret=0
-
- _requested ancillary-interrogator-commands && \
- _describe -t ancillary-interrogator-commands 'ancillary interrogator command' ancillary_interrogator_commands && ret=0
-
- _requested interaction-commands && \
- _describe -t interaction-commands 'interaction command' interaction_commands && ret=0
-
- _requested plumbing-manipulator-commands && \
- _describe -t plumbing-manipulator-commands 'plumbing manipulator command' plumbing_manipulator_commands && ret=0
-
- _requested plumbing-interrogator-commands && \
- _describe -t plumbing-interrogator-commands 'plumbing interrogator command' plumbing_interrogator_commands && ret=0
-
- _requested plumbing-sync-commands && \
- _describe -t plumbing-sync-commands 'plumbing sync command' plumbing_sync_commands && ret=0
-
- _requested plumbing-sync-helper-commands && \
- _describe -t plumbing-sync-helper-commands 'plumbing sync helper command' plumbing_sync_helper_commands && ret=0
-
- _requested plumbing-internal-helper-commands && \
- _describe -t plumbing-internal-helper-commands 'plumbing internal helper command' plumbing_internal_helper_commands && ret=0
-
- (( ret )) || break
+ zstyle -T ":completion:${curcontext}:" verbose && disp=(-ld '${cmdtype}_d')
+ _description '' expl '' # get applicable matchers
+ compadd "$expl[@]" -O allmatching -a allcmds
+ len=${#${(O)allmatching//?/.}[1]} # length of longest match
+ for cmdtype in aliases $cmdtypes; do
+ local -a ${cmdtype}_d
+ (( $#disp )) && set -A ${cmdtype}_d \
+ ${${(Pr.COLUMNS-4.)cmdtype/(#s)(#m)[^:]##:/${(r.len.)MATCH[1,-2]} $sep }%% #}
+ alts+=( "${cmdtype//_/-}:${${cmdtype//_/ }%%(e|)s}:compadd ${(e)disp} -a ${cmdtype}_m" )
done
- return ret
+ _alternative $alts
}
(( $+functions[__git_aliases] )) ||
@@ -5789,7 +5740,11 @@ __git_tree_ishs () {
__git_objects () {
compset -P '*:'
if [[ -n $IPREFIX ]]; then
- __git_tree_files "$PREFIX" "${IPREFIX%:}"
+ if compset -P ./ ; then
+ __git_tree_files "$PREFIX" "${IPREFIX%:./}"
+ else
+ __git_tree_files --root-relative "$PREFIX" "${IPREFIX%:}"
+ fi
else
_alternative \
'revisions::__git_revisions' \
@@ -6034,12 +5989,23 @@ __git_changed_files () {
'changed-in-working-tree-files::__git_changed-in-working-tree_files'
}
+# __git_tree_files [--root-relative] FSPATH TREEISH [TREEISH...] [COMPADD OPTIONS]
+#
+# Complete [presently: a single level of] repository files under FSPATH.
+# FSPATH is interpreted as a directory path within each TREEISH.
+# FSPATH is relative to cwd, unless --root-relative is specified, in
+# which case it is relative to the repository root.
(( $+functions[__git_tree_files] )) ||
__git_tree_files () {
local multi_parts_opts
local tree Path
integer at_least_one_tree_added
local -a tree_files compadd_opts
+ local -a extra_args
+
+ if [[ $1 == --root-relative ]]; then
+ extra_args+=(--full-tree)
+ fi
zparseopts -D -E -a compadd_opts V: J: 1 2 n f X: M: P: S: r: R: q F:
@@ -6047,7 +6013,7 @@ __git_tree_files () {
shift
(( at_least_one_tree_added = 0 ))
for tree in $*; do
- tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree --name-only -z $tree $Path 2>/dev/null)"})
+ tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z $tree $Path 2>/dev/null)"})
__git_command_successful $pipestatus && (( at_least_one_tree_added = 1 ))
done
@@ -6271,6 +6237,95 @@ __git_setup_diff_stage_options () {
)
}
+(( $+functions[__git_format_placeholders] )) ||
+__git_format_placeholders() {
+ local sep
+ local -a disp names placeholders expl
+ if compset -P 'format:'; then
+ compset -P '(%[^acgCG]|%?[^%]|[^%])#'
+ if compset -P '%C'; then
+ _wanted colors expl color compadd reset red green blue
+ return
+ fi
+ if [[ -prefix %G ]]; then
+ placeholders=(
+ 'GG:raw verification message'
+ 'G?:indicate [G]ood, [B]ad, [U]ntrusted or [N]o signature'
+ 'GS:name of signer'
+ 'GK:signing key'
+ )
+ disp=( -l )
+ elif [[ -prefix %g ]]; then
+ placeholders=(
+ gD:'reflog selector'
+ gd:'short reflog selector'
+ gn:'reflog identity'
+ gs:'reflog subject'
+ )
+ disp=( -l )
+ elif [[ $PREFIX = (#b)%([ac]) ]]; then
+ placeholders=(
+ n:'name'
+ N:'name (use .mailmap)'
+ e:'email'
+ E:'email (use .mailmap)'
+ d:'date'
+ D:'date, RFC2822 style'
+ r:'date, relative'
+ t:'date, UNIX timestamp'
+ i:'date, like ISO 8601'
+ I:'date, strict ISO 8601'
+ )
+ placeholders=( $match[1]$^placeholders )
+ else
+ placeholders=(
+ H:commit\ hash
+ h:'abbreviated commit hash'
+ T:'tree hash'
+ t:'abbreviated tree hash'
+ P:'parent hash'
+ p:'abbreviated parent hash'
+ a:'author details'
+ c:'committer details'
+ d:'ref name in brackets'
+ D:'ref name'
+ e:encoding
+ s:subject
+ f:'sanitized subject'
+ g:reflog
+ b:body
+ B:'raw body'
+ N:notes
+ G:GPG\ details
+ C:color
+ m:mark
+ n:newline
+ %:raw\ %
+ x:'hex code'
+ w:'switch line wrapping'
+ )
+ fi
+ names=( ${placeholders%%:*} )
+ if zstyle -T ":completion:${curcontext}:" verbose; then
+ zstyle -s ":completion:${curcontext}:" list-separator sep || sep=--
+ zformat -a placeholders " $sep " $placeholders
+ disp+=(-d placeholders)
+ else
+ disp=()
+ 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] )) ||
__git_setup_revision_options () {
local -a diff_options
@@ -6278,16 +6333,7 @@ __git_setup_revision_options () {
revision_options=(
$diff_options
- # TODO: format pretty print format is a lot more advanced than this.
- # TODO: You can't actually specify --format without a format.
- '(-v --header)'{--pretty=-,--format=-}'[pretty print commit messages]::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"))'
+ '(-v --header)'{--pretty=-,--format=-}'[pretty print commit messages]::format:__git_format_placeholders'
'(--abbrev-commit --no-abbrev-commit)--abbrev-commit[show only partial prefixes of commit object names]'
'(--abbrev-commit --no-abbrev-commit)--no-abbrev-commit[show the full 40-byte hexadecimal commit object name]'
'(--abbrev --no-abbrev)--abbrev=[set minimum SHA1 display-length (for use with --abbrev-commit)]: :__git_guard_number length'
@@ -6329,8 +6375,8 @@ __git_setup_revision_options () {
'*--not[reverses meaning of ^ prefix for revisions that follow]'
'--all[show all commits from refs]'
'--branches=-[show all commits from refs/heads]::pattern'
- '--tags=[-show all commits from refs/tags]::pattern'
- '--remotes=[-show all commits from refs/remotes]::pattern'
+ '--tags=-[show all commits from refs/tags]::pattern'
+ '--remotes=-[show all commits from refs/remotes]::pattern'
'--glob=[show all commits from refs matching glob]:pattern'
'--exclude=[do not include refs matching glob]:pattern'
'--exclude=[do not include refs matching glob]:pattern'