Last active
August 29, 2015 14:07
-
-
Save blt04/c394ed08d4d450e994e9 to your computer and use it in GitHub Desktop.
RVM 1.25.29 breaks git tab completion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
See https://github.com/wayneeseguin/rvm/issues/3076 | |
My envioronment: | |
* OSX with homebrew | |
* ZSH 5.0.6 (installed via homebrew) | |
* git 2.1.1 (installed via homebrew) | |
* RVM 1.25.33 (installed via curl from rvm.io) | |
* fpath automatically set to: /usr/local/share/zsh/site-functions /usr/local/Cellar/zsh/5.0.6/share/zsh/functions | |
* Files: | |
* ~/.zshrc (see zshrc below) | |
* /usr/local/share/zsh/site-functions/_git (symlink to homebrew's git 2.1.1 site-functions, see git_git below) | |
* /usr/local/share/zsh/site-functions/git-completion.bash (symlink to homebrew's git 2.1.1 git-completion.bash, see git-completion.bash) | |
* /usr/local/Cellar/zsh/5.0.6/share/zsh/functions/_git (see zsh_git below) | |
* ~/.zcompdump is auto-generated, remove it before trying to reproduce | |
There may be other files contributing to this, there are over 928 default function files in /usr/local/Cellar/zsh/5.0.6/share/zsh/functions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# bash/zsh completion support for core Git. | |
# | |
# Copyright (C) 2006,2007 Shawn O. Pearce <[email protected]> | |
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/). | |
# Distributed under the GNU General Public License, version 2.0. | |
# | |
# The contained completion routines provide support for completing: | |
# | |
# *) local and remote branch names | |
# *) local and remote tag names | |
# *) .git/remotes file names | |
# *) git 'subcommands' | |
# *) tree paths within 'ref:path/to/file' expressions | |
# *) file paths within current working directory and index | |
# *) common --long-options | |
# | |
# To use these routines: | |
# | |
# 1) Copy this file to somewhere (e.g. ~/.git-completion.sh). | |
# 2) Add the following line to your .bashrc/.zshrc: | |
# source ~/.git-completion.sh | |
# 3) Consider changing your PS1 to also show the current branch, | |
# see git-prompt.sh for details. | |
# | |
# If you use complex aliases of form '!f() { ... }; f', you can use the null | |
# command ':' as the first command in the function body to declare the desired | |
# completion style. For example '!f() { : git commit ; ... }; f' will | |
# tell the completion to use commit completion. This also works with aliases | |
# of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '". | |
case "$COMP_WORDBREAKS" in | |
*:*) : great ;; | |
*) COMP_WORDBREAKS="$COMP_WORDBREAKS:" | |
esac | |
# __gitdir accepts 0 or 1 arguments (i.e., location) | |
# returns location of .git repo | |
__gitdir () | |
{ | |
if [ -z "${1-}" ]; then | |
if [ -n "${__git_dir-}" ]; then | |
echo "$__git_dir" | |
elif [ -n "${GIT_DIR-}" ]; then | |
test -d "${GIT_DIR-}" || return 1 | |
echo "$GIT_DIR" | |
elif [ -d .git ]; then | |
echo .git | |
else | |
git rev-parse --git-dir 2>/dev/null | |
fi | |
elif [ -d "$1/.git" ]; then | |
echo "$1/.git" | |
else | |
echo "$1" | |
fi | |
} | |
# The following function is based on code from: | |
# | |
# bash_completion - programmable completion functions for bash 3.2+ | |
# | |
# Copyright © 2006-2008, Ian Macdonald <[email protected]> | |
# © 2009-2010, Bash Completion Maintainers | |
# <[email protected]> | |
# | |
# This program is free software; you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation; either version 2, or (at your option) | |
# any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software Foundation, | |
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
# | |
# The latest version of this software can be obtained here: | |
# | |
# http://bash-completion.alioth.debian.org/ | |
# | |
# RELEASE: 2.x | |
# This function can be used to access a tokenized list of words | |
# on the command line: | |
# | |
# __git_reassemble_comp_words_by_ref '=:' | |
# if test "${words_[cword_-1]}" = -w | |
# then | |
# ... | |
# fi | |
# | |
# The argument should be a collection of characters from the list of | |
# word completion separators (COMP_WORDBREAKS) to treat as ordinary | |
# characters. | |
# | |
# This is roughly equivalent to going back in time and setting | |
# COMP_WORDBREAKS to exclude those characters. The intent is to | |
# make option types like --date=<type> and <rev>:<path> easy to | |
# recognize by treating each shell word as a single token. | |
# | |
# It is best not to set COMP_WORDBREAKS directly because the value is | |
# shared with other completion scripts. By the time the completion | |
# function gets called, COMP_WORDS has already been populated so local | |
# changes to COMP_WORDBREAKS have no effect. | |
# | |
# Output: words_, cword_, cur_. | |
__git_reassemble_comp_words_by_ref() | |
{ | |
local exclude i j first | |
# Which word separators to exclude? | |
exclude="${1//[^$COMP_WORDBREAKS]}" | |
cword_=$COMP_CWORD | |
if [ -z "$exclude" ]; then | |
words_=("${COMP_WORDS[@]}") | |
return | |
fi | |
# List of word completion separators has shrunk; | |
# re-assemble words to complete. | |
for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do | |
# Append each nonempty word consisting of just | |
# word separator characters to the current word. | |
first=t | |
while | |
[ $i -gt 0 ] && | |
[ -n "${COMP_WORDS[$i]}" ] && | |
# word consists of excluded word separators | |
[ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] | |
do | |
# Attach to the previous token, | |
# unless the previous token is the command name. | |
if [ $j -ge 2 ] && [ -n "$first" ]; then | |
((j--)) | |
fi | |
first= | |
words_[$j]=${words_[j]}${COMP_WORDS[i]} | |
if [ $i = $COMP_CWORD ]; then | |
cword_=$j | |
fi | |
if (($i < ${#COMP_WORDS[@]} - 1)); then | |
((i++)) | |
else | |
# Done. | |
return | |
fi | |
done | |
words_[$j]=${words_[j]}${COMP_WORDS[i]} | |
if [ $i = $COMP_CWORD ]; then | |
cword_=$j | |
fi | |
done | |
} | |
if ! type _get_comp_words_by_ref >/dev/null 2>&1; then | |
_get_comp_words_by_ref () | |
{ | |
local exclude cur_ words_ cword_ | |
if [ "$1" = "-n" ]; then | |
exclude=$2 | |
shift 2 | |
fi | |
__git_reassemble_comp_words_by_ref "$exclude" | |
cur_=${words_[cword_]} | |
while [ $# -gt 0 ]; do | |
case "$1" in | |
cur) | |
cur=$cur_ | |
;; | |
prev) | |
prev=${words_[$cword_-1]} | |
;; | |
words) | |
words=("${words_[@]}") | |
;; | |
cword) | |
cword=$cword_ | |
;; | |
esac | |
shift | |
done | |
} | |
fi | |
__gitcompappend () | |
{ | |
local i=${#COMPREPLY[@]} | |
for x in $1; do | |
if [[ "$x" == "$3"* ]]; then | |
COMPREPLY[i++]="$2$x$4" | |
fi | |
done | |
} | |
__gitcompadd () | |
{ | |
COMPREPLY=() | |
__gitcompappend "$@" | |
} | |
# Generates completion reply, appending a space to possible completion words, | |
# if necessary. | |
# It accepts 1 to 4 arguments: | |
# 1: List of possible completion words. | |
# 2: A prefix to be added to each possible completion word (optional). | |
# 3: Generate possible completion matches for this word (optional). | |
# 4: A suffix to be appended to each possible completion word (optional). | |
__gitcomp () | |
{ | |
local cur_="${3-$cur}" | |
case "$cur_" in | |
--*=) | |
;; | |
*) | |
local c i=0 IFS=$' \t\n' | |
for c in $1; do | |
c="$c${4-}" | |
if [[ $c == "$cur_"* ]]; then | |
case $c in | |
--*=*|*.) ;; | |
*) c="$c " ;; | |
esac | |
COMPREPLY[i++]="${2-}$c" | |
fi | |
done | |
;; | |
esac | |
} | |
# Variation of __gitcomp_nl () that appends to the existing list of | |
# completion candidates, COMPREPLY. | |
__gitcomp_nl_append () | |
{ | |
local IFS=$'\n' | |
__gitcompappend "$1" "${2-}" "${3-$cur}" "${4- }" | |
} | |
# Generates completion reply from newline-separated possible completion words | |
# by appending a space to all of them. | |
# It accepts 1 to 4 arguments: | |
# 1: List of possible completion words, separated by a single newline. | |
# 2: A prefix to be added to each possible completion word (optional). | |
# 3: Generate possible completion matches for this word (optional). | |
# 4: A suffix to be appended to each possible completion word instead of | |
# the default space (optional). If specified but empty, nothing is | |
# appended. | |
__gitcomp_nl () | |
{ | |
COMPREPLY=() | |
__gitcomp_nl_append "$@" | |
} | |
# Generates completion reply with compgen from newline-separated possible | |
# completion filenames. | |
# It accepts 1 to 3 arguments: | |
# 1: List of possible completion filenames, separated by a single newline. | |
# 2: A directory prefix to be added to each possible completion filename | |
# (optional). | |
# 3: Generate possible completion matches for this word (optional). | |
__gitcomp_file () | |
{ | |
local IFS=$'\n' | |
# XXX does not work when the directory prefix contains a tilde, | |
# since tilde expansion is not applied. | |
# This means that COMPREPLY will be empty and Bash default | |
# completion will be used. | |
__gitcompadd "$1" "${2-}" "${3-$cur}" "" | |
# use a hack to enable file mode in bash < 4 | |
compopt -o filenames +o nospace 2>/dev/null || | |
compgen -f /non-existing-dir/ > /dev/null | |
} | |
# Execute 'git ls-files', unless the --committable option is specified, in | |
# which case it runs 'git diff-index' to find out the files that can be | |
# committed. It return paths relative to the directory specified in the first | |
# argument, and using the options specified in the second argument. | |
__git_ls_files_helper () | |
{ | |
( | |
test -n "${CDPATH+set}" && unset CDPATH | |
cd "$1" | |
if [ "$2" == "--committable" ]; then | |
git diff-index --name-only --relative HEAD | |
else | |
# NOTE: $2 is not quoted in order to support multiple options | |
git ls-files --exclude-standard $2 | |
fi | |
) 2>/dev/null | |
} | |
# __git_index_files accepts 1 or 2 arguments: | |
# 1: Options to pass to ls-files (required). | |
# 2: A directory path (optional). | |
# If provided, only files within the specified directory are listed. | |
# Sub directories are never recursed. Path must have a trailing | |
# slash. | |
__git_index_files () | |
{ | |
local dir="$(__gitdir)" root="${2-.}" file | |
if [ -d "$dir" ]; then | |
__git_ls_files_helper "$root" "$1" | | |
while read -r file; do | |
case "$file" in | |
?*/*) echo "${file%%/*}" ;; | |
*) echo "$file" ;; | |
esac | |
done | sort | uniq | |
fi | |
} | |
__git_heads () | |
{ | |
local dir="$(__gitdir)" | |
if [ -d "$dir" ]; then | |
git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ | |
refs/heads | |
return | |
fi | |
} | |
__git_tags () | |
{ | |
local dir="$(__gitdir)" | |
if [ -d "$dir" ]; then | |
git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ | |
refs/tags | |
return | |
fi | |
} | |
# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments | |
# presence of 2nd argument means use the guess heuristic employed | |
# by checkout for tracking branches | |
__git_refs () | |
{ | |
local i hash dir="$(__gitdir "${1-}")" track="${2-}" | |
local format refs | |
if [ -d "$dir" ]; then | |
case "$cur" in | |
refs|refs/*) | |
format="refname" | |
refs="${cur%/*}" | |
track="" | |
;; | |
*) | |
for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do | |
if [ -e "$dir/$i" ]; then echo $i; fi | |
done | |
format="refname:short" | |
refs="refs/tags refs/heads refs/remotes" | |
;; | |
esac | |
git --git-dir="$dir" for-each-ref --format="%($format)" \ | |
$refs | |
if [ -n "$track" ]; then | |
# employ the heuristic used by git checkout | |
# Try to find a remote branch that matches the completion word | |
# but only output if the branch name is unique | |
local ref entry | |
git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \ | |
"refs/remotes/" | \ | |
while read -r entry; do | |
eval "$entry" | |
ref="${ref#*/}" | |
if [[ "$ref" == "$cur"* ]]; then | |
echo "$ref" | |
fi | |
done | sort | uniq -u | |
fi | |
return | |
fi | |
case "$cur" in | |
refs|refs/*) | |
git ls-remote "$dir" "$cur*" 2>/dev/null | \ | |
while read -r hash i; do | |
case "$i" in | |
*^{}) ;; | |
*) echo "$i" ;; | |
esac | |
done | |
;; | |
*) | |
echo "HEAD" | |
git for-each-ref --format="%(refname:short)" -- "refs/remotes/$dir/" | sed -e "s#^$dir/##" | |
;; | |
esac | |
} | |
# __git_refs2 requires 1 argument (to pass to __git_refs) | |
__git_refs2 () | |
{ | |
local i | |
for i in $(__git_refs "$1"); do | |
echo "$i:$i" | |
done | |
} | |
# __git_refs_remotes requires 1 argument (to pass to ls-remote) | |
__git_refs_remotes () | |
{ | |
local i hash | |
git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \ | |
while read -r hash i; do | |
echo "$i:refs/remotes/$1/${i#refs/heads/}" | |
done | |
} | |
__git_remotes () | |
{ | |
local i IFS=$'\n' d="$(__gitdir)" | |
test -d "$d/remotes" && ls -1 "$d/remotes" | |
for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do | |
i="${i#remote.}" | |
echo "${i/.url*/}" | |
done | |
} | |
__git_list_merge_strategies () | |
{ | |
git merge -s help 2>&1 | | |
sed -n -e '/[Aa]vailable strategies are: /,/^$/{ | |
s/\.$// | |
s/.*:// | |
s/^[ ]*// | |
s/[ ]*$// | |
p | |
}' | |
} | |
__git_merge_strategies= | |
# 'git merge -s help' (and thus detection of the merge strategy | |
# list) fails, unfortunately, if run outside of any git working | |
# tree. __git_merge_strategies is set to the empty string in | |
# that case, and the detection will be repeated the next time it | |
# is needed. | |
__git_compute_merge_strategies () | |
{ | |
test -n "$__git_merge_strategies" || | |
__git_merge_strategies=$(__git_list_merge_strategies) | |
} | |
__git_complete_revlist_file () | |
{ | |
local pfx ls ref cur_="$cur" | |
case "$cur_" in | |
*..?*:*) | |
return | |
;; | |
?*:*) | |
ref="${cur_%%:*}" | |
cur_="${cur_#*:}" | |
case "$cur_" in | |
?*/*) | |
pfx="${cur_%/*}" | |
cur_="${cur_##*/}" | |
ls="$ref:$pfx" | |
pfx="$pfx/" | |
;; | |
*) | |
ls="$ref" | |
;; | |
esac | |
case "$COMP_WORDBREAKS" in | |
*:*) : great ;; | |
*) pfx="$ref:$pfx" ;; | |
esac | |
__gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \ | |
| sed '/^100... blob /{ | |
s,^.* ,, | |
s,$, , | |
} | |
/^120000 blob /{ | |
s,^.* ,, | |
s,$, , | |
} | |
/^040000 tree /{ | |
s,^.* ,, | |
s,$,/, | |
} | |
s/^.* //')" \ | |
"$pfx" "$cur_" "" | |
;; | |
*...*) | |
pfx="${cur_%...*}..." | |
cur_="${cur_#*...}" | |
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" | |
;; | |
*..*) | |
pfx="${cur_%..*}.." | |
cur_="${cur_#*..}" | |
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" | |
;; | |
*) | |
__gitcomp_nl "$(__git_refs)" | |
;; | |
esac | |
} | |
# __git_complete_index_file requires 1 argument: | |
# 1: the options to pass to ls-file | |
# | |
# The exception is --committable, which finds the files appropriate commit. | |
__git_complete_index_file () | |
{ | |
local pfx="" cur_="$cur" | |
case "$cur_" in | |
?*/*) | |
pfx="${cur_%/*}" | |
cur_="${cur_##*/}" | |
pfx="${pfx}/" | |
;; | |
esac | |
__gitcomp_file "$(__git_index_files "$1" "$pfx")" "$pfx" "$cur_" | |
} | |
__git_complete_file () | |
{ | |
__git_complete_revlist_file | |
} | |
__git_complete_revlist () | |
{ | |
__git_complete_revlist_file | |
} | |
__git_complete_remote_or_refspec () | |
{ | |
local cur_="$cur" cmd="${words[1]}" | |
local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0 | |
if [ "$cmd" = "remote" ]; then | |
((c++)) | |
fi | |
while [ $c -lt $cword ]; do | |
i="${words[c]}" | |
case "$i" in | |
--mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;; | |
--all) | |
case "$cmd" in | |
push) no_complete_refspec=1 ;; | |
fetch) | |
return | |
;; | |
*) ;; | |
esac | |
;; | |
-*) ;; | |
*) remote="$i"; break ;; | |
esac | |
((c++)) | |
done | |
if [ -z "$remote" ]; then | |
__gitcomp_nl "$(__git_remotes)" | |
return | |
fi | |
if [ $no_complete_refspec = 1 ]; then | |
return | |
fi | |
[ "$remote" = "." ] && remote= | |
case "$cur_" in | |
*:*) | |
case "$COMP_WORDBREAKS" in | |
*:*) : great ;; | |
*) pfx="${cur_%%:*}:" ;; | |
esac | |
cur_="${cur_#*:}" | |
lhs=0 | |
;; | |
+*) | |
pfx="+" | |
cur_="${cur_#+}" | |
;; | |
esac | |
case "$cmd" in | |
fetch) | |
if [ $lhs = 1 ]; then | |
__gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_" | |
else | |
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" | |
fi | |
;; | |
pull|remote) | |
if [ $lhs = 1 ]; then | |
__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_" | |
else | |
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" | |
fi | |
;; | |
push) | |
if [ $lhs = 1 ]; then | |
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_" | |
else | |
__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_" | |
fi | |
;; | |
esac | |
} | |
__git_complete_strategy () | |
{ | |
__git_compute_merge_strategies | |
case "$prev" in | |
-s|--strategy) | |
__gitcomp "$__git_merge_strategies" | |
return 0 | |
esac | |
case "$cur" in | |
--strategy=*) | |
__gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}" | |
return 0 | |
;; | |
esac | |
return 1 | |
} | |
__git_commands () { | |
if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}" | |
then | |
printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" | |
else | |
git help -a|egrep '^ [a-zA-Z0-9]' | |
fi | |
} | |
__git_list_all_commands () | |
{ | |
local i IFS=" "$'\n' | |
for i in $(__git_commands) | |
do | |
case $i in | |
*--*) : helper pattern;; | |
*) echo $i;; | |
esac | |
done | |
} | |
__git_all_commands= | |
__git_compute_all_commands () | |
{ | |
test -n "$__git_all_commands" || | |
__git_all_commands=$(__git_list_all_commands) | |
} | |
__git_list_porcelain_commands () | |
{ | |
local i IFS=" "$'\n' | |
__git_compute_all_commands | |
for i in $__git_all_commands | |
do | |
case $i in | |
*--*) : helper pattern;; | |
applymbox) : ask gittus;; | |
applypatch) : ask gittus;; | |
archimport) : import;; | |
cat-file) : plumbing;; | |
check-attr) : plumbing;; | |
check-ignore) : plumbing;; | |
check-mailmap) : plumbing;; | |
check-ref-format) : plumbing;; | |
checkout-index) : plumbing;; | |
commit-tree) : plumbing;; | |
count-objects) : infrequent;; | |
credential-cache) : credentials helper;; | |
credential-store) : credentials helper;; | |
cvsexportcommit) : export;; | |
cvsimport) : import;; | |
cvsserver) : daemon;; | |
daemon) : daemon;; | |
diff-files) : plumbing;; | |
diff-index) : plumbing;; | |
diff-tree) : plumbing;; | |
fast-import) : import;; | |
fast-export) : export;; | |
fsck-objects) : plumbing;; | |
fetch-pack) : plumbing;; | |
fmt-merge-msg) : plumbing;; | |
for-each-ref) : plumbing;; | |
hash-object) : plumbing;; | |
http-*) : transport;; | |
index-pack) : plumbing;; | |
init-db) : deprecated;; | |
local-fetch) : plumbing;; | |
ls-files) : plumbing;; | |
ls-remote) : plumbing;; | |
ls-tree) : plumbing;; | |
mailinfo) : plumbing;; | |
mailsplit) : plumbing;; | |
merge-*) : plumbing;; | |
mktree) : plumbing;; | |
mktag) : plumbing;; | |
pack-objects) : plumbing;; | |
pack-redundant) : plumbing;; | |
pack-refs) : plumbing;; | |
parse-remote) : plumbing;; | |
patch-id) : plumbing;; | |
prune) : plumbing;; | |
prune-packed) : plumbing;; | |
quiltimport) : import;; | |
read-tree) : plumbing;; | |
receive-pack) : plumbing;; | |
remote-*) : transport;; | |
rerere) : plumbing;; | |
rev-list) : plumbing;; | |
rev-parse) : plumbing;; | |
runstatus) : plumbing;; | |
sh-setup) : internal;; | |
shell) : daemon;; | |
show-ref) : plumbing;; | |
send-pack) : plumbing;; | |
show-index) : plumbing;; | |
ssh-*) : transport;; | |
stripspace) : plumbing;; | |
symbolic-ref) : plumbing;; | |
unpack-file) : plumbing;; | |
unpack-objects) : plumbing;; | |
update-index) : plumbing;; | |
update-ref) : plumbing;; | |
update-server-info) : daemon;; | |
upload-archive) : plumbing;; | |
upload-pack) : plumbing;; | |
write-tree) : plumbing;; | |
var) : infrequent;; | |
verify-pack) : infrequent;; | |
verify-tag) : plumbing;; | |
*) echo $i;; | |
esac | |
done | |
} | |
__git_porcelain_commands= | |
__git_compute_porcelain_commands () | |
{ | |
__git_compute_all_commands | |
test -n "$__git_porcelain_commands" || | |
__git_porcelain_commands=$(__git_list_porcelain_commands) | |
} | |
__git_pretty_aliases () | |
{ | |
local i IFS=$'\n' | |
for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do | |
case "$i" in | |
pretty.*) | |
i="${i#pretty.}" | |
echo "${i/ */}" | |
;; | |
esac | |
done | |
} | |
__git_aliases () | |
{ | |
local i IFS=$'\n' | |
for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do | |
case "$i" in | |
alias.*) | |
i="${i#alias.}" | |
echo "${i/ */}" | |
;; | |
esac | |
done | |
} | |
# __git_aliased_command requires 1 argument | |
__git_aliased_command () | |
{ | |
local word cmdline=$(git --git-dir="$(__gitdir)" \ | |
config --get "alias.$1") | |
for word in $cmdline; do | |
case "$word" in | |
\!gitk|gitk) | |
echo "gitk" | |
return | |
;; | |
\!*) : shell command alias ;; | |
-*) : option ;; | |
*=*) : setting env ;; | |
git) : git itself ;; | |
\(\)) : skip parens of shell function definition ;; | |
{) : skip start of shell helper function ;; | |
:) : skip null command ;; | |
\'*) : skip opening quote after sh -c ;; | |
*) | |
echo "$word" | |
return | |
esac | |
done | |
} | |
# __git_find_on_cmdline requires 1 argument | |
__git_find_on_cmdline () | |
{ | |
local word subcommand c=1 | |
while [ $c -lt $cword ]; do | |
word="${words[c]}" | |
for subcommand in $1; do | |
if [ "$subcommand" = "$word" ]; then | |
echo "$subcommand" | |
return | |
fi | |
done | |
((c++)) | |
done | |
} | |
__git_has_doubledash () | |
{ | |
local c=1 | |
while [ $c -lt $cword ]; do | |
if [ "--" = "${words[c]}" ]; then | |
return 0 | |
fi | |
((c++)) | |
done | |
return 1 | |
} | |
# Try to count non option arguments passed on the command line for the | |
# specified git command. | |
# When options are used, it is necessary to use the special -- option to | |
# tell the implementation were non option arguments begin. | |
# XXX this can not be improved, since options can appear everywhere, as | |
# an example: | |
# git mv x -n y | |
# | |
# __git_count_arguments requires 1 argument: the git command executed. | |
__git_count_arguments () | |
{ | |
local word i c=0 | |
# Skip "git" (first argument) | |
for ((i=1; i < ${#words[@]}; i++)); do | |
word="${words[i]}" | |
case "$word" in | |
--) | |
# Good; we can assume that the following are only non | |
# option arguments. | |
((c = 0)) | |
;; | |
"$1") | |
# Skip the specified git command and discard git | |
# main options | |
((c = 0)) | |
;; | |
?*) | |
((c++)) | |
;; | |
esac | |
done | |
printf "%d" $c | |
} | |
__git_whitespacelist="nowarn warn error error-all fix" | |
_git_am () | |
{ | |
local dir="$(__gitdir)" | |
if [ -d "$dir"/rebase-apply ]; then | |
__gitcomp "--skip --continue --resolved --abort" | |
return | |
fi | |
case "$cur" in | |
--whitespace=*) | |
__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--3way --committer-date-is-author-date --ignore-date | |
--ignore-whitespace --ignore-space-change | |
--interactive --keep --no-utf8 --signoff --utf8 | |
--whitespace= --scissors | |
" | |
return | |
esac | |
} | |
_git_apply () | |
{ | |
case "$cur" in | |
--whitespace=*) | |
__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--stat --numstat --summary --check --index | |
--cached --index-info --reverse --reject --unidiff-zero | |
--apply --no-add --exclude= | |
--ignore-whitespace --ignore-space-change | |
--whitespace= --inaccurate-eof --verbose | |
" | |
return | |
esac | |
} | |
_git_add () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--interactive --refresh --patch --update --dry-run | |
--ignore-errors --intent-to-add | |
" | |
return | |
esac | |
# XXX should we check for --update and --all options ? | |
__git_complete_index_file "--others --modified --directory --no-empty-directory" | |
} | |
_git_archive () | |
{ | |
case "$cur" in | |
--format=*) | |
__gitcomp "$(git archive --list)" "" "${cur##--format=}" | |
return | |
;; | |
--remote=*) | |
__gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--format= --list --verbose | |
--prefix= --remote= --exec= | |
" | |
return | |
;; | |
esac | |
__git_complete_file | |
} | |
_git_bisect () | |
{ | |
__git_has_doubledash && return | |
local subcommands="start bad good skip reset visualize replay log run" | |
local subcommand="$(__git_find_on_cmdline "$subcommands")" | |
if [ -z "$subcommand" ]; then | |
if [ -f "$(__gitdir)"/BISECT_START ]; then | |
__gitcomp "$subcommands" | |
else | |
__gitcomp "replay start" | |
fi | |
return | |
fi | |
case "$subcommand" in | |
bad|good|reset|skip|start) | |
__gitcomp_nl "$(__git_refs)" | |
;; | |
*) | |
;; | |
esac | |
} | |
_git_branch () | |
{ | |
local i c=1 only_local_ref="n" has_r="n" | |
while [ $c -lt $cword ]; do | |
i="${words[c]}" | |
case "$i" in | |
-d|-m) only_local_ref="y" ;; | |
-r) has_r="y" ;; | |
esac | |
((c++)) | |
done | |
case "$cur" in | |
--set-upstream-to=*) | |
__gitcomp "$(__git_refs)" "" "${cur##--set-upstream-to=}" | |
;; | |
--*) | |
__gitcomp " | |
--color --no-color --verbose --abbrev= --no-abbrev | |
--track --no-track --contains --merged --no-merged | |
--set-upstream-to= --edit-description --list | |
--unset-upstream | |
" | |
;; | |
*) | |
if [ $only_local_ref = "y" -a $has_r = "n" ]; then | |
__gitcomp_nl "$(__git_heads)" | |
else | |
__gitcomp_nl "$(__git_refs)" | |
fi | |
;; | |
esac | |
} | |
_git_bundle () | |
{ | |
local cmd="${words[2]}" | |
case "$cword" in | |
2) | |
__gitcomp "create list-heads verify unbundle" | |
;; | |
3) | |
# looking for a file | |
;; | |
*) | |
case "$cmd" in | |
create) | |
__git_complete_revlist | |
;; | |
esac | |
;; | |
esac | |
} | |
_git_checkout () | |
{ | |
__git_has_doubledash && return | |
case "$cur" in | |
--conflict=*) | |
__gitcomp "diff3 merge" "" "${cur##--conflict=}" | |
;; | |
--*) | |
__gitcomp " | |
--quiet --ours --theirs --track --no-track --merge | |
--conflict= --orphan --patch | |
" | |
;; | |
*) | |
# check if --track, --no-track, or --no-guess was specified | |
# if so, disable DWIM mode | |
local flags="--track --no-track --no-guess" track=1 | |
if [ -n "$(__git_find_on_cmdline "$flags")" ]; then | |
track='' | |
fi | |
__gitcomp_nl "$(__git_refs '' $track)" | |
;; | |
esac | |
} | |
_git_cherry () | |
{ | |
__gitcomp "$(__git_refs)" | |
} | |
_git_cherry_pick () | |
{ | |
local dir="$(__gitdir)" | |
if [ -f "$dir"/CHERRY_PICK_HEAD ]; then | |
__gitcomp "--continue --quit --abort" | |
return | |
fi | |
case "$cur" in | |
--*) | |
__gitcomp "--edit --no-commit --signoff --strategy= --mainline" | |
;; | |
*) | |
__gitcomp_nl "$(__git_refs)" | |
;; | |
esac | |
} | |
_git_clean () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp "--dry-run --quiet" | |
return | |
;; | |
esac | |
# XXX should we check for -x option ? | |
__git_complete_index_file "--others --directory" | |
} | |
_git_clone () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--local | |
--no-hardlinks | |
--shared | |
--reference | |
--quiet | |
--no-checkout | |
--bare | |
--mirror | |
--origin | |
--upload-pack | |
--template= | |
--depth | |
--single-branch | |
--branch | |
" | |
return | |
;; | |
esac | |
} | |
_git_commit () | |
{ | |
case "$prev" in | |
-c|-C) | |
__gitcomp_nl "$(__git_refs)" "" "${cur}" | |
return | |
;; | |
esac | |
case "$cur" in | |
--cleanup=*) | |
__gitcomp "default strip verbatim whitespace | |
" "" "${cur##--cleanup=}" | |
return | |
;; | |
--reuse-message=*|--reedit-message=*|\ | |
--fixup=*|--squash=*) | |
__gitcomp_nl "$(__git_refs)" "" "${cur#*=}" | |
return | |
;; | |
--untracked-files=*) | |
__gitcomp "all no normal" "" "${cur##--untracked-files=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--all --author= --signoff --verify --no-verify | |
--edit --no-edit | |
--amend --include --only --interactive | |
--dry-run --reuse-message= --reedit-message= | |
--reset-author --file= --message= --template= | |
--cleanup= --untracked-files --untracked-files= | |
--verbose --quiet --fixup= --squash= | |
" | |
return | |
esac | |
if git rev-parse --verify --quiet HEAD >/dev/null; then | |
__git_complete_index_file "--committable" | |
else | |
# This is the first commit | |
__git_complete_index_file "--cached" | |
fi | |
} | |
_git_describe () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--all --tags --contains --abbrev= --candidates= | |
--exact-match --debug --long --match --always | |
" | |
return | |
esac | |
__gitcomp_nl "$(__git_refs)" | |
} | |
__git_diff_algorithms="myers minimal patience histogram" | |
__git_diff_common_options="--stat --numstat --shortstat --summary | |
--patch-with-stat --name-only --name-status --color | |
--no-color --color-words --no-renames --check | |
--full-index --binary --abbrev --diff-filter= | |
--find-copies-harder | |
--text --ignore-space-at-eol --ignore-space-change | |
--ignore-all-space --exit-code --quiet --ext-diff | |
--no-ext-diff | |
--no-prefix --src-prefix= --dst-prefix= | |
--inter-hunk-context= | |
--patience --histogram --minimal | |
--raw --word-diff | |
--dirstat --dirstat= --dirstat-by-file | |
--dirstat-by-file= --cumulative | |
--diff-algorithm= | |
" | |
_git_diff () | |
{ | |
__git_has_doubledash && return | |
case "$cur" in | |
--diff-algorithm=*) | |
__gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}" | |
return | |
;; | |
--*) | |
__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex | |
--base --ours --theirs --no-index | |
$__git_diff_common_options | |
" | |
return | |
;; | |
esac | |
__git_complete_revlist_file | |
} | |
__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff | |
tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3 codecompare | |
" | |
_git_difftool () | |
{ | |
__git_has_doubledash && return | |
case "$cur" in | |
--tool=*) | |
__gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}" | |
return | |
;; | |
--*) | |
__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex | |
--base --ours --theirs | |
--no-renames --diff-filter= --find-copies-harder | |
--relative --ignore-submodules | |
--tool=" | |
return | |
;; | |
esac | |
__git_complete_revlist_file | |
} | |
__git_fetch_recurse_submodules="yes on-demand no" | |
__git_fetch_options=" | |
--quiet --verbose --append --upload-pack --force --keep --depth= | |
--tags --no-tags --all --prune --dry-run --recurse-submodules= | |
" | |
_git_fetch () | |
{ | |
case "$cur" in | |
--recurse-submodules=*) | |
__gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}" | |
return | |
;; | |
--*) | |
__gitcomp "$__git_fetch_options" | |
return | |
;; | |
esac | |
__git_complete_remote_or_refspec | |
} | |
__git_format_patch_options=" | |
--stdout --attach --no-attach --thread --thread= --no-thread | |
--numbered --start-number --numbered-files --keep-subject --signoff | |
--signature --no-signature --in-reply-to= --cc= --full-index --binary | |
--not --all --cover-letter --no-prefix --src-prefix= --dst-prefix= | |
--inline --suffix= --ignore-if-in-upstream --subject-prefix= | |
--output-directory --reroll-count --to= --quiet --notes | |
" | |
_git_format_patch () | |
{ | |
case "$cur" in | |
--thread=*) | |
__gitcomp " | |
deep shallow | |
" "" "${cur##--thread=}" | |
return | |
;; | |
--*) | |
__gitcomp "$__git_format_patch_options" | |
return | |
;; | |
esac | |
__git_complete_revlist | |
} | |
_git_fsck () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--tags --root --unreachable --cache --no-reflogs --full | |
--strict --verbose --lost-found | |
" | |
return | |
;; | |
esac | |
} | |
_git_gc () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp "--prune --aggressive" | |
return | |
;; | |
esac | |
} | |
_git_gitk () | |
{ | |
_gitk | |
} | |
__git_match_ctag() { | |
awk "/^${1////\\/}/ { print \$1 }" "$2" | |
} | |
_git_grep () | |
{ | |
__git_has_doubledash && return | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--cached | |
--text --ignore-case --word-regexp --invert-match | |
--full-name --line-number | |
--extended-regexp --basic-regexp --fixed-strings | |
--perl-regexp | |
--files-with-matches --name-only | |
--files-without-match | |
--max-depth | |
--count | |
--and --or --not --all-match | |
" | |
return | |
;; | |
esac | |
case "$cword,$prev" in | |
2,*|*,-*) | |
if test -r tags; then | |
__gitcomp_nl "$(__git_match_ctag "$cur" tags)" | |
return | |
fi | |
;; | |
esac | |
__gitcomp_nl "$(__git_refs)" | |
} | |
_git_help () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp "--all --info --man --web" | |
return | |
;; | |
esac | |
__git_compute_all_commands | |
__gitcomp "$__git_all_commands $(__git_aliases) | |
attributes cli core-tutorial cvs-migration | |
diffcore gitk glossary hooks ignore modules | |
namespaces repository-layout tutorial tutorial-2 | |
workflows | |
" | |
} | |
_git_init () | |
{ | |
case "$cur" in | |
--shared=*) | |
__gitcomp " | |
false true umask group all world everybody | |
" "" "${cur##--shared=}" | |
return | |
;; | |
--*) | |
__gitcomp "--quiet --bare --template= --shared --shared=" | |
return | |
;; | |
esac | |
} | |
_git_ls_files () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp "--cached --deleted --modified --others --ignored | |
--stage --directory --no-empty-directory --unmerged | |
--killed --exclude= --exclude-from= | |
--exclude-per-directory= --exclude-standard | |
--error-unmatch --with-tree= --full-name | |
--abbrev --ignored --exclude-per-directory | |
" | |
return | |
;; | |
esac | |
# XXX ignore options like --modified and always suggest all cached | |
# files. | |
__git_complete_index_file "--cached" | |
} | |
_git_ls_remote () | |
{ | |
__gitcomp_nl "$(__git_remotes)" | |
} | |
_git_ls_tree () | |
{ | |
__git_complete_file | |
} | |
# Options that go well for log, shortlog and gitk | |
__git_log_common_options=" | |
--not --all | |
--branches --tags --remotes | |
--first-parent --merges --no-merges | |
--max-count= | |
--max-age= --since= --after= | |
--min-age= --until= --before= | |
--min-parents= --max-parents= | |
--no-min-parents --no-max-parents | |
" | |
# Options that go well for log and gitk (not shortlog) | |
__git_log_gitk_options=" | |
--dense --sparse --full-history | |
--simplify-merges --simplify-by-decoration | |
--left-right --notes --no-notes | |
" | |
# Options that go well for log and shortlog (not gitk) | |
__git_log_shortlog_options=" | |
--author= --committer= --grep= | |
--all-match | |
" | |
__git_log_pretty_formats="oneline short medium full fuller email raw format:" | |
__git_log_date_formats="relative iso8601 rfc2822 short local default raw" | |
_git_log () | |
{ | |
__git_has_doubledash && return | |
local g="$(git rev-parse --git-dir 2>/dev/null)" | |
local merge="" | |
if [ -f "$g/MERGE_HEAD" ]; then | |
merge="--merge" | |
fi | |
case "$cur" in | |
--pretty=*|--format=*) | |
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases) | |
" "" "${cur#*=}" | |
return | |
;; | |
--date=*) | |
__gitcomp "$__git_log_date_formats" "" "${cur##--date=}" | |
return | |
;; | |
--decorate=*) | |
__gitcomp "long short" "" "${cur##--decorate=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
$__git_log_common_options | |
$__git_log_shortlog_options | |
$__git_log_gitk_options | |
--root --topo-order --date-order --reverse | |
--follow --full-diff | |
--abbrev-commit --abbrev= | |
--relative-date --date= | |
--pretty= --format= --oneline | |
--cherry-pick | |
--graph | |
--decorate --decorate= | |
--walk-reflogs | |
--parents --children | |
$merge | |
$__git_diff_common_options | |
--pickaxe-all --pickaxe-regex | |
" | |
return | |
;; | |
esac | |
__git_complete_revlist | |
} | |
# Common merge options shared by git-merge(1) and git-pull(1). | |
__git_merge_options=" | |
--no-commit --no-stat --log --no-log --squash --strategy | |
--commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit | |
--verify-signatures --no-verify-signatures --gpg-sign | |
--quiet --verbose --progress --no-progress | |
" | |
_git_merge () | |
{ | |
__git_complete_strategy && return | |
case "$cur" in | |
--*) | |
__gitcomp "$__git_merge_options | |
--rerere-autoupdate --no-rerere-autoupdate --abort" | |
return | |
esac | |
__gitcomp_nl "$(__git_refs)" | |
} | |
_git_mergetool () | |
{ | |
case "$cur" in | |
--tool=*) | |
__gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}" | |
return | |
;; | |
--*) | |
__gitcomp "--tool=" | |
return | |
;; | |
esac | |
} | |
_git_merge_base () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp "--octopus --independent --is-ancestor --fork-point" | |
return | |
;; | |
esac | |
__gitcomp_nl "$(__git_refs)" | |
} | |
_git_mv () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp "--dry-run" | |
return | |
;; | |
esac | |
if [ $(__git_count_arguments "mv") -gt 0 ]; then | |
# We need to show both cached and untracked files (including | |
# empty directories) since this may not be the last argument. | |
__git_complete_index_file "--cached --others --directory" | |
else | |
__git_complete_index_file "--cached" | |
fi | |
} | |
_git_name_rev () | |
{ | |
__gitcomp "--tags --all --stdin" | |
} | |
_git_notes () | |
{ | |
local subcommands='add append copy edit list prune remove show' | |
local subcommand="$(__git_find_on_cmdline "$subcommands")" | |
case "$subcommand,$cur" in | |
,--*) | |
__gitcomp '--ref' | |
;; | |
,*) | |
case "$prev" in | |
--ref) | |
__gitcomp_nl "$(__git_refs)" | |
;; | |
*) | |
__gitcomp "$subcommands --ref" | |
;; | |
esac | |
;; | |
add,--reuse-message=*|append,--reuse-message=*|\ | |
add,--reedit-message=*|append,--reedit-message=*) | |
__gitcomp_nl "$(__git_refs)" "" "${cur#*=}" | |
;; | |
add,--*|append,--*) | |
__gitcomp '--file= --message= --reedit-message= | |
--reuse-message=' | |
;; | |
copy,--*) | |
__gitcomp '--stdin' | |
;; | |
prune,--*) | |
__gitcomp '--dry-run --verbose' | |
;; | |
prune,*) | |
;; | |
*) | |
case "$prev" in | |
-m|-F) | |
;; | |
*) | |
__gitcomp_nl "$(__git_refs)" | |
;; | |
esac | |
;; | |
esac | |
} | |
_git_pull () | |
{ | |
__git_complete_strategy && return | |
case "$cur" in | |
--recurse-submodules=*) | |
__gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--rebase --no-rebase | |
$__git_merge_options | |
$__git_fetch_options | |
" | |
return | |
;; | |
esac | |
__git_complete_remote_or_refspec | |
} | |
__git_push_recurse_submodules="check on-demand" | |
__git_complete_force_with_lease () | |
{ | |
local cur_=$1 | |
case "$cur_" in | |
--*=) | |
;; | |
*:*) | |
__gitcomp_nl "$(__git_refs)" "" "${cur_#*:}" | |
;; | |
*) | |
__gitcomp_nl "$(__git_refs)" "" "$cur_" | |
;; | |
esac | |
} | |
_git_push () | |
{ | |
case "$prev" in | |
--repo) | |
__gitcomp_nl "$(__git_remotes)" | |
return | |
;; | |
--recurse-submodules) | |
__gitcomp "$__git_push_recurse_submodules" | |
return | |
;; | |
esac | |
case "$cur" in | |
--repo=*) | |
__gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}" | |
return | |
;; | |
--recurse-submodules=*) | |
__gitcomp "$__git_push_recurse_submodules" "" "${cur##--recurse-submodules=}" | |
return | |
;; | |
--force-with-lease=*) | |
__git_complete_force_with_lease "${cur##--force-with-lease=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--all --mirror --tags --dry-run --force --verbose | |
--quiet --prune --delete --follow-tags | |
--receive-pack= --repo= --set-upstream | |
--force-with-lease --force-with-lease= --recurse-submodules= | |
" | |
return | |
;; | |
esac | |
__git_complete_remote_or_refspec | |
} | |
_git_rebase () | |
{ | |
local dir="$(__gitdir)" | |
if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then | |
__gitcomp "--continue --skip --abort" | |
return | |
fi | |
__git_complete_strategy && return | |
case "$cur" in | |
--whitespace=*) | |
__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--onto --merge --strategy --interactive | |
--preserve-merges --stat --no-stat | |
--committer-date-is-author-date --ignore-date | |
--ignore-whitespace --whitespace= | |
--autosquash --fork-point --no-fork-point | |
" | |
return | |
esac | |
__gitcomp_nl "$(__git_refs)" | |
} | |
_git_reflog () | |
{ | |
local subcommands="show delete expire" | |
local subcommand="$(__git_find_on_cmdline "$subcommands")" | |
if [ -z "$subcommand" ]; then | |
__gitcomp "$subcommands" | |
else | |
__gitcomp_nl "$(__git_refs)" | |
fi | |
} | |
__git_send_email_confirm_options="always never auto cc compose" | |
__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all" | |
_git_send_email () | |
{ | |
case "$cur" in | |
--confirm=*) | |
__gitcomp " | |
$__git_send_email_confirm_options | |
" "" "${cur##--confirm=}" | |
return | |
;; | |
--suppress-cc=*) | |
__gitcomp " | |
$__git_send_email_suppresscc_options | |
" "" "${cur##--suppress-cc=}" | |
return | |
;; | |
--smtp-encryption=*) | |
__gitcomp "ssl tls" "" "${cur##--smtp-encryption=}" | |
return | |
;; | |
--thread=*) | |
__gitcomp " | |
deep shallow | |
" "" "${cur##--thread=}" | |
return | |
;; | |
--*) | |
__gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to | |
--compose --confirm= --dry-run --envelope-sender | |
--from --identity | |
--in-reply-to --no-chain-reply-to --no-signed-off-by-cc | |
--no-suppress-from --no-thread --quiet | |
--signed-off-by-cc --smtp-pass --smtp-server | |
--smtp-server-port --smtp-encryption= --smtp-user | |
--subject --suppress-cc= --suppress-from --thread --to | |
--validate --no-validate | |
$__git_format_patch_options" | |
return | |
;; | |
esac | |
__git_complete_revlist | |
} | |
_git_stage () | |
{ | |
_git_add | |
} | |
__git_config_get_set_variables () | |
{ | |
local prevword word config_file= c=$cword | |
while [ $c -gt 1 ]; do | |
word="${words[c]}" | |
case "$word" in | |
--system|--global|--local|--file=*) | |
config_file="$word" | |
break | |
;; | |
-f|--file) | |
config_file="$word $prevword" | |
break | |
;; | |
esac | |
prevword=$word | |
c=$((--c)) | |
done | |
git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null | | |
while read -r line | |
do | |
case "$line" in | |
*.*=*) | |
echo "${line/=*/}" | |
;; | |
esac | |
done | |
} | |
_git_config () | |
{ | |
case "$prev" in | |
branch.*.remote|branch.*.pushremote) | |
__gitcomp_nl "$(__git_remotes)" | |
return | |
;; | |
branch.*.merge) | |
__gitcomp_nl "$(__git_refs)" | |
return | |
;; | |
branch.*.rebase) | |
__gitcomp "false true" | |
return | |
;; | |
remote.pushdefault) | |
__gitcomp_nl "$(__git_remotes)" | |
return | |
;; | |
remote.*.fetch) | |
local remote="${prev#remote.}" | |
remote="${remote%.fetch}" | |
if [ -z "$cur" ]; then | |
__gitcomp_nl "refs/heads/" "" "" "" | |
return | |
fi | |
__gitcomp_nl "$(__git_refs_remotes "$remote")" | |
return | |
;; | |
remote.*.push) | |
local remote="${prev#remote.}" | |
remote="${remote%.push}" | |
__gitcomp_nl "$(git --git-dir="$(__gitdir)" \ | |
for-each-ref --format='%(refname):%(refname)' \ | |
refs/heads)" | |
return | |
;; | |
pull.twohead|pull.octopus) | |
__git_compute_merge_strategies | |
__gitcomp "$__git_merge_strategies" | |
return | |
;; | |
color.branch|color.diff|color.interactive|\ | |
color.showbranch|color.status|color.ui) | |
__gitcomp "always never auto" | |
return | |
;; | |
color.pager) | |
__gitcomp "false true" | |
return | |
;; | |
color.*.*) | |
__gitcomp " | |
normal black red green yellow blue magenta cyan white | |
bold dim ul blink reverse | |
" | |
return | |
;; | |
diff.submodule) | |
__gitcomp "log short" | |
return | |
;; | |
help.format) | |
__gitcomp "man info web html" | |
return | |
;; | |
log.date) | |
__gitcomp "$__git_log_date_formats" | |
return | |
;; | |
sendemail.aliasesfiletype) | |
__gitcomp "mutt mailrc pine elm gnus" | |
return | |
;; | |
sendemail.confirm) | |
__gitcomp "$__git_send_email_confirm_options" | |
return | |
;; | |
sendemail.suppresscc) | |
__gitcomp "$__git_send_email_suppresscc_options" | |
return | |
;; | |
--get|--get-all|--unset|--unset-all) | |
__gitcomp_nl "$(__git_config_get_set_variables)" | |
return | |
;; | |
*.*) | |
return | |
;; | |
esac | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--system --global --local --file= | |
--list --replace-all | |
--get --get-all --get-regexp | |
--add --unset --unset-all | |
--remove-section --rename-section | |
" | |
return | |
;; | |
branch.*.*) | |
local pfx="${cur%.*}." cur_="${cur##*.}" | |
__gitcomp "remote pushremote merge mergeoptions rebase" "$pfx" "$cur_" | |
return | |
;; | |
branch.*) | |
local pfx="${cur%.*}." cur_="${cur#*.}" | |
__gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "." | |
__gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_" | |
return | |
;; | |
guitool.*.*) | |
local pfx="${cur%.*}." cur_="${cur##*.}" | |
__gitcomp " | |
argprompt cmd confirm needsfile noconsole norescan | |
prompt revprompt revunmerged title | |
" "$pfx" "$cur_" | |
return | |
;; | |
difftool.*.*) | |
local pfx="${cur%.*}." cur_="${cur##*.}" | |
__gitcomp "cmd path" "$pfx" "$cur_" | |
return | |
;; | |
man.*.*) | |
local pfx="${cur%.*}." cur_="${cur##*.}" | |
__gitcomp "cmd path" "$pfx" "$cur_" | |
return | |
;; | |
mergetool.*.*) | |
local pfx="${cur%.*}." cur_="${cur##*.}" | |
__gitcomp "cmd path trustExitCode" "$pfx" "$cur_" | |
return | |
;; | |
pager.*) | |
local pfx="${cur%.*}." cur_="${cur#*.}" | |
__git_compute_all_commands | |
__gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" | |
return | |
;; | |
remote.*.*) | |
local pfx="${cur%.*}." cur_="${cur##*.}" | |
__gitcomp " | |
url proxy fetch push mirror skipDefaultUpdate | |
receivepack uploadpack tagopt pushurl | |
" "$pfx" "$cur_" | |
return | |
;; | |
remote.*) | |
local pfx="${cur%.*}." cur_="${cur#*.}" | |
__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "." | |
__gitcomp_nl_append "pushdefault" "$pfx" "$cur_" | |
return | |
;; | |
url.*.*) | |
local pfx="${cur%.*}." cur_="${cur##*.}" | |
__gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" | |
return | |
;; | |
esac | |
__gitcomp " | |
add.ignoreErrors | |
advice.commitBeforeMerge | |
advice.detachedHead | |
advice.implicitIdentity | |
advice.pushNonFastForward | |
advice.resolveConflict | |
advice.statusHints | |
alias. | |
am.keepcr | |
apply.ignorewhitespace | |
apply.whitespace | |
branch.autosetupmerge | |
branch.autosetuprebase | |
browser. | |
clean.requireForce | |
color.branch | |
color.branch.current | |
color.branch.local | |
color.branch.plain | |
color.branch.remote | |
color.decorate.HEAD | |
color.decorate.branch | |
color.decorate.remoteBranch | |
color.decorate.stash | |
color.decorate.tag | |
color.diff | |
color.diff.commit | |
color.diff.frag | |
color.diff.func | |
color.diff.meta | |
color.diff.new | |
color.diff.old | |
color.diff.plain | |
color.diff.whitespace | |
color.grep | |
color.grep.context | |
color.grep.filename | |
color.grep.function | |
color.grep.linenumber | |
color.grep.match | |
color.grep.selected | |
color.grep.separator | |
color.interactive | |
color.interactive.error | |
color.interactive.header | |
color.interactive.help | |
color.interactive.prompt | |
color.pager | |
color.showbranch | |
color.status | |
color.status.added | |
color.status.changed | |
color.status.header | |
color.status.nobranch | |
color.status.untracked | |
color.status.updated | |
color.ui | |
commit.status | |
commit.template | |
core.abbrev | |
core.askpass | |
core.attributesfile | |
core.autocrlf | |
core.bare | |
core.bigFileThreshold | |
core.compression | |
core.createObject | |
core.deltaBaseCacheLimit | |
core.editor | |
core.eol | |
core.excludesfile | |
core.fileMode | |
core.fsyncobjectfiles | |
core.gitProxy | |
core.ignoreStat | |
core.ignorecase | |
core.logAllRefUpdates | |
core.loosecompression | |
core.notesRef | |
core.packedGitLimit | |
core.packedGitWindowSize | |
core.pager | |
core.preferSymlinkRefs | |
core.preloadindex | |
core.quotepath | |
core.repositoryFormatVersion | |
core.safecrlf | |
core.sharedRepository | |
core.sparseCheckout | |
core.symlinks | |
core.trustctime | |
core.warnAmbiguousRefs | |
core.whitespace | |
core.worktree | |
diff.autorefreshindex | |
diff.external | |
diff.ignoreSubmodules | |
diff.mnemonicprefix | |
diff.noprefix | |
diff.renameLimit | |
diff.renames | |
diff.statGraphWidth | |
diff.submodule | |
diff.suppressBlankEmpty | |
diff.tool | |
diff.wordRegex | |
diff.algorithm | |
difftool. | |
difftool.prompt | |
fetch.recurseSubmodules | |
fetch.unpackLimit | |
format.attach | |
format.cc | |
format.coverLetter | |
format.headers | |
format.numbered | |
format.pretty | |
format.signature | |
format.signoff | |
format.subjectprefix | |
format.suffix | |
format.thread | |
format.to | |
gc. | |
gc.aggressiveWindow | |
gc.auto | |
gc.autopacklimit | |
gc.packrefs | |
gc.pruneexpire | |
gc.reflogexpire | |
gc.reflogexpireunreachable | |
gc.rerereresolved | |
gc.rerereunresolved | |
gitcvs.allbinary | |
gitcvs.commitmsgannotation | |
gitcvs.dbTableNamePrefix | |
gitcvs.dbdriver | |
gitcvs.dbname | |
gitcvs.dbpass | |
gitcvs.dbuser | |
gitcvs.enabled | |
gitcvs.logfile | |
gitcvs.usecrlfattr | |
guitool. | |
gui.blamehistoryctx | |
gui.commitmsgwidth | |
gui.copyblamethreshold | |
gui.diffcontext | |
gui.encoding | |
gui.fastcopyblame | |
gui.matchtrackingbranch | |
gui.newbranchtemplate | |
gui.pruneduringfetch | |
gui.spellingdictionary | |
gui.trustmtime | |
help.autocorrect | |
help.browser | |
help.format | |
http.lowSpeedLimit | |
http.lowSpeedTime | |
http.maxRequests | |
http.minSessions | |
http.noEPSV | |
http.postBuffer | |
http.proxy | |
http.sslCAInfo | |
http.sslCAPath | |
http.sslCert | |
http.sslCertPasswordProtected | |
http.sslKey | |
http.sslVerify | |
http.useragent | |
i18n.commitEncoding | |
i18n.logOutputEncoding | |
imap.authMethod | |
imap.folder | |
imap.host | |
imap.pass | |
imap.port | |
imap.preformattedHTML | |
imap.sslverify | |
imap.tunnel | |
imap.user | |
init.templatedir | |
instaweb.browser | |
instaweb.httpd | |
instaweb.local | |
instaweb.modulepath | |
instaweb.port | |
interactive.singlekey | |
log.date | |
log.decorate | |
log.showroot | |
mailmap.file | |
man. | |
man.viewer | |
merge. | |
merge.conflictstyle | |
merge.log | |
merge.renameLimit | |
merge.renormalize | |
merge.stat | |
merge.tool | |
merge.verbosity | |
mergetool. | |
mergetool.keepBackup | |
mergetool.keepTemporaries | |
mergetool.prompt | |
notes.displayRef | |
notes.rewrite. | |
notes.rewrite.amend | |
notes.rewrite.rebase | |
notes.rewriteMode | |
notes.rewriteRef | |
pack.compression | |
pack.deltaCacheLimit | |
pack.deltaCacheSize | |
pack.depth | |
pack.indexVersion | |
pack.packSizeLimit | |
pack.threads | |
pack.window | |
pack.windowMemory | |
pager. | |
pretty. | |
pull.octopus | |
pull.twohead | |
push.default | |
rebase.autosquash | |
rebase.stat | |
receive.autogc | |
receive.denyCurrentBranch | |
receive.denyDeleteCurrent | |
receive.denyDeletes | |
receive.denyNonFastForwards | |
receive.fsckObjects | |
receive.unpackLimit | |
receive.updateserverinfo | |
remote.pushdefault | |
remotes. | |
repack.usedeltabaseoffset | |
rerere.autoupdate | |
rerere.enabled | |
sendemail. | |
sendemail.aliasesfile | |
sendemail.aliasfiletype | |
sendemail.bcc | |
sendemail.cc | |
sendemail.cccmd | |
sendemail.chainreplyto | |
sendemail.confirm | |
sendemail.envelopesender | |
sendemail.from | |
sendemail.identity | |
sendemail.multiedit | |
sendemail.signedoffbycc | |
sendemail.smtpdomain | |
sendemail.smtpencryption | |
sendemail.smtppass | |
sendemail.smtpserver | |
sendemail.smtpserveroption | |
sendemail.smtpserverport | |
sendemail.smtpuser | |
sendemail.suppresscc | |
sendemail.suppressfrom | |
sendemail.thread | |
sendemail.to | |
sendemail.validate | |
showbranch.default | |
status.relativePaths | |
status.showUntrackedFiles | |
status.submodulesummary | |
submodule. | |
tar.umask | |
transfer.unpackLimit | |
url. | |
user.email | |
user.name | |
user.signingkey | |
web.browser | |
branch. remote. | |
" | |
} | |
_git_remote () | |
{ | |
local subcommands="add rename remove set-head set-branches set-url show prune update" | |
local subcommand="$(__git_find_on_cmdline "$subcommands")" | |
if [ -z "$subcommand" ]; then | |
__gitcomp "$subcommands" | |
return | |
fi | |
case "$subcommand" in | |
rename|remove|set-url|show|prune) | |
__gitcomp_nl "$(__git_remotes)" | |
;; | |
set-head|set-branches) | |
__git_complete_remote_or_refspec | |
;; | |
update) | |
local i c='' IFS=$'\n' | |
for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do | |
i="${i#remotes.}" | |
c="$c ${i/ */}" | |
done | |
__gitcomp "$c" | |
;; | |
*) | |
;; | |
esac | |
} | |
_git_replace () | |
{ | |
__gitcomp_nl "$(__git_refs)" | |
} | |
_git_reset () | |
{ | |
__git_has_doubledash && return | |
case "$cur" in | |
--*) | |
__gitcomp "--merge --mixed --hard --soft --patch" | |
return | |
;; | |
esac | |
__gitcomp_nl "$(__git_refs)" | |
} | |
_git_revert () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp "--edit --mainline --no-edit --no-commit --signoff" | |
return | |
;; | |
esac | |
__gitcomp_nl "$(__git_refs)" | |
} | |
_git_rm () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp "--cached --dry-run --ignore-unmatch --quiet" | |
return | |
;; | |
esac | |
__git_complete_index_file "--cached" | |
} | |
_git_shortlog () | |
{ | |
__git_has_doubledash && return | |
case "$cur" in | |
--*) | |
__gitcomp " | |
$__git_log_common_options | |
$__git_log_shortlog_options | |
--numbered --summary | |
" | |
return | |
;; | |
esac | |
__git_complete_revlist | |
} | |
_git_show () | |
{ | |
__git_has_doubledash && return | |
case "$cur" in | |
--pretty=*|--format=*) | |
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases) | |
" "" "${cur#*=}" | |
return | |
;; | |
--diff-algorithm=*) | |
__gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}" | |
return | |
;; | |
--*) | |
__gitcomp "--pretty= --format= --abbrev-commit --oneline | |
$__git_diff_common_options | |
" | |
return | |
;; | |
esac | |
__git_complete_revlist_file | |
} | |
_git_show_branch () | |
{ | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--all --remotes --topo-order --current --more= | |
--list --independent --merge-base --no-name | |
--color --no-color | |
--sha1-name --sparse --topics --reflog | |
" | |
return | |
;; | |
esac | |
__git_complete_revlist | |
} | |
_git_stash () | |
{ | |
local save_opts='--keep-index --no-keep-index --quiet --patch' | |
local subcommands='save list show apply clear drop pop create branch' | |
local subcommand="$(__git_find_on_cmdline "$subcommands")" | |
if [ -z "$subcommand" ]; then | |
case "$cur" in | |
--*) | |
__gitcomp "$save_opts" | |
;; | |
*) | |
if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then | |
__gitcomp "$subcommands" | |
fi | |
;; | |
esac | |
else | |
case "$subcommand,$cur" in | |
save,--*) | |
__gitcomp "$save_opts" | |
;; | |
apply,--*|pop,--*) | |
__gitcomp "--index --quiet" | |
;; | |
show,--*|drop,--*|branch,--*) | |
;; | |
show,*|apply,*|drop,*|pop,*|branch,*) | |
__gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \ | |
| sed -n -e 's/:.*//p')" | |
;; | |
*) | |
;; | |
esac | |
fi | |
} | |
_git_submodule () | |
{ | |
__git_has_doubledash && return | |
local subcommands="add status init deinit update summary foreach sync" | |
if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then | |
case "$cur" in | |
--*) | |
__gitcomp "--quiet --cached" | |
;; | |
*) | |
__gitcomp "$subcommands" | |
;; | |
esac | |
return | |
fi | |
} | |
_git_svn () | |
{ | |
local subcommands=" | |
init fetch clone rebase dcommit log find-rev | |
set-tree commit-diff info create-ignore propget | |
proplist show-ignore show-externals branch tag blame | |
migrate mkdirs reset gc | |
" | |
local subcommand="$(__git_find_on_cmdline "$subcommands")" | |
if [ -z "$subcommand" ]; then | |
__gitcomp "$subcommands" | |
else | |
local remote_opts="--username= --config-dir= --no-auth-cache" | |
local fc_opts=" | |
--follow-parent --authors-file= --repack= | |
--no-metadata --use-svm-props --use-svnsync-props | |
--log-window-size= --no-checkout --quiet | |
--repack-flags --use-log-author --localtime | |
--ignore-paths= --include-paths= $remote_opts | |
" | |
local init_opts=" | |
--template= --shared= --trunk= --tags= | |
--branches= --stdlayout --minimize-url | |
--no-metadata --use-svm-props --use-svnsync-props | |
--rewrite-root= --prefix= --use-log-author | |
--add-author-from $remote_opts | |
" | |
local cmt_opts=" | |
--edit --rmdir --find-copies-harder --copy-similarity= | |
" | |
case "$subcommand,$cur" in | |
fetch,--*) | |
__gitcomp "--revision= --fetch-all $fc_opts" | |
;; | |
clone,--*) | |
__gitcomp "--revision= $fc_opts $init_opts" | |
;; | |
init,--*) | |
__gitcomp "$init_opts" | |
;; | |
dcommit,--*) | |
__gitcomp " | |
--merge --strategy= --verbose --dry-run | |
--fetch-all --no-rebase --commit-url | |
--revision --interactive $cmt_opts $fc_opts | |
" | |
;; | |
set-tree,--*) | |
__gitcomp "--stdin $cmt_opts $fc_opts" | |
;; | |
create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\ | |
show-externals,--*|mkdirs,--*) | |
__gitcomp "--revision=" | |
;; | |
log,--*) | |
__gitcomp " | |
--limit= --revision= --verbose --incremental | |
--oneline --show-commit --non-recursive | |
--authors-file= --color | |
" | |
;; | |
rebase,--*) | |
__gitcomp " | |
--merge --verbose --strategy= --local | |
--fetch-all --dry-run $fc_opts | |
" | |
;; | |
commit-diff,--*) | |
__gitcomp "--message= --file= --revision= $cmt_opts" | |
;; | |
info,--*) | |
__gitcomp "--url" | |
;; | |
branch,--*) | |
__gitcomp "--dry-run --message --tag" | |
;; | |
tag,--*) | |
__gitcomp "--dry-run --message" | |
;; | |
blame,--*) | |
__gitcomp "--git-format" | |
;; | |
migrate,--*) | |
__gitcomp " | |
--config-dir= --ignore-paths= --minimize | |
--no-auth-cache --username= | |
" | |
;; | |
reset,--*) | |
__gitcomp "--revision= --parent" | |
;; | |
*) | |
;; | |
esac | |
fi | |
} | |
_git_tag () | |
{ | |
local i c=1 f=0 | |
while [ $c -lt $cword ]; do | |
i="${words[c]}" | |
case "$i" in | |
-d|-v) | |
__gitcomp_nl "$(__git_tags)" | |
return | |
;; | |
-f) | |
f=1 | |
;; | |
esac | |
((c++)) | |
done | |
case "$prev" in | |
-m|-F) | |
;; | |
-*|tag) | |
if [ $f = 1 ]; then | |
__gitcomp_nl "$(__git_tags)" | |
fi | |
;; | |
*) | |
__gitcomp_nl "$(__git_refs)" | |
;; | |
esac | |
} | |
_git_whatchanged () | |
{ | |
_git_log | |
} | |
__git_main () | |
{ | |
local i c=1 command __git_dir | |
while [ $c -lt $cword ]; do | |
i="${words[c]}" | |
case "$i" in | |
--git-dir=*) __git_dir="${i#--git-dir=}" ;; | |
--git-dir) ((c++)) ; __git_dir="${words[c]}" ;; | |
--bare) __git_dir="." ;; | |
--help) command="help"; break ;; | |
-c|--work-tree|--namespace) ((c++)) ;; | |
-*) ;; | |
*) command="$i"; break ;; | |
esac | |
((c++)) | |
done | |
if [ -z "$command" ]; then | |
case "$cur" in | |
--*) __gitcomp " | |
--paginate | |
--no-pager | |
--git-dir= | |
--bare | |
--version | |
--exec-path | |
--exec-path= | |
--html-path | |
--man-path | |
--info-path | |
--work-tree= | |
--namespace= | |
--no-replace-objects | |
--help | |
" | |
;; | |
*) __git_compute_porcelain_commands | |
__gitcomp "$__git_porcelain_commands $(__git_aliases)" ;; | |
esac | |
return | |
fi | |
local completion_func="_git_${command//-/_}" | |
declare -f $completion_func >/dev/null && $completion_func && return | |
local expansion=$(__git_aliased_command "$command") | |
if [ -n "$expansion" ]; then | |
words[1]=$expansion | |
completion_func="_git_${expansion//-/_}" | |
declare -f $completion_func >/dev/null && $completion_func | |
fi | |
} | |
__gitk_main () | |
{ | |
__git_has_doubledash && return | |
local g="$(__gitdir)" | |
local merge="" | |
if [ -f "$g/MERGE_HEAD" ]; then | |
merge="--merge" | |
fi | |
case "$cur" in | |
--*) | |
__gitcomp " | |
$__git_log_common_options | |
$__git_log_gitk_options | |
$merge | |
" | |
return | |
;; | |
esac | |
__git_complete_revlist | |
} | |
if [[ -n ${ZSH_VERSION-} ]]; then | |
echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2 | |
autoload -U +X compinit && compinit | |
__gitcomp () | |
{ | |
emulate -L zsh | |
local cur_="${3-$cur}" | |
case "$cur_" in | |
--*=) | |
;; | |
*) | |
local c IFS=$' \t\n' | |
local -a array | |
for c in ${=1}; do | |
c="$c${4-}" | |
case $c in | |
--*=*|*.) ;; | |
*) c="$c " ;; | |
esac | |
array[${#array[@]}+1]="$c" | |
done | |
compset -P '*[=:]' | |
compadd -Q -S '' -p "${2-}" -a -- array && _ret=0 | |
;; | |
esac | |
} | |
__gitcomp_nl () | |
{ | |
emulate -L zsh | |
local IFS=$'\n' | |
compset -P '*[=:]' | |
compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 | |
} | |
__gitcomp_file () | |
{ | |
emulate -L zsh | |
local IFS=$'\n' | |
compset -P '*[=:]' | |
compadd -Q -p "${2-}" -f -- ${=1} && _ret=0 | |
} | |
_git () | |
{ | |
local _ret=1 cur cword prev | |
cur=${words[CURRENT]} | |
prev=${words[CURRENT-1]} | |
let cword=CURRENT-1 | |
emulate ksh -c __${service}_main | |
let _ret && _default && _ret=0 | |
return _ret | |
} | |
compdef _git git gitk | |
return | |
fi | |
__git_func_wrap () | |
{ | |
local cur words cword prev | |
_get_comp_words_by_ref -n =: cur words cword prev | |
$1 | |
} | |
# Setup completion for certain functions defined above by setting common | |
# variables and workarounds. | |
# This is NOT a public function; use at your own risk. | |
__git_complete () | |
{ | |
local wrapper="__git_wrap${2}" | |
eval "$wrapper () { __git_func_wrap $2 ; }" | |
complete -o bashdefault -o default -o nospace -F $wrapper $1 2>/dev/null \ | |
|| complete -o default -o nospace -F $wrapper $1 | |
} | |
# wrapper for backwards compatibility | |
_git () | |
{ | |
__git_wrap__git_main | |
} | |
# wrapper for backwards compatibility | |
_gitk () | |
{ | |
__git_wrap__gitk_main | |
} | |
__git_complete git __git_main | |
__git_complete gitk __gitk_main | |
# The following are necessary only for Cygwin, and only are needed | |
# when the user has tab-completed the executable name and consequently | |
# included the '.exe' suffix. | |
# | |
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then | |
__git_complete git.exe __git_main | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#compdef git gitk | |
# zsh completion wrapper for git | |
# | |
# Copyright (c) 2012-2013 Felipe Contreras <[email protected]> | |
# | |
# You need git's bash completion script installed somewhere, by default it | |
# would be the location bash-completion uses. | |
# | |
# If your script is somewhere else, you can configure it on your ~/.zshrc: | |
# | |
# zstyle ':completion:*:*:git:*' script ~/.git-completion.sh | |
# | |
# The recommended way to install this script is to copy to '~/.zsh/_git', and | |
# then add the following to your ~/.zshrc file: | |
# | |
# fpath=(~/.zsh $fpath) | |
complete () | |
{ | |
# do nothing | |
return 0 | |
} | |
zstyle -T ':completion:*:*:git:*' tag-order && \ | |
zstyle ':completion:*:*:git:*' tag-order 'common-commands' | |
zstyle -s ":completion:*:*:git:*" script script | |
if [ -z "$script" ]; then | |
local -a locations | |
local e | |
locations=( | |
$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash | |
'/etc/bash_completion.d/git' # fedora, old debian | |
'/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian | |
'/usr/share/bash-completion/git' # gentoo | |
) | |
for e in $locations; do | |
test -f $e && script="$e" && break | |
done | |
fi | |
ZSH_VERSION='' . "$script" | |
__gitcomp () | |
{ | |
emulate -L zsh | |
local cur_="${3-$cur}" | |
case "$cur_" in | |
--*=) | |
;; | |
*) | |
local c IFS=$' \t\n' | |
local -a array | |
for c in ${=1}; do | |
c="$c${4-}" | |
case $c in | |
--*=*|*.) ;; | |
*) c="$c " ;; | |
esac | |
array+=("$c") | |
done | |
compset -P '*[=:]' | |
compadd -Q -S '' -p "${2-}" -a -- array && _ret=0 | |
;; | |
esac | |
} | |
__gitcomp_nl () | |
{ | |
emulate -L zsh | |
local IFS=$'\n' | |
compset -P '*[=:]' | |
compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 | |
} | |
__gitcomp_nl_append () | |
{ | |
emulate -L zsh | |
local IFS=$'\n' | |
compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 | |
} | |
__gitcomp_file () | |
{ | |
emulate -L zsh | |
local IFS=$'\n' | |
compset -P '*[=:]' | |
compadd -Q -p "${2-}" -f -- ${=1} && _ret=0 | |
} | |
__git_zsh_bash_func () | |
{ | |
emulate -L ksh | |
local command=$1 | |
local completion_func="_git_${command//-/_}" | |
declare -f $completion_func >/dev/null && $completion_func && return | |
local expansion=$(__git_aliased_command "$command") | |
if [ -n "$expansion" ]; then | |
words[1]=$expansion | |
completion_func="_git_${expansion//-/_}" | |
declare -f $completion_func >/dev/null && $completion_func | |
fi | |
} | |
__git_zsh_cmd_common () | |
{ | |
local -a list | |
list=( | |
add:'add file contents to the index' | |
bisect:'find by binary search the change that introduced a bug' | |
branch:'list, create, or delete branches' | |
checkout:'checkout a branch or paths to the working tree' | |
clone:'clone a repository into a new directory' | |
commit:'record changes to the repository' | |
diff:'show changes between commits, commit and working tree, etc' | |
fetch:'download objects and refs from another repository' | |
grep:'print lines matching a pattern' | |
init:'create an empty Git repository or reinitialize an existing one' | |
log:'show commit logs' | |
merge:'join two or more development histories together' | |
mv:'move or rename a file, a directory, or a symlink' | |
pull:'fetch from and merge with another repository or a local branch' | |
push:'update remote refs along with associated objects' | |
rebase:'forward-port local commits to the updated upstream head' | |
reset:'reset current HEAD to the specified state' | |
rm:'remove files from the working tree and from the index' | |
show:'show various types of objects' | |
status:'show the working tree status' | |
tag:'create, list, delete or verify a tag object signed with GPG') | |
_describe -t common-commands 'common commands' list && _ret=0 | |
} | |
__git_zsh_cmd_alias () | |
{ | |
local -a list | |
list=(${${${(0)"$(git config -z --get-regexp '^alias\.')"}#alias.}%$'\n'*}) | |
_describe -t alias-commands 'aliases' list $* && _ret=0 | |
} | |
__git_zsh_cmd_all () | |
{ | |
local -a list | |
emulate ksh -c __git_compute_all_commands | |
list=( ${=__git_all_commands} ) | |
_describe -t all-commands 'all commands' list && _ret=0 | |
} | |
__git_zsh_main () | |
{ | |
local curcontext="$curcontext" state state_descr line | |
typeset -A opt_args | |
local -a orig_words | |
orig_words=( ${words[@]} ) | |
_arguments -C \ | |
'(-p --paginate --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \ | |
'(-p --paginate)--no-pager[do not pipe git output into a pager]' \ | |
'--git-dir=-[set the path to the repository]: :_directories' \ | |
'--bare[treat the repository as a bare repository]' \ | |
'(- :)--version[prints the git suite version]' \ | |
'--exec-path=-[path to where your core git programs are installed]:: :_directories' \ | |
'--html-path[print the path where git''s HTML documentation is installed]' \ | |
'--info-path[print the path where the Info files are installed]' \ | |
'--man-path[print the manpath (see `man(1)`) for the man pages]' \ | |
'--work-tree=-[set the path to the working tree]: :_directories' \ | |
'--namespace=-[set the git namespace]' \ | |
'--no-replace-objects[do not use replacement refs to replace git objects]' \ | |
'(- :)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \ | |
'(-): :->command' \ | |
'(-)*:: :->arg' && return | |
case $state in | |
(command) | |
_alternative \ | |
'alias-commands:alias:__git_zsh_cmd_alias' \ | |
'common-commands:common:__git_zsh_cmd_common' \ | |
'all-commands:all:__git_zsh_cmd_all' && _ret=0 | |
;; | |
(arg) | |
local command="${words[1]}" __git_dir | |
if (( $+opt_args[--bare] )); then | |
__git_dir='.' | |
else | |
__git_dir=${opt_args[--git-dir]} | |
fi | |
(( $+opt_args[--help] )) && command='help' | |
words=( ${orig_words[@]} ) | |
__git_zsh_bash_func $command | |
;; | |
esac | |
} | |
_git () | |
{ | |
local _ret=1 | |
local cur cword prev | |
cur=${words[CURRENT]} | |
prev=${words[CURRENT-1]} | |
let cword=CURRENT-1 | |
if (( $+functions[__${service}_zsh_main] )); then | |
__${service}_zsh_main | |
else | |
emulate ksh -c __${service}_main | |
fi | |
let _ret && _default && _ret=0 | |
return _ret | |
} | |
_git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#compdef git git-cvsserver git-receive-pack git-upload-archive git-upload-pack git-shell gitk tig | |
# Some parts of this completion's behaviour are configurable: | |
# | |
# Say you got your own git sub-commands (git will run a program `git-foo' | |
# when you run "git foo") and you want "git f<tab>" to complete that sub | |
# commands name for you. You can make that sub-command know to the completion | |
# via the user-command style: | |
# | |
# % zstyle ':completion:*:*:git:*' user-commands foo:'description for foo' | |
# | |
# `user-commands' is a list style, so you can add any number of programs there. | |
# The :description part is optional, so you could add all git-* programs from | |
# your $path like this: | |
# | |
# % zstyle ':completion:*:*:git:*' user-commands ${${(M)${(k)commands}:#git-*}/git-/} | |
# | |
# A better solution is to create a function _git-foo() to handle specific | |
# completion for that command. This also allows you to add command-specific | |
# completion as well. Place such a function inside an autoloaded #compdef file | |
# and you should be all set. You can add a description to such a function by | |
# adding a line matching | |
# | |
# #description DESCRIPTION | |
# | |
# as the second line in the file. See | |
# Completion/Debian/Command/_git-buildpackage in the Zsh sources for an | |
# example. | |
# | |
# As this solution is so much better than the user-commands zstyle method, the | |
# zstyle method is now DEPRECATED. It will most likely be removed in the next | |
# major release of Zsh (5.0). | |
# | |
# When _git does not know a given sub-command (say `bar'), it falls back to | |
# completing file names for all arguments to that sub command. I.e.: | |
# | |
# % git bar <tab> | |
# | |
# ...will complete file names. If you do *not* want that fallback to be used, | |
# use the `use-fallback' style like this: | |
# | |
# % zstyle ':completion:*:*:git*:*' use-fallback false | |
# TODO: There is still undocumented configurability in here. | |
# HIGH-LEVEL COMMANDS (PORCELAIN) | |
# Main Porcelain Commands | |
(( $+functions[_git-add] )) || | |
_git-add () { | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
local ignore_missing= | |
if (( words[(I)-n|--dry-run] )); then | |
ignore_missing='--ignore-missing[check if files (even missing) are ignored in dry run]' | |
fi | |
_arguments -w -C -S -s \ | |
'(-n --dry-run)'{-n,--dry-run}'[do not actually add files; only show which ones would be added]' \ | |
'(-v --verbose)'{-v,--verbose}'[show files as they are added]' \ | |
'(-f --force)'{-f,--force}'[allow adding otherwise ignored files]' \ | |
'(-i --interactive : -)'{-i,--interactive}'[add contents interactively to index]' \ | |
'(-p --patch)'{-p,--patch}'[like -i but go directly into patch mode for specified files]' \ | |
'(-e --edit)'{-e,--edit}'[open diff against index in editor]' \ | |
'(-A --all --no-ignore-removal -u --update --no-all --ignore-removal)'{-A,--all,--no-ignore-removal}'[add, modify, and remove index entries to match the working tree]' \ | |
'(-A --all --no-ignore-removal -u --update --no-all --ignore-removal)'{--no-all,--ignore-removal}'[like "--all" but ignore removals]' \ | |
'(-A --all --no-ignore-removal -u --update --no-all --ignore-removal)'{-u,--update}'[update the index just where it already has an entry matching <pathspec>]' \ | |
'(-N --intent-to-add)'{-N,--intent-to-add}'[record only that path will be added later]' \ | |
'--refresh[do not add files, but refresh their stat() info in index]' \ | |
'--ignore-errors[continue adding if an error occurs]' \ | |
$ignore_missing \ | |
'*:: :->file' && return | |
case $state in | |
(file) | |
declare -a ignored_files_alternatives | |
if [[ -n ${opt_args[(I)-f|--force]} ]]; then | |
ignored_files_alternatives=( | |
'ignored-modified-files:ignored modified files:__git_ignore_line_inside_arguments __git_modified_files --ignored' | |
'ignored-other-files:ignored other files:__git_ignore_line_inside_arguments __git_other_files --ignored') | |
fi | |
_alternative \ | |
'modified-files::__git_ignore_line_inside_arguments __git_modified_files' \ | |
'other-files::__git_ignore_line_inside_arguments __git_other_files' \ | |
$ignored_files_alternatives && ret=0 | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-am] )) || | |
_git-am () { | |
local -a apply_options | |
__git_setup_apply_options | |
# NOTE: --rebasing and --resolvemsg are only for internal use between git | |
# rebase and git am. | |
# TODO: --patch-format is undocumented. | |
# TODO: --rerere-autoupdate and --no-rerere-autoupdate are | |
# undocumented (and not implemented here). | |
_arguments -S \ | |
'(-s --signoff)'{-s,--signoff}'[add Signed-off-by: line to the commit message]' \ | |
'(-k --keep)'{-k,--keep}'[pass -k to git mailinfo]' \ | |
'--keep-non-patch[pass -b to git mailinfo]' \ | |
'( --no-keep-cr)--keep-cr[pass --keep-cr to git mailsplit]' \ | |
'(--keep-cr )--no-keep-cr[do not pass --keep-cr to git mailsplit]' \ | |
'(-c --scissors --no-scissors)'{-c,--scissors}'[strip everything before a scissors line]' \ | |
'(-c --scissors --no-scissors)--no-scissors[ignore scissors lines]' \ | |
'(-q --quiet)'{-q,--quiet}'[only print error messages]' \ | |
'(-u --utf8 --no-utf8)'{-u,--utf8}'[pass -u to git mailinfo]' \ | |
'(-u --utf8 --no-utf8)--no-utf8[pass -n to git mailinfo]' \ | |
'(-3 --3way)'{-3,--3way}'[use 3-way merge if patch does not apply cleanly]' \ | |
$apply_options \ | |
'(-i --interactive)'{-i,--interactive}'[apply patches interactively]' \ | |
'--committer-date-is-author-date[use author date as committer date]' \ | |
'--ignore-date[use committer date as author date]' \ | |
'--skip[skip the current patch]' \ | |
'(--continue -r --resolved)'{--continue,-r,--resolved}'[continue after resolving patch failure by hand]' \ | |
'--abort[restore the original branch and abort the patching operation]' \ | |
'--patch-format=-[specify format patches are in]:patch format:((mbox\:"mbox format" | |
stgit-series\:"StGit patch series" | |
stgit\:"stgit format"))' \ | |
'*:mbox file:_files' | |
} | |
(( $+functions[_git-archive] )) || | |
_git-archive () { | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
declare -a backend_args | |
if (( words[(I)--format=*] > 0 && words[(I)--format=*] < CURRENT )); then | |
case ${words[$words[(I)--format=*]]#--format=} in | |
(zip) | |
backend_args=( | |
'-0[do not deflate files]' | |
'-1[minimum compression]' | |
'-2[a little more compression]' | |
'-3[slightly more compression]' | |
'-4[a bit more compression]' | |
'-5[even more compression]' | |
'-6[slightly even more compression]' | |
'-7[getting there]' | |
'-8[close to maximum compression]' | |
'-9[maximum compression]') | |
;; | |
esac | |
fi | |
_arguments -w -C -S -s \ | |
'--format=-[format of the resulting archive]:archive format:__git_archive_formats' \ | |
'(- :)'{-l,--list}'[list available archive formats]' \ | |
'(-v --verbose)'{-v,--verbose}'[report progress to stderr]' \ | |
'--prefix=-[prepend the given path prefix to each filename]:path prefix:_directories -r ""' \ | |
'--output=[write archive to argument instead of stdout]:archive:_files' \ | |
'--worktree-attributes[look for attributes in .gitattributes in working directory too]' \ | |
$backend_args \ | |
'--remote=[archive remote repository]:remote repository:__git_any_repositories' \ | |
'--exec=[path to git-receive-pack on remote]:remote path:_files' \ | |
': :__git_tree_ishs' \ | |
'*: :->file' && ret=0 | |
case $state in | |
(file) | |
__git_tree_files ${PREFIX:-.} $line[1] && ret=0 | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-applymbox] )) || | |
_git-applymbox () { | |
_arguments -A '-*' \ | |
'-k[do not modify "Subject:" header]' \ | |
'-m[apply patches with "git-apply" and fail if patch is unclean]' \ | |
'-q[apply patches interactively]' \ | |
'-u[encode commit information in UTF-8]' \ | |
'(1)-c[restart command after fixing an unclean patch]:patch:_files -g ".dotest/0*"' \ | |
':mbox file:_files' \ | |
'::signoff file:__git_signoff_file' | |
} | |
(( $+functions[_git-bisect] )) || | |
_git-bisect () { | |
# TODO: next subcommand is undocumented. Git-bisect.sh mentions that the | |
# subcommand might be removed from the UI level. | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
_arguments -C \ | |
'--help[display git-bisect manual page]' \ | |
': :->command' \ | |
'*:: :->option-or-argument' && ret=0 | |
case $state in | |
(command) | |
declare -a commands | |
commands=( | |
help:'display a short usage description' | |
start:'reset bisection state and start a new bisection' | |
bad:'mark current or given revision as bad' | |
good:'mark current or given revision as good' | |
skip:'choose a nearby commit' | |
next:'find next bisection to test and check it out' | |
reset:'finish bisection search and return to the given branch (or master)' | |
visualize:'show the remaining revisions in gitk' | |
view:'show the remaining revisions in gitk' | |
replay:'replay a bisection log' | |
log:'show the log of the current bisection' | |
run:'run evaluation script') | |
_describe -t commands command commands && ret=0 | |
;; | |
(option-or-argument) | |
curcontext=${curcontext%:*}-$line[1]: | |
case $line[1] in | |
(start) | |
_arguments -C \ | |
':bad revision:__git_commits' \ | |
'*: :->revision-or-path' && ret=0 | |
case $state in | |
(revision-or-path) | |
if compset -N '--' || ! __git_is_committish $line[CURRENT-1]; then | |
__git_cached_files && ret=0 | |
else | |
_alternative \ | |
'revisions::__git_revisions' \ | |
'files::__git_cached_files' && ret=0 | |
fi | |
;; | |
esac | |
;; | |
(bad) | |
_arguments \ | |
': :__git_commits' && ret=0 | |
;; | |
(good|skip) | |
# TODO: skip can take revlists. | |
_arguments \ | |
'*: :__git_commits' && ret=0 | |
;; | |
(replay) | |
_arguments \ | |
':log file:_files' && ret=0 | |
;; | |
(reset) | |
_arguments \ | |
': :__git_heads' && ret=0 | |
;; | |
(run) | |
_arguments \ | |
'*:: : _normal' && ret=0 | |
;; | |
(view|visualize) | |
local -a log_options revision_options | |
__git_setup_log_options | |
__git_setup_revision_options | |
_arguments -w -C -s \ | |
$log_options \ | |
$revision_options && ret=0 | |
(*) | |
_nothing | |
;; | |
esac | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-branch] )) || | |
_git-branch () { | |
declare l c m d e | |
l='--color --no-color -r -a -v --verbose --abbrev --no-abbrev --list' | |
c='-l -f --force -t --track --no-track -u --set-upstream --set-upstream-to --unset-upstream --contains --merged --no-merged' | |
m='-m --move -M' | |
d='-d --delete -D' | |
e='--edit-description' | |
declare -a dependent_creation_args | |
if (( words[(I)-r] == 0 )); then | |
dependent_creation_args=( | |
"($l $m $d): :__git_branch_names" | |
"::start-point:__git_revisions") | |
fi | |
declare -a dependent_deletion_args | |
if (( words[(I)-d] || words[(I)-D] )); then | |
dependent_creation_args= | |
dependent_deletion_args=( | |
'-r[delete only remote-tracking branches]') | |
if (( words[(I)-r] )); then | |
dependent_deletion_args+='*: :__git_ignore_line_inside_arguments __git_remote_branch_names' | |
else | |
dependent_deletion_args+='*: :__git_ignore_line_inside_arguments __git_branch_names' | |
fi | |
fi | |
declare -a dependent_modification_args | |
if (( words[(I)-m] || words[(I)-M] )); then | |
dependent_creation_args= | |
dependent_modification_args=( | |
':old or new branch name:__git_branch_names' | |
'::new branch name:__git_branch_names') | |
fi | |
_arguments -w -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[list or delete only remote-tracking branches]" \ | |
"($c $m $d $e: -r)-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 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 which contain the specified commit]: :__git_committishs" \ | |
"($l $m $d $e)--merged=[only list branches which are fully contained by HEAD]: :__git_committishs" \ | |
"($l $m $d $e)--no-merged=[do not list branches which 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]" \ | |
$dependent_modification_args \ | |
"($l $c $m $d $e)"{-d,--delete}"[delete a fully merged branch]" \ | |
"($l $c $m $d $e)-D[delete a branch]" \ | |
{-q,--quiet}"[be more quiet]" \ | |
$dependent_deletion_args | |
} | |
(( $+functions[_git-bundle] )) || | |
_git-bundle () { | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
_arguments -C \ | |
': :->command' \ | |
'*:: :->option-or-argument' && ret=0 | |
case $state in | |
(command) | |
declare -a commands | |
commands=( | |
'create:create a bundle' | |
'verify:check that a bundle is valid and will apply cleanly' | |
'list-heads:list references defined in bundle' | |
'unbundle:unbundle a bundle to repository') | |
_describe -t commands command commands && ret=0 | |
;; | |
(option-or-argument) | |
curcontext=${curcontext%:*}-$line[1]: | |
case $line[1] in | |
(create) | |
if (( CURRENT == 2 )); then | |
_arguments \ | |
':bundle:_files' && ret=0 | |
else | |
local revision_options | |
__git_setup_revision_options | |
_arguments -w -S -s \ | |
$revision_options \ | |
': :_files' \ | |
'*: :__git_commit_ranges2' && ret=0 | |
fi | |
;; | |
(verify) | |
_arguments \ | |
':bundle:_files' && ret=0 | |
;; | |
(list-heads|unbundle) | |
_arguments \ | |
'*: :__git_ref_specs' && ret=0 | |
;; | |
esac | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-check-ignore] )) || | |
_git-check-ignore () { | |
_arguments \ | |
'(-q --quiet)'{-q,--quiet}'[do not output anything, just set exit status]' \ | |
'(-v --verbose)'{-v,--verbose}'[output details about the matching pattern (if any) for each pathname]' \ | |
'--stdin[read file names from stdin instead of from the command-line]' \ | |
'-z[make output format machine-parseable and treat input-paths as NUL-separated with --stdin]' \ | |
'(-n --non-matching)'{-n,--non-matching}'[show given paths which do not match any pattern]' \ | |
'--no-index[do not look in the index when undertaking the checks]' \ | |
'*:: :->file' && ret=0 | |
} | |
(( $+functions[_git-check-mailmap] )) || | |
_git-check-mailmap () { | |
_arguments \ | |
'--stdin[read contacts from stdin after those given on the command line]' | |
} | |
(( $+functions[_git-checkout] )) || | |
_git-checkout () { | |
# TODO: __git_tree_ishs is just stupid. It should be giving us a list of tags | |
# and perhaps also allow all that just with ^{tree} and so on. Not quite sure | |
# how to do that, though. | |
local new_branch_reflog_opt | |
if (( words[(I)-b|-B|--orphan] )); then | |
new_branch_reflog_opt="(--patch)-l[create the new branch's reflog]" | |
fi | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
_arguments -w -C -s \ | |
'(-q --quiet)'{-q,--quiet}'[suppress feedback messages]' \ | |
'(-f --force -m --merge --conflict --patch)'{-f,--force}'[force branch switch/ignore unmerged entries]' \ | |
'(-q --quiet --theirs --patch)--ours[check out stage #2 for unmerged paths]' \ | |
'(-q --quiet --ours --patch)--theirs[check out stage #3 for unmerged paths]' \ | |
'( -B --orphan --ours --theirs --conflict --patch --detach)-b[create a new branch based at given commit]: :__git_branch_names' \ | |
'(-b --orphan --ours --theirs --conflict --patch --detach)-B[create or update branch based at given commit]: :__git_branch_names' \ | |
'(-t --track --orphan --patch --detach)'{-t,--track}'[set up configuration so pull merges from the base commit]' \ | |
'(--patch)--no-track[override the branch.autosetupmerge configuration variable]' \ | |
$new_branch_reflog_opt \ | |
'(-b -B -t --track --patch --orphan)--detach[detach the HEAD at named commit]' \ | |
'(-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)' \ | |
'(-)'{-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 | |
case $state in | |
(branch-or-tree-ish-or-file) | |
# TODO: Something about *:: brings us here when we complete at "-". I | |
# guess that this makes sense in a way, as we might want to treat it as | |
# an argument, but I can't find anything in the documentation about this | |
# behavior. | |
[[ $line[CURRENT] = -* ]] && return | |
if (( CURRENT == 1 )) && [[ -z $opt_args[(I)--] ]]; then | |
# TODO: Allow A...B | |
local branch_arg='branches::__git_revisions' \ | |
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' | |
remote_branch_noprefix_arg= | |
tree_ish_arg= | |
file_arg= | |
elif [[ -n ${opt_args[(I)--ours|--theirs|-m|--conflict|--patch]} ]]; then | |
branch_arg= | |
remote_branch_noprefix_arg= | |
fi | |
_alternative \ | |
$branch_arg \ | |
$remote_branch_noprefix_arg \ | |
$tree_ish_arg \ | |
$file_arg && ret=0 | |
elif [[ -n ${opt_args[(I)-b|-B|-t|--track|--orphan|--detach]} ]]; then | |
_nothing | |
elif [[ -n $line[1] ]] && __git_is_treeish $line[1]; then | |
__git_ignore_line __git_tree_files ${PREFIX:-.} $line[1] && ret=0 | |
else | |
__git_ignore_line __git_modified_files && ret=0 | |
fi | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-cherry-pick] )) || | |
_git-cherry-pick () { | |
_arguments \ | |
'(- :)--quit[end revert or cherry-pick sequence]' \ | |
'(- :)--continue[resume revert or cherry-pick sequence]' \ | |
'(- :)--abort[cancel revert or cherry-pick sequence]' \ | |
'--allow-empty-message[allow replaying a commit with an empty message]' \ | |
'--keep-redundant-commits[keep cherry-picked commits that will become empty]' \ | |
'(-e --edit --ff)'{-e,--edit}'[edit commit before committing the revert]' \ | |
'(--ff)-x[append information about what commit was cherry-picked]' \ | |
'(-m --mainline)'{-m,--mainline}'[specify mainline when cherry-picking a merge commit]:parent number' \ | |
'(-n --no-commit --ff)'{-n,--no-commit}'[do not make the actually commit]' \ | |
'(-s --signoff --ff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \ | |
'*'{-s,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies' \ | |
'*'{-X,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]' \ | |
'(-e --edit -x -n --no-commit -s --signoff)--ff[fast forward, if possible]' \ | |
': :__git_commit_ranges' | |
} | |
(( $+functions[_git-citool] )) || | |
_git-citool () { | |
_nothing | |
} | |
(( $+functions[_git-clean] )) || | |
_git-clean () { | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
_arguments -w -C -S -s \ | |
'-d[also remove untracked directories]' \ | |
'(-f --force)'{-f,--force}'[required when clean.requireForce is true (default)]' \ | |
'(-i --interactive)'{-i,--interactive}'[show what would be done and clean files interactively]' \ | |
'(-n --dry-run)'{-n,--dry-run}'[only show what would and what would not be removed]' \ | |
'(-q --quiet)'{-q,--quiet}'[only report errors]' \ | |
'*'{-e,--exclude=}'[skip files matching specified pattern]:pattern' \ | |
'(-X )-x[also remove ignored files]' \ | |
'( -x)-X[remove only ignored files]' \ | |
'*: :->file' && ret=0 | |
case $state in | |
(file) | |
local exclusion ignored_other_files_alt other_files_alt | |
declare -a exclusions | |
for spec in $opt_args[-e] $opt_args[--exclude]; do | |
integer i | |
for (( i = 1; i <= $#spec; i++ )); do | |
case $spec[i] in | |
(\\) | |
if (( i + 1 <= $#spec )) && [[ $spec[i+1] == : ]]; then | |
(( i++ )) | |
exclusion+=: | |
else | |
exclusion+=$spec[i] | |
fi | |
;; | |
(:) | |
exclusions+=(-x $exclusion) exclusion= | |
;; | |
(*) | |
exclusion+=$spec[i] | |
;; | |
esac | |
done | |
done | |
[[ -n $exclusion ]] && exclusions+=(-x $exclusion) | |
if [[ -n ${opt_args[(I)-x|-X]} ]]; then | |
ignored_other_files_alt="ignored-untracked-files::__git_ignored_other_files $exclusions" | |
fi | |
if [[ -z ${opt_args[(I)-X]} ]]; then | |
other_files_alt="untracked-files::__git_other_files $exclusions" | |
fi | |
_alternative \ | |
$ignored_other_files_alt \ | |
$other_files_alt && ret=0 | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-clone] )) || | |
_git-clone () { | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
# TODO: Argument to -o should be a remote name. | |
# TODO: Argument to -b should complete branch names in the repository being | |
# cloned. | |
_arguments -w -C -S -s \ | |
'(-l --local --no-local)'{-l,--local}'[clone locally, hardlink refs and objects if possible]' \ | |
'(-l --local --no-local)--no-local[override --local, as if file:/// URL was given]' \ | |
'--no-hardlinks[copy files instead of hardlinking when doing a local clone]' \ | |
'(-s --shared)'{-s,--shared}'[share the objects with the source repository (warning: see man page)]' \ | |
'--reference[reference repository]:repository:_directories' \ | |
'(-q --quiet)'{-q,--quiet}'[operate quietly]' \ | |
'(-v --verbose)'{-v,--verbose}'[always display the progressbar]' \ | |
'--progress[output progress even if stderr is not a terminal]' \ | |
'(-n --no-checkout)'{-n,--no-checkout}'[do not checkout HEAD after clone is complete]' \ | |
'(-o --origin)--bare[make a bare GIT repository]' \ | |
'(--bare)--mirror[clone refs into refs/* instead of refs/remotes/origin/*]' \ | |
'(-o --origin --bare)'{-o,--origin}'[use given remote name instead of "origin"]: :__git_guard_branch-name' \ | |
'(-b --branch)'{-b,--branch}'[point HEAD to the given branch]: :__git_guard_branch-name' \ | |
'(-u --upload-pack)'{-u,--upload-pack=}'[specify path to git-upload-pack on remote side]:remote path' \ | |
'--template=[directory to use as a template for the object database]: :_directories' \ | |
'*'{-c,--config}'[<key>=<value> set a configuration variable in the newly created repository]' \ | |
'--depth[create a shallow clone, given number of revisions deep]: :__git_guard_number depth' \ | |
'--single-branch[clone only history leading up to the main branch or the one specified by -b]' \ | |
'--recursive[initialize all contained submodules]' \ | |
': :->repository' \ | |
': :_directories' && ret=0 | |
case $state in | |
(repository) | |
if [[ -n ${opt_args[(I)-l|--local|--no-hardlinks|-s|--shared|--reference]} ]]; then | |
__git_local_repositories && ret=0 | |
else | |
__git_any_repositories && ret=0 | |
fi | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-column] )) || | |
_git-column () { | |
_arguments -w -S -s \ | |
'--command=[look up layout mode using config vars column.<name> and column.ui]' \ | |
'--mode=[specify layout mode. See configuration variable column.ui for option syntax]' \ | |
'--raw-mode=[same as --mode but take mode encoded as a number]' \ | |
'--width=[specify the terminal width]' \ | |
'--indent=[string to be printed at the beginning of each line]' \ | |
'--nl[string to be printed at the end of each line, including newline character]' \ | |
'--padding[the number of spaces between columns. One space by default]' | |
} | |
(( $+functions[_git-commit] )) || | |
_git-commit () { | |
local amend_opt='--amend[amend the tip of the current branch]' | |
if __git_is_initial_commit || __git_is_in_middle_of_merge; then | |
amend_opt= | |
fi | |
local reset_author_opt= | |
if (( words[(I)-C|--reuse-message(=*|)|-c|--reedit-message(=*|)|--amend] )); then | |
reset_author_opt='(--author)--reset-author[make committer the author of the commit]' | |
fi | |
# TODO: --interactive isn't explicitly listed in the documentation. | |
_arguments -w -S -s \ | |
'(-a --all --interactive -o --only -i --include *)'{-a,--all}'[stage all modified and deleted paths]' \ | |
'--fixup=[construct a commit message for use with rebase --autosquash]:' \ | |
'--squash=[construct a commit message for use with rebase --autosquash]:' \ | |
$reset_author_opt \ | |
'( --porcelain --dry-run)--short[output dry run in short format]' \ | |
'(--short --dry-run)--porcelain[output dry run in porcelain-ready format]' \ | |
'(--short --porcelain --dry-run -z --null)'{-z,--null}'[separate dry run entry output with NUL]' \ | |
'--patch[use the interactive patch selection interface to chose which changes to commit]' \ | |
'(--reset-author)--author[override the author name used in the commit]:author name' \ | |
'--date=[override the author date used in the commit]:date' \ | |
'(-s --signoff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \ | |
'(-n --no-verify)'{-n,--no-verify}'[do not look for suspicious lines the commit introduces]' \ | |
'--allow-empty[allow recording an empty commit]' \ | |
'--allow-empty-message[allow recording a commit with an empty message]' \ | |
'--cleanup=[specify how the commit message should be cleaned up]:mode:((verbatim\:"do not change the commit message at all" | |
whitespace\:"remove leading and trailing whitespace lines" | |
strip\:"remove both whitespace and commentary lines" | |
default\:"act as '\''strip'\'' if the message is to be edited and as '\''whitespace'\'' otherwise"))' \ | |
'(-e --edit --no-edit)'{-e,--edit}'[edit the commit message before committing]' \ | |
'(-e --edit --no-edit)--no-edit[do not edit the commit message before committing]' \ | |
'--no-post-rewrite[bypass the post-rewrite hook]' \ | |
'(-a --all --interactive -o --only -i --include)'{-i,--include}'[update the given files and commit the whole index]' \ | |
'(-a --all --interactive -o --only -i --include)'{-o,--only}'[commit only the given files]' \ | |
'(-u --untracked-files)'{-u-,--untracked-files=}'[show files in untracked directories]::mode:((no\:"show no untracked files" | |
normal\:"show untracked files and directories" | |
all\:"show individual files in untracked directories"))' \ | |
'(-q --quiet -v --verbose)'{-v,--verbose}'[show unified diff of all file changes]' \ | |
'(-q --quiet -v --verbose)'{-q,--quiet}'[suppress commit summary message]' \ | |
'--dry-run[only show list of paths that are to be commited or not, and any untracked]' \ | |
'( --no-status)--status[include the output of git status in the commit message template]' \ | |
'(--status )--no-status[do not include the output of git status in the commit message template]' \ | |
'(-S --gpg-sign)'{-S-,--gpg-sign=}'[GPG-sign the commit]::key id' \ | |
'(-a --all --interactive -o --only -i --include *)--interactive[interactively update paths in the index file]' \ | |
'*: :__git_ignore_line_inside_arguments __git_changed_files' \ | |
- '(message)' \ | |
{-C,--reuse-message=}'[use existing commit object with same log message]: :__git_commits' \ | |
{-c,--reedit-message=}'[use existing commit object and edit log message]: :__git_commits' \ | |
{-F,--file=}'[read commit message from given file]: :_files' \ | |
{-m,--message=}'[use the given message as the commit message]:message' \ | |
{-t,--template=}'[use file as a template commit message]:template:_files' \ | |
$amend_opt | |
} | |
(( $+functions[_git-describe] )) || | |
_git-describe () { | |
_arguments -w -S -s \ | |
'(*)--dirty=-[describe HEAD, adding mark if dirty]::mark' \ | |
'--all[use any ref found in "$GIT_DIR/refs/"]' \ | |
'--tags[use any ref found in "$GIT_DIR/refs/tags"]' \ | |
'(--tags)--contains[find the tag after the commit instead of before]' \ | |
'(--long)--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length' \ | |
'( --exact-match)--candidates=[consider up to given number of candidates]: :__git_guard_number "number of candidates"' \ | |
'(--candidates )--exact-match[only output exact matches, same as --candidates=0]' \ | |
'--debug[display information about the searching strategy]' \ | |
'(--abbrev)--long[always show full format, even for exact matches]' \ | |
'--match=[only consider tags matching glob pattern]:pattern' \ | |
'--always[show uniquely abbreviated commit object as fallback]' \ | |
'--first-parent[follow only the first parent of merge commits]' \ | |
'*: :__git_committishs' | |
} | |
(( $+functions[_git-diff] )) || | |
_git-diff () { | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
local -a diff_options | |
__git_setup_diff_options | |
_arguments -w -C -s \ | |
$* \ | |
$diff_options \ | |
'(--cached --staged)'{--cached,--staged}'[show diff between index and named commit]' \ | |
'(-)--[start file arguments]' \ | |
'*:: :->from-to-file' && ret=0 | |
case $state in | |
(from-to-file) | |
# If "--" is part of $opt_args, this means it was specified before any | |
# $words arguments. This means that no heads are specified in front, so | |
# we need to complete *changed* files only. | |
if [[ -n ${opt_args[(I)--]} ]]; then | |
if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then | |
__git_changed-in-index_files && ret=0 | |
else | |
__git_changed-in-working-tree_files && ret=0 | |
fi | |
return ret | |
fi | |
# Otherwise, more complex conditions need to be checked. | |
case $CURRENT in | |
(1) | |
local files_alt='files::__git_changed-in-working-tree_files' | |
if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then | |
files_alt='files::__git_changed-in-index_files' | |
fi | |
_alternative \ | |
'commit-ranges::__git_commit_ranges' \ | |
'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ | |
$files_alt \ | |
'blobs::__git_blobs ' && ret=0 | |
;; | |
(2) | |
# Check if first argument is something special. In case of committish ranges and committishs offer a full list compatible completions. | |
if __git_is_committish_range $line[1]; then | |
# Example: git diff branch1..branch2 <tab> | |
__git_tree_files ${PREFIX:-.} $(__git_committish_range_last $line[1]) && ret=0 | |
elif __git_is_committish $line[1] || __git_is_treeish $line[1]; then | |
# Example: git diff branch1 <tab> | |
_alternative \ | |
'commits::__git_commits' \ | |
'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ | |
'files::__git_tree_files ${PREFIX:-.} HEAD' && ret=0 | |
elif __git_is_blob $line[1]; then | |
_alternative \ | |
'files::__git_cached_files' \ | |
'blobs::__git_blobs' && ret=0 | |
elif [[ -n ${opt_args[(I)--cached|--staged]} ]]; then | |
# Example: git diff --cached file1 <tab> | |
__git_changed-in-index_files && ret=0 | |
else | |
# Example: git diff file1 <tab> | |
__git_changed-in-working-tree_files && ret=0 | |
fi | |
;; | |
(*) | |
if __git_is_committish_range $line[1]; then | |
# Example: git diff branch1..branch2 file1 <tab> | |
__git_tree_files ${PREFIX:-.} $(__git_committish_range_last $line[1]) && ret=0 | |
elif { __git_is_committish $line[1] && __git_is_committish $line[2] } || | |
__git_is_treeish $line[2]; then | |
# Example: git diff branch1 branch2 <tab> | |
__git_tree_files ${PREFIX:-.} $line[2] && ret=0 | |
elif __git_is_committish $line[1] || __git_is_treeish $line[1]; then | |
# Example: git diff branch file1 <tab> | |
# Example: git diff branch -- f<tab> | |
__git_tree_files ${PREFIX:-.} HEAD && ret=0 | |
elif __git_is_blob $line[1] && __git_is_blob $line[2]; then | |
_nothing | |
elif [[ -n ${opt_args[(I)--cached|--staged]} ]]; then | |
# Example: git diff --cached file1 file2 <tab> | |
__git_changed-in-index_files && ret=0 | |
else | |
# Example: git diff file1 file2 <tab> | |
__git_changed-in-working-tree_files && ret=0 | |
fi | |
;; | |
esac | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-fetch] )) || | |
_git-fetch () { | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
local -a fetch_options | |
__git_setup_fetch_options | |
_arguments -w -C -S -s \ | |
$fetch_options \ | |
'--multiple[allow several repository arguments]' \ | |
'*:: :->repository-or-group-or-refspec' && ret=0 | |
case $state in | |
(repository-or-group-or-refspec) | |
if (( CURRENT > 1 )) && [[ -z ${opt_args[(I)--multiple]} ]]; then | |
__git_ref_specs && ret=0 | |
else | |
_alternative \ | |
'remotes::__git_remotes' \ | |
'remotes-groups::__git_remotes_groups' \ | |
'local-repositories::__git_local_repositories' \ | |
'remote-repositories::__git_remote_repositories' && ret=0 | |
fi | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-format-patch] )) || | |
_git-format-patch () { | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
local -a diff_options | |
__git_setup_diff_options | |
# TODO: -- is wrong. | |
# TODO: Should filter out --name-only, --name-status, and --check from | |
# $diff_options. | |
_arguments -w -C -S -s \ | |
$diff_options \ | |
'--[limit the number of patches to prepare]: :__git_guard_number "number of patches to prepare"' \ | |
'(-o --output-directory --stdout)'{-o,--output-directory}'[store resulting files in given directory]: :_directories' \ | |
'(-n --numbered -N --no-numbered -k --keep-subject)'{-n,--numbered}'[name output in \[PATCH n/m\] format]' \ | |
'(-n --numbered -N --no-numbered -k --keep-subject)'{-N,--no-numbered}'[name output in \[PATCH\] format]' \ | |
'--start-number=[start numbering patches at given number]: :__git_guard_number "patch number"' \ | |
'--numbered-files[use only number for file name]' \ | |
'(-n --numbered -N --no-numbered -k --keep-subject --subject-prefix)'{-k,--keep-subject}'[do not strip/add \[PATCH\] from the first line of the commit message]' \ | |
'(-s --signoff)'{-s,--signoff}'[add Signed-off-by: line to the commit message]' \ | |
'(-o --output-directory)--stdout[output the generated mbox on standard output (implies --mbox)]' \ | |
'( --no-attach --inline)--attach=-[create attachments instead of inlining patches]::boundary' \ | |
'(--attach --inline)--no-attach[disable creation of attachments]' \ | |
'(--attach --no-attach )--inline=-[inline patches]::boundary' \ | |
'( --no-thread)--thread=-[make the second and subsequent mails refer to the first]::style:((shallow\:"all refer to the first" | |
deep\:"each refers to the previous"))' \ | |
'(--thread )--no-thread[do not thread messages]' \ | |
'--in-reply-to=[make the first mail a reply to the given message]:message id' \ | |
'--ignore-if-in-upstream[do not include a patch that matches a commit in the given range]' \ | |
'(-v --reroll-count)'{-v,--reroll-count=}'[mark the series as the <n>-th iteration of the topic]: :__git_guard_number iteration' \ | |
'(-k --keep-subject)--subject-prefix=[use the given prefix instead of \[PATCH\]]:prefix' \ | |
'*--to=[add To: header to email headers]: :_email_addresses' \ | |
'*--cc=[add Cc: header to email headers]: :_email_addresses' \ | |
'--from=[add From: header to email headers]: :_email_addresses' \ | |
'*--add-header=[add an arbitrary header to email headers]:header' \ | |
'--cover-letter[generate a cover letter template]' \ | |
'--notes=[append notes for the commit after the three-dash line]:: :__git_notes_refs' \ | |
'( --no-signature)--signature=[add a signature]:signature' \ | |
'(--signature )--no-signature[do not add a signature]' \ | |
'--suffix=[use the given suffix for filenames]:filename suffix' \ | |
'--quiet[suppress the output of the names of generated files]' \ | |
'--no-binary[do not output contents of changes in binary files, only note that they differ]' \ | |
'--root[treat the revision argument as a range]' \ | |
': :->commit-or-commit-range' && ret=0 | |
case $state in | |
(commit-or-commit-range) | |
if [[ -n ${opt_args[(I)--root]} ]]; then | |
__git_commits && ret=0 | |
else | |
__git_commit_ranges && ret=0 | |
fi | |
;; | |
esac | |
return ret | |
} | |
(( $+functions[_git-gc] )) || | |
_git-gc () { | |
_arguments -w -S -s \ | |
'--aggressive[more aggressively optimize]' \ | |
'--auto[check whether housekeeping is required]' \ | |
'( --no-prune)--prune=[prune loose objects older than given date]: :__git_datetimes' \ | |
'(--prune )--no-prune[do not prune any loose objects]' \ | |
'--quiet[suppress all progress reports]' | |
} | |
(( $+functions[_git-grep] )) || | |
_git-grep () { | |
local -a pattern_operators | |
# TODO: Need to deal with grouping with ( and ) | |
if (( words[(I)-e] == CURRENT - 2 )); then | |
pattern_operators=( | |
'--and[both patterns must match]' | |
'--or[either pattern must match]' | |
'--not[the following pattern must not match]') | |
fi | |
local curcontext=$curcontext state line ret=1 | |
declare -A opt_args | |
# 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]' \ | |
'(--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]' \ | |
'(-a --text)'{-a,--text}'[process binary files as if they were text]' \ | |
'(--textconv --no-textconv)--textconv[honor textconv filter settings]' \ | |
'(--textconv --no-textconv)--no-textconv[do not honor textconv filter settings]' \ | |
'(-i --ignore-case)'{-i,--ignore-case}'[ignore case when matching]' \ | |
'-I[do not match pattern in binary files]' \ | |
'--max-depth=[descend at most given levels of directories]: :__git_guard_number depth' \ | |
'(-w --word-regexp)'{-w,--word-regexp}'[match only whole words]' \ | |
'(-v --invert-match)'{-v,--invert-match}'[select non-matching lines]' \ | |
'( -H)-h[supress output of filenames]' \ | |
'(-h )-H[show filenames]' \ | |
'--full-name[output paths relative to the project top directory]' \ | |
'(-E --extended-regexp -G --basic-regexp -P --perl-regexp -F --fixed-strings)'{-E,--extended-regexp}'[use POSIX extended regexes]' \ | |
'(-E --extended-regexp -G --basic-regexp -P --perl-regexp -F --fixed-strings)'{-G,--basic-regexp}'[use POSIX basic regexes]' \ | |
'(-E --extended-regexp -G --basic-regexp -P --perl-regexp -F --fixed-strings)'{-P,--perl-regexp}'[use perl-compatible regexes]' \ | |
'(-E --extended-regexp -G --basic-regexp -P --perl-regexp -F --fixed-strings)'{-F,--fixed-strings}'[do not interpret pattern as a regex]' \ | |
'(-n --line-number)'{-n,--line-number}'[prefix the line number to matching lines]' \ | |
'(-l --files-with-matches -L --files-without-match --name-only)'{-l,--files-with-matches,--name-only}'[show only names of matching files]' \ | |
'(-l --files-with-matches -L --files-without-match)'{-L,--files-without-match}'[show only names of non-matching files]' \ | |
'(--cached -O --open-files-in-pager)'{-O,--open-files-in-pager}'=-[open matching files in pager]::_path_commands' \ | |
'(-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]' \ | |
'--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' \ | |
'(-B --before-context)'{-B,--before-context=}'[show <num> leading lines, and separate groups of matches]: :__git_guard_number lines' \ | |
'(-A --after-context -B --before-context -C --context)'{-C,--context=}'[show <num> leading and trailing lines, and separate groups of matches]: :__git_guard_number lines' \ | |
'(-p --show-function)'{-p,--show-function}'[show preceding line containing function name of match]' \ | |
'(-W --function-context)'{-W,--function-context}'[show whole function where a match was found]' \ | |
'(1)*-f[read patterns from given file]:pattern file:_files' \ | |
'(1)*-e[use the given pattern for matching]:pattern' \ | |
$pattern_operators \ | |
'--all-match[all patterns must match]' \ | |
':pattern' \ | |
'*:: :->tree-or-file' && ret=0 | |
# TODO: If --cached, --no-index, -O, or --open-files-in-pager was given, | |
# don't complete treeishs. | |
case $state in | |
(tree-or-file) | |
integer first_tree last_tree start end | |
(( start = words[(I)(-f|-e)] > 0 ? 1 : 2 )) | |
(( end = $#line - 1 )) | |
for (( i = start; i <= end; i++ )); do | |
[[ line[i] == '--' ]] && break | |
__git_is_treeish $line[i] || break | |
if (( first_tree == 0 )); then | |
(( first_tree = last_tree = i )) | |
else | |
(( last_tree = i )) | |
fi | |
done | |
# TODO: Need to respect --cached and --no-index here. | |
if (( last_tree == 0 || last_tree == end )); then | |
if (( first_tree == 0 )); then | |
_alternative \ | |
'treeishs::__git_tree_ishs' \ | |
'files::__git_cached_files' && ret=0 | |
else | |
_alternative \ | |
'treeishs::__git_trees' \ | |
"files::__git_tree_files ${PREFIX:-.} $line[first_tree,last_tree]" && ret=0 | |
fi | |
else | |
if (( first_tree == 0 )); then | |
__git_cached_files && ret=0 | |
else | |
__git_tree_files ${PREFIX:-.} $line[first_tree,last_tree] && ret=0 | |
fi | |
fi | |
;; | |
esac |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
autoload -U compinit | |
compinit -i -d "${HOME}/.zcompdump" | |
export rvmsudo_secure_path=1 | |
if [[ -s "$HOME/.rvm/scripts/rvm" ]]; then | |
source "$HOME/.rvm/scripts/rvm" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment