Last active
December 22, 2015 01:58
-
-
Save billcotter/6399538 to your computer and use it in GitHub Desktop.
bash completion support for core 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
#!bash | |
# | |
# bash 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 | |
# *) common --long-options | |
# | |
# To use these routines: | |
# | |
# 1) Copy this file to somewhere (e.g. ~/.git-completion.sh). | |
# 2) Added the following line to your .bashrc: | |
# source ~/.git-completion.sh | |
# | |
# Or, add the following lines to your .zshrc: | |
# autoload bashcompinit | |
# bashcompinit | |
# source ~/.git-completion.sh | |
# | |
# 3) Consider changing your PS1 to also show the current branch: | |
# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' | |
# | |
# The argument to __git_ps1 will be displayed only if you | |
# are currently in a git repository. The %s token will be | |
# the name of the current branch. | |
# | |
# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty | |
# value, unstaged (*) and staged (+) changes will be shown next | |
# to the branch name. You can configure this per-repository | |
# with the bash.showDirtyState variable, which defaults to true | |
# once GIT_PS1_SHOWDIRTYSTATE is enabled. | |
# | |
# You can also see if currently something is stashed, by setting | |
# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, | |
# then a '$' will be shown next to the branch name. | |
# | |
# If you would like to see if there're untracked files, then you can | |
# set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're | |
# untracked files, then a '%' will be shown next to the branch name. | |
# | |
# If you would like to see the difference between HEAD and its | |
# upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates | |
# you are behind, ">" indicates you are ahead, and "<>" | |
# indicates you have diverged. You can further control | |
# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated | |
# list of values: | |
# verbose show number of commits ahead/behind (+/-) upstream | |
# legacy don't use the '--count' option available in recent | |
# versions of git-rev-list | |
# git always compare HEAD to @{upstream} | |
# svn always compare HEAD to your SVN upstream | |
# By default, __git_ps1 will compare HEAD to your SVN upstream | |
# if it can find one, or @{upstream} otherwise. Once you have | |
# set GIT_PS1_SHOWUPSTREAM, you can override it on a | |
# per-repository basis by setting the bash.showUpstream config | |
# variable. | |
# | |
# | |
# To submit patches: | |
# | |
# *) Read Documentation/SubmittingPatches | |
# *) Send all patches to the current maintainer: | |
# | |
# "Shawn O. Pearce" <[email protected]> | |
# | |
# *) Always CC the Git mailing list: | |
# | |
# [email protected] | |
# | |
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 [ -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 | |
} | |
# stores the divergence from upstream in $p | |
# used by GIT_PS1_SHOWUPSTREAM | |
__git_ps1_show_upstream () | |
{ | |
local key value | |
local svn_remote=() svn_url_pattern count n | |
local upstream=git legacy="" verbose="" | |
# get some config options from git-config | |
while read key value; do | |
case "$key" in | |
bash.showupstream) | |
GIT_PS1_SHOWUPSTREAM="$value" | |
if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then | |
p="" | |
return | |
fi | |
;; | |
svn-remote.*.url) | |
svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value" | |
svn_url_pattern+="\\|$value" | |
upstream=svn+git # default upstream is SVN if available, else git | |
;; | |
esac | |
done < <(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ') | |
# parse configuration values | |
for option in ${GIT_PS1_SHOWUPSTREAM}; do | |
case "$option" in | |
git|svn) upstream="$option" ;; | |
verbose) verbose=1 ;; | |
legacy) legacy=1 ;; | |
esac | |
done | |
# Find our upstream | |
case "$upstream" in | |
git) upstream="@{upstream}" ;; | |
svn*) | |
# get the upstream from the "git-svn-id: ..." in a commit message | |
# (git-svn uses essentially the same procedure internally) | |
local svn_upstream=($(git log --first-parent -1 \ | |
--grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null)) | |
if [[ 0 -ne ${#svn_upstream[@]} ]]; then | |
svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} | |
svn_upstream=${svn_upstream%@*} | |
local n_stop="${#svn_remote[@]}" | |
for ((n=1; n <= n_stop; ++n)); do | |
svn_upstream=${svn_upstream#${svn_remote[$n]}} | |
done | |
if [[ -z "$svn_upstream" ]]; then | |
# default branch name for checkouts with no layout: | |
upstream=${GIT_SVN_ID:-git-svn} | |
else | |
upstream=${svn_upstream#/} | |
fi | |
elif [[ "svn+git" = "$upstream" ]]; then | |
upstream="@{upstream}" | |
fi | |
;; | |
esac | |
# Find how many commits we are ahead/behind our upstream | |
if [[ -z "$legacy" ]]; then | |
count="$(git rev-list --count --left-right \ | |
"$upstream"...HEAD 2>/dev/null)" | |
else | |
# produce equivalent output to --count for older versions of git | |
local commits | |
if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" | |
then | |
local commit behind=0 ahead=0 | |
for commit in $commits | |
do | |
case "$commit" in | |
"<"*) let ++behind | |
;; | |
*) let ++ahead | |
;; | |
esac | |
done | |
count="$behind $ahead" | |
else | |
count="" | |
fi | |
fi | |
# calculate the result | |
if [[ -z "$verbose" ]]; then | |
case "$count" in | |
"") # no upstream | |
p="" ;; | |
"0 0") # equal to upstream | |
p="=" ;; | |
"0 "*) # ahead of upstream | |
p=">" ;; | |
*" 0") # behind upstream | |
p="<" ;; | |
*) # diverged from upstream | |
p="<>" ;; | |
esac | |
else | |
case "$count" in | |
"") # no upstream | |
p="" ;; | |
"0 0") # equal to upstream | |
p=" u=" ;; | |
"0 "*) # ahead of upstream | |
p=" u+${count#0 }" ;; | |
*" 0") # behind upstream | |
p=" u-${count% 0}" ;; | |
*) # diverged from upstream | |
p=" u+${count#* }-${count% *}" ;; | |
esac | |
fi | |
} | |
# __git_ps1 accepts 0 or 1 arguments (i.e., format string) | |
# returns text to add to bash PS1 prompt (includes branch name) | |
__git_ps1 () | |
{ | |
local g="$(__gitdir)" | |
if [ -n "$g" ]; then | |
local r="" | |
local b="" | |
if [ -f "$g/rebase-merge/interactive" ]; then | |
r="|REBASE-i" | |
b="$(cat "$g/rebase-merge/head-name")" | |
elif [ -d "$g/rebase-merge" ]; then | |
r="|REBASE-m" | |
b="$(cat "$g/rebase-merge/head-name")" | |
else | |
if [ -d "$g/rebase-apply" ]; then | |
if [ -f "$g/rebase-apply/rebasing" ]; then | |
r="|REBASE" | |
elif [ -f "$g/rebase-apply/applying" ]; then | |
r="|AM" | |
else | |
r="|AM/REBASE" | |
fi | |
elif [ -f "$g/MERGE_HEAD" ]; then | |
r="|MERGING" | |
elif [ -f "$g/BISECT_LOG" ]; then | |
r="|BISECTING" | |
fi | |
b="$(git symbolic-ref HEAD 2>/dev/null)" || { | |
b="$( | |
case "${GIT_PS1_DESCRIBE_STYLE-}" in | |
(contains) | |
git describe --contains HEAD ;; | |
(branch) | |
git describe --contains --all HEAD ;; | |
(describe) | |
git describe HEAD ;; | |
(* | default) | |
git describe --tags --exact-match HEAD ;; | |
esac 2>/dev/null)" || | |
b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || | |
b="unknown" | |
b="($b)" | |
} | |
fi | |
local w="" | |
local i="" | |
local s="" | |
local u="" | |
local c="" | |
local p="" | |
if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then | |
if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then | |
c="BARE:" | |
else | |
b="GIT_DIR!" | |
fi | |
elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then | |
if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then | |
if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then | |
git diff --no-ext-diff --quiet --exit-code || w="*" | |
if git rev-parse --quiet --verify HEAD >/dev/null; then | |
git diff-index --cached --quiet HEAD -- || i="+" | |
else | |
i="#" | |
fi | |
fi | |
fi | |
if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then | |
git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" | |
fi | |
if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then | |
if [ -n "$(git ls-files --others --exclude-standard)" ]; then | |
u="%" | |
fi | |
fi | |
if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then | |
__git_ps1_show_upstream | |
fi | |
fi | |
local f="$w$i$s$u" | |
printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" | |
fi | |
} | |
# __gitcomp_1 requires 2 arguments | |
__gitcomp_1 () | |
{ | |
local c IFS=' '$'\t'$'\n' | |
for c in $1; do | |
case "$c$2" in | |
--*=*) printf %s$'\n' "$c$2" ;; | |
*.) printf %s$'\n' "$c$2" ;; | |
*) printf %s$'\n' "$c$2 " ;; | |
esac | |
done | |
} | |
# 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 | |
if [[ -z ${ZSH_VERSION:+set} ]]; 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 | |
} | |
else | |
_get_comp_words_by_ref () | |
{ | |
while [ $# -gt 0 ]; do | |
case "$1" in | |
cur) | |
cur=${COMP_WORDS[COMP_CWORD]} | |
;; | |
prev) | |
prev=${COMP_WORDS[COMP_CWORD-1]} | |
;; | |
words) | |
words=("${COMP_WORDS[@]}") | |
;; | |
cword) | |
cword=$COMP_CWORD | |
;; | |
-n) | |
# assume COMP_WORDBREAKS is already set sanely | |
shift | |
;; | |
esac | |
shift | |
done | |
} | |
fi | |
fi | |
# __gitcomp accepts 1, 2, 3, or 4 arguments | |
# generates completion reply with compgen | |
__gitcomp () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
if [ $# -gt 2 ]; then | |
cur="$3" | |
fi | |
case "$cur" in | |
--*=) | |
COMPREPLY=() | |
;; | |
*) | |
local IFS=$'\n' | |
COMPREPLY=($(compgen -P "${2-}" \ | |
-W "$(__gitcomp_1 "${1-}" "${4-}")" \ | |
-- "$cur")) | |
;; | |
esac | |
} | |
# __git_heads accepts 0 or 1 arguments (to pass to __gitdir) | |
__git_heads () | |
{ | |
local cmd i is_hash=y dir="$(__gitdir "${1-}")" | |
if [ -d "$dir" ]; then | |
git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ | |
refs/heads | |
return | |
fi | |
for i in $(git ls-remote "${1-}" 2>/dev/null); do | |
case "$is_hash,$i" in | |
y,*) is_hash=n ;; | |
n,*^{}) is_hash=y ;; | |
n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; | |
n,*) is_hash=y; echo "$i" ;; | |
esac | |
done | |
} | |
# __git_tags accepts 0 or 1 arguments (to pass to __gitdir) | |
__git_tags () | |
{ | |
local cmd i is_hash=y dir="$(__gitdir "${1-}")" | |
if [ -d "$dir" ]; then | |
git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ | |
refs/tags | |
return | |
fi | |
for i in $(git ls-remote "${1-}" 2>/dev/null); do | |
case "$is_hash,$i" in | |
y,*) is_hash=n ;; | |
n,*^{}) is_hash=y ;; | |
n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;; | |
n,*) is_hash=y; echo "$i" ;; | |
esac | |
done | |
} | |
# __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 is_hash=y dir="$(__gitdir "${1-}")" track="${2-}" | |
local cur format refs | |
_get_comp_words_by_ref -n =: cur | |
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 entry; do | |
eval "$entry" | |
ref="${ref#*/}" | |
if [[ "$ref" == "$cur"* ]]; then | |
echo "$ref" | |
fi | |
done | uniq -u | |
fi | |
return | |
fi | |
for i in $(git ls-remote "$dir" 2>/dev/null); do | |
case "$is_hash,$i" in | |
y,*) is_hash=n ;; | |
n,*^{}) is_hash=y ;; | |
n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;; | |
n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; | |
n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;; | |
n,*) is_hash=y; echo "$i" ;; | |
esac | |
done | |
} | |
# __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 cmd i is_hash=y | |
for i in $(git ls-remote "$1" 2>/dev/null); do | |
case "$is_hash,$i" in | |
n,refs/heads/*) | |
is_hash=y | |
echo "$i:refs/remotes/$1/${i#refs/heads/}" | |
;; | |
y,*) is_hash=n ;; | |
n,*^{}) is_hash=y ;; | |
n,refs/tags/*) is_hash=y;; | |
n,*) is_hash=y; ;; | |
esac | |
done | |
} | |
__git_remotes () | |
{ | |
local i ngoff IFS=$'\n' d="$(__gitdir)" | |
shopt -q nullglob || ngoff=1 | |
shopt -s nullglob | |
for i in "$d/remotes"/*; do | |
echo ${i#$d/remotes/} | |
done | |
[ "$ngoff" ] && shopt -u nullglob | |
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 () | |
{ | |
: ${__git_merge_strategies:=$(__git_list_merge_strategies)} | |
} | |
__git_complete_file () | |
{ | |
local pfx ls ref cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
?*:*) | |
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 | |
local IFS=$'\n' | |
COMPREPLY=($(compgen -P "$pfx" \ | |
-W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \ | |
| sed '/^100... blob /{ | |
s,^.* ,, | |
s,$, , | |
} | |
/^120000 blob /{ | |
s,^.* ,, | |
s,$, , | |
} | |
/^040000 tree /{ | |
s,^.* ,, | |
s,$,/, | |
} | |
s/^.* //')" \ | |
-- "$cur")) | |
;; | |
*) | |
__gitcomp "$(__git_refs)" | |
;; | |
esac | |
} | |
__git_complete_revlist () | |
{ | |
local pfx cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
*...*) | |
pfx="${cur%...*}..." | |
cur="${cur#*...}" | |
__gitcomp "$(__git_refs)" "$pfx" "$cur" | |
;; | |
*..*) | |
pfx="${cur%..*}.." | |
cur="${cur#*..}" | |
__gitcomp "$(__git_refs)" "$pfx" "$cur" | |
;; | |
*) | |
__gitcomp "$(__git_refs)" | |
;; | |
esac | |
} | |
__git_complete_remote_or_refspec () | |
{ | |
local cur words cword | |
_get_comp_words_by_ref -n =: cur words cword | |
local cmd="${words[1]}" | |
local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0 | |
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) | |
COMPREPLY=() | |
return | |
;; | |
*) ;; | |
esac | |
;; | |
-*) ;; | |
*) remote="$i"; break ;; | |
esac | |
c=$((++c)) | |
done | |
if [ -z "$remote" ]; then | |
__gitcomp "$(__git_remotes)" | |
return | |
fi | |
if [ $no_complete_refspec = 1 ]; then | |
COMPREPLY=() | |
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 "$(__git_refs2 "$remote")" "$pfx" "$cur" | |
else | |
__gitcomp "$(__git_refs)" "$pfx" "$cur" | |
fi | |
;; | |
pull) | |
if [ $lhs = 1 ]; then | |
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur" | |
else | |
__gitcomp "$(__git_refs)" "$pfx" "$cur" | |
fi | |
;; | |
push) | |
if [ $lhs = 1 ]; then | |
__gitcomp "$(__git_refs)" "$pfx" "$cur" | |
else | |
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur" | |
fi | |
;; | |
esac | |
} | |
__git_complete_strategy () | |
{ | |
local cur prev | |
_get_comp_words_by_ref -n =: cur prev | |
__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_list_all_commands () | |
{ | |
local i IFS=" "$'\n' | |
for i in $(git help -a|egrep '^ [a-zA-Z0-9]') | |
do | |
case $i in | |
*--*) : helper pattern;; | |
*) echo $i;; | |
esac | |
done | |
} | |
__git_all_commands= | |
__git_compute_all_commands () | |
{ | |
: ${__git_all_commands:=$(__git_list_all_commands)} | |
} | |
__git_list_porcelain_commands () | |
{ | |
local i IFS=" "$'\n' | |
__git_compute_all_commands | |
for i in "help" $__git_all_commands | |
do | |
case $i in | |
*--*) : helper pattern;; | |
applymbox) : ask gittus;; | |
applypatch) : ask gittus;; | |
archimport) : import;; | |
cat-file) : plumbing;; | |
check-attr) : plumbing;; | |
check-ref-format) : plumbing;; | |
checkout-index) : plumbing;; | |
commit-tree) : plumbing;; | |
count-objects) : infrequent;; | |
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;; | |
lost-found) : infrequent;; | |
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;; | |
peek-remote) : plumbing;; | |
prune) : plumbing;; | |
prune-packed) : plumbing;; | |
quiltimport) : import;; | |
read-tree) : plumbing;; | |
receive-pack) : plumbing;; | |
remote-*) : transport;; | |
repo-config) : deprecated;; | |
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;; | |
tar-tree) : deprecated;; | |
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 | |
: ${__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 ;; | |
*) | |
echo "$word" | |
return | |
esac | |
done | |
} | |
# __git_find_on_cmdline requires 1 argument | |
__git_find_on_cmdline () | |
{ | |
local word subcommand c=1 words cword | |
_get_comp_words_by_ref -n =: words cword | |
while [ $c -lt $cword ]; do | |
word="${words[c]}" | |
for subcommand in $1; do | |
if [ "$subcommand" = "$word" ]; then | |
echo "$subcommand" | |
return | |
fi | |
done | |
c=$((++c)) | |
done | |
} | |
__git_has_doubledash () | |
{ | |
local c=1 words cword | |
_get_comp_words_by_ref -n =: words cword | |
while [ $c -lt $cword ]; do | |
if [ "--" = "${words[c]}" ]; then | |
return 0 | |
fi | |
c=$((++c)) | |
done | |
return 1 | |
} | |
__git_whitespacelist="nowarn warn error error-all fix" | |
_git_am () | |
{ | |
local cur dir="$(__gitdir)" | |
_get_comp_words_by_ref -n =: cur | |
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 | |
COMPREPLY=() | |
} | |
_git_apply () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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 | |
COMPREPLY=() | |
} | |
_git_add () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--interactive --refresh --patch --update --dry-run | |
--ignore-errors --intent-to-add | |
" | |
return | |
esac | |
COMPREPLY=() | |
} | |
_git_archive () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--format=*) | |
__gitcomp "$(git archive --list)" "" "${cur##--format=}" | |
return | |
;; | |
--remote=*) | |
__gitcomp "$(__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 "$(__git_refs)" | |
;; | |
*) | |
COMPREPLY=() | |
;; | |
esac | |
} | |
_git_branch () | |
{ | |
local i c=1 only_local_ref="n" has_r="n" cur words cword | |
_get_comp_words_by_ref -n =: cur words cword | |
while [ $c -lt $cword ]; do | |
i="${words[c]}" | |
case "$i" in | |
-d|-m) only_local_ref="y" ;; | |
-r) has_r="y" ;; | |
esac | |
c=$((++c)) | |
done | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--color --no-color --verbose --abbrev= --no-abbrev | |
--track --no-track --contains --merged --no-merged | |
--set-upstream | |
" | |
;; | |
*) | |
if [ $only_local_ref = "y" -a $has_r = "n" ]; then | |
__gitcomp "$(__git_heads)" | |
else | |
__gitcomp "$(__git_refs)" | |
fi | |
;; | |
esac | |
} | |
_git_bundle () | |
{ | |
local words cword | |
_get_comp_words_by_ref -n =: words cword | |
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 | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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 "$(__git_refs '' $track)" | |
;; | |
esac | |
} | |
_git_cherry () | |
{ | |
__gitcomp "$(__git_refs)" | |
} | |
_git_cherry_pick () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--edit --no-commit" | |
;; | |
*) | |
__gitcomp "$(__git_refs)" | |
;; | |
esac | |
} | |
_git_clean () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--dry-run --quiet" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_git_clone () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--local | |
--no-hardlinks | |
--shared | |
--reference | |
--quiet | |
--no-checkout | |
--bare | |
--mirror | |
--origin | |
--upload-pack | |
--template= | |
--depth | |
" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_git_commit () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--cleanup=*) | |
__gitcomp "default strip verbatim whitespace | |
" "" "${cur##--cleanup=}" | |
return | |
;; | |
--reuse-message=*) | |
__gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}" | |
return | |
;; | |
--reedit-message=*) | |
__gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}" | |
return | |
;; | |
--untracked-files=*) | |
__gitcomp "all no normal" "" "${cur##--untracked-files=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--all --author= --signoff --verify --no-verify | |
--edit --amend --include --only --interactive | |
--dry-run --reuse-message= --reedit-message= | |
--reset-author --file= --message= --template= | |
--cleanup= --untracked-files --untracked-files= | |
--verbose --quiet | |
" | |
return | |
esac | |
COMPREPLY=() | |
} | |
_git_describe () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--all --tags --contains --abbrev= --candidates= | |
--exact-match --debug --long --match --always | |
" | |
return | |
esac | |
__gitcomp "$(__git_refs)" | |
} | |
__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 | |
--raw | |
--dirstat --dirstat= --dirstat-by-file | |
--dirstat-by-file= --cumulative | |
" | |
_git_diff () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex | |
--base --ours --theirs --no-index | |
$__git_diff_common_options | |
" | |
return | |
;; | |
esac | |
__git_complete_file | |
} | |
__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff | |
tkdiff vimdiff gvimdiff xxdiff araxis p4merge | |
" | |
_git_difftool () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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_file | |
} | |
__git_fetch_options=" | |
--quiet --verbose --append --upload-pack --force --keep --depth= | |
--tags --no-tags --all --prune --dry-run | |
" | |
_git_fetch () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "$__git_fetch_options" | |
return | |
;; | |
esac | |
__git_complete_remote_or_refspec | |
} | |
_git_format_patch () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--thread=*) | |
__gitcomp " | |
deep shallow | |
" "" "${cur##--thread=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--stdout --attach --no-attach --thread --thread= | |
--output-directory | |
--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= | |
" | |
return | |
;; | |
esac | |
__git_complete_revlist | |
} | |
_git_fsck () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--tags --root --unreachable --cache --no-reflogs --full | |
--strict --verbose --lost-found | |
" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_git_gc () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--prune --aggressive" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_git_gitk () | |
{ | |
_gitk | |
} | |
_git_grep () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--cached | |
--text --ignore-case --word-regexp --invert-match | |
--full-name | |
--extended-regexp --basic-regexp --fixed-strings | |
--files-with-matches --name-only | |
--files-without-match | |
--max-depth | |
--count | |
--and --or --not --all-match | |
" | |
return | |
;; | |
esac | |
__gitcomp "$(__git_refs)" | |
} | |
_git_help () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--all --info --man --web" | |
return | |
;; | |
esac | |
__git_compute_all_commands | |
__gitcomp "$__git_all_commands | |
attributes cli core-tutorial cvs-migration | |
diffcore gitk glossary hooks ignore modules | |
repository-layout tutorial tutorial-2 | |
workflows | |
" | |
} | |
_git_init () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--shared=*) | |
__gitcomp " | |
false true umask group all world everybody | |
" "" "${cur##--shared=}" | |
return | |
;; | |
--*) | |
__gitcomp "--quiet --bare --template= --shared --shared=" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_git_ls_files () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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 | |
COMPREPLY=() | |
} | |
_git_ls_remote () | |
{ | |
__gitcomp "$(__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= | |
" | |
# 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 | |
" | |
# 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 | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--pretty=*) | |
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases) | |
" "" "${cur##--pretty=}" | |
return | |
;; | |
--format=*) | |
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases) | |
" "" "${cur##--format=}" | |
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 | |
} | |
__git_merge_options=" | |
--no-commit --no-stat --log --no-log --squash --strategy | |
--commit --stat --no-squash --ff --no-ff --ff-only | |
" | |
_git_merge () | |
{ | |
__git_complete_strategy && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "$__git_merge_options" | |
return | |
esac | |
__gitcomp "$(__git_refs)" | |
} | |
_git_mergetool () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--tool=*) | |
__gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}" | |
return | |
;; | |
--*) | |
__gitcomp "--tool=" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_git_merge_base () | |
{ | |
__gitcomp "$(__git_refs)" | |
} | |
_git_mv () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--dry-run" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_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")" | |
local cur words cword | |
_get_comp_words_by_ref -n =: cur words cword | |
case "$subcommand,$cur" in | |
,--*) | |
__gitcomp '--ref' | |
;; | |
,*) | |
case "${words[cword-1]}" in | |
--ref) | |
__gitcomp "$(__git_refs)" | |
;; | |
*) | |
__gitcomp "$subcommands --ref" | |
;; | |
esac | |
;; | |
add,--reuse-message=*|append,--reuse-message=*) | |
__gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}" | |
;; | |
add,--reedit-message=*|append,--reedit-message=*) | |
__gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}" | |
;; | |
add,--*|append,--*) | |
__gitcomp '--file= --message= --reedit-message= | |
--reuse-message=' | |
;; | |
copy,--*) | |
__gitcomp '--stdin' | |
;; | |
prune,--*) | |
__gitcomp '--dry-run --verbose' | |
;; | |
prune,*) | |
;; | |
*) | |
case "${words[cword-1]}" in | |
-m|-F) | |
;; | |
*) | |
__gitcomp "$(__git_refs)" | |
;; | |
esac | |
;; | |
esac | |
} | |
_git_pull () | |
{ | |
__git_complete_strategy && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--rebase --no-rebase | |
$__git_merge_options | |
$__git_fetch_options | |
" | |
return | |
;; | |
esac | |
__git_complete_remote_or_refspec | |
} | |
_git_push () | |
{ | |
local cur prev | |
_get_comp_words_by_ref -n =: cur prev | |
case "$prev" in | |
--repo) | |
__gitcomp "$(__git_remotes)" | |
return | |
esac | |
case "$cur" in | |
--repo=*) | |
__gitcomp "$(__git_remotes)" "" "${cur##--repo=}" | |
return | |
;; | |
--*) | |
__gitcomp " | |
--all --mirror --tags --dry-run --force --verbose | |
--receive-pack= --repo= | |
" | |
return | |
;; | |
esac | |
__git_complete_remote_or_refspec | |
} | |
_git_rebase () | |
{ | |
local dir="$(__gitdir)" | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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 | |
" | |
return | |
esac | |
__gitcomp "$(__git_refs)" | |
} | |
_git_reflog () | |
{ | |
local subcommands="show delete expire" | |
local subcommand="$(__git_find_on_cmdline "$subcommands")" | |
if [ -z "$subcommand" ]; then | |
__gitcomp "$subcommands" | |
else | |
__gitcomp "$(__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 () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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 | |
;; | |
--*) | |
__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" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_git_stage () | |
{ | |
_git_add | |
} | |
__git_config_get_set_variables () | |
{ | |
local words cword | |
_get_comp_words_by_ref -n =: words cword | |
local prevword word config_file= c=$cword | |
while [ $c -gt 1 ]; do | |
word="${words[c]}" | |
case "$word" in | |
--global|--system|--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 line | |
do | |
case "$line" in | |
*.*=*) | |
echo "${line/=*/}" | |
;; | |
esac | |
done | |
} | |
_git_config () | |
{ | |
local cur prev | |
_get_comp_words_by_ref -n =: cur prev | |
case "$prev" in | |
branch.*.remote) | |
__gitcomp "$(__git_remotes)" | |
return | |
;; | |
branch.*.merge) | |
__gitcomp "$(__git_refs)" | |
return | |
;; | |
remote.*.fetch) | |
local remote="${prev#remote.}" | |
remote="${remote%.fetch}" | |
__gitcomp "$(__git_refs_remotes "$remote")" | |
return | |
;; | |
remote.*.push) | |
local remote="${prev#remote.}" | |
remote="${remote%.push}" | |
__gitcomp "$(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 | |
;; | |
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 "$(__git_config_get_set_variables)" | |
return | |
;; | |
*.*) | |
COMPREPLY=() | |
return | |
;; | |
esac | |
case "$cur" in | |
--*) | |
__gitcomp " | |
--global --system --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 merge mergeoptions rebase" "$pfx" "$cur" | |
return | |
;; | |
branch.*) | |
local pfx="${cur%.*}." | |
cur="${cur#*.}" | |
__gitcomp "$(__git_heads)" "$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 "$__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 "$(__git_remotes)" "$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.abbrevguard | |
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.ignoreCygwinFSTricks | |
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.suppressBlankEmpty | |
diff.tool | |
diff.wordRegex | |
difftool. | |
difftool.prompt | |
fetch.recurseSubmodules | |
fetch.unpackLimit | |
format.attach | |
format.cc | |
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 | |
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 rm show prune update set-head" | |
local subcommand="$(__git_find_on_cmdline "$subcommands")" | |
if [ -z "$subcommand" ]; then | |
__gitcomp "$subcommands" | |
return | |
fi | |
case "$subcommand" in | |
rename|rm|show|prune) | |
__gitcomp "$(__git_remotes)" | |
;; | |
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" | |
;; | |
*) | |
COMPREPLY=() | |
;; | |
esac | |
} | |
_git_replace () | |
{ | |
__gitcomp "$(__git_refs)" | |
} | |
_git_reset () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--merge --mixed --hard --soft --patch" | |
return | |
;; | |
esac | |
__gitcomp "$(__git_refs)" | |
} | |
_git_revert () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--edit --mainline --no-edit --no-commit --signoff" | |
return | |
;; | |
esac | |
__gitcomp "$(__git_refs)" | |
} | |
_git_rm () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp "--cached --dry-run --ignore-unmatch --quiet" | |
return | |
;; | |
esac | |
COMPREPLY=() | |
} | |
_git_shortlog () | |
{ | |
__git_has_doubledash && return | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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 | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--pretty=*) | |
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases) | |
" "" "${cur##--pretty=}" | |
return | |
;; | |
--format=*) | |
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases) | |
" "" "${cur##--format=}" | |
return | |
;; | |
--*) | |
__gitcomp "--pretty= --format= --abbrev-commit --oneline | |
$__git_diff_common_options | |
" | |
return | |
;; | |
esac | |
__git_complete_file | |
} | |
_git_show_branch () | |
{ | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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 cur | |
_get_comp_words_by_ref -n =: cur | |
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" | |
else | |
COMPREPLY=() | |
fi | |
;; | |
esac | |
else | |
case "$subcommand,$cur" in | |
save,--*) | |
__gitcomp "$save_opts" | |
;; | |
apply,--*|pop,--*) | |
__gitcomp "--index --quiet" | |
;; | |
show,--*|drop,--*|branch,--*) | |
COMPREPLY=() | |
;; | |
show,*|apply,*|drop,*|pop,*|branch,*) | |
__gitcomp "$(git --git-dir="$(__gitdir)" stash list \ | |
| sed -n -e 's/:.*//p')" | |
;; | |
*) | |
COMPREPLY=() | |
;; | |
esac | |
fi | |
} | |
_git_submodule () | |
{ | |
__git_has_doubledash && return | |
local subcommands="add status init update summary foreach sync" | |
if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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= $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= | |
" | |
local cur | |
_get_comp_words_by_ref -n =: cur | |
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 $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" | |
;; | |
*) | |
COMPREPLY=() | |
;; | |
esac | |
fi | |
} | |
_git_tag () | |
{ | |
local i c=1 f=0 | |
local words cword prev | |
_get_comp_words_by_ref -n =: words cword prev | |
while [ $c -lt $cword ]; do | |
i="${words[c]}" | |
case "$i" in | |
-d|-v) | |
__gitcomp "$(__git_tags)" | |
return | |
;; | |
-f) | |
f=1 | |
;; | |
esac | |
c=$((++c)) | |
done | |
case "$prev" in | |
-m|-F) | |
COMPREPLY=() | |
;; | |
-*|tag) | |
if [ $f = 1 ]; then | |
__gitcomp "$(__git_tags)" | |
else | |
COMPREPLY=() | |
fi | |
;; | |
*) | |
__gitcomp "$(__git_refs)" | |
;; | |
esac | |
} | |
_git_whatchanged () | |
{ | |
_git_log | |
} | |
_git () | |
{ | |
local i c=1 command __git_dir | |
if [[ -n ${ZSH_VERSION-} ]]; then | |
emulate -L bash | |
setopt KSH_TYPESET | |
fi | |
local cur words cword | |
_get_comp_words_by_ref -n =: cur words cword | |
while [ $c -lt $cword ]; do | |
i="${words[c]}" | |
case "$i" in | |
--git-dir=*) __git_dir="${i#--git-dir=}" ;; | |
--bare) __git_dir="." ;; | |
--version|-p|--paginate) ;; | |
--help) command="help"; break ;; | |
*) command="$i"; break ;; | |
esac | |
c=$((++c)) | |
done | |
if [ -z "$command" ]; then | |
case "$cur" in | |
--*) __gitcomp " | |
--paginate | |
--no-pager | |
--git-dir= | |
--bare | |
--version | |
--exec-path | |
--html-path | |
--work-tree= | |
--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 | |
completion_func="_git_${expansion//-/_}" | |
declare -f $completion_func >/dev/null && $completion_func | |
fi | |
} | |
_gitk () | |
{ | |
if [[ -n ${ZSH_VERSION-} ]]; then | |
emulate -L bash | |
setopt KSH_TYPESET | |
fi | |
__git_has_doubledash && return | |
local cur | |
local g="$(__gitdir)" | |
local merge="" | |
if [ -f "$g/MERGE_HEAD" ]; then | |
merge="--merge" | |
fi | |
_get_comp_words_by_ref -n =: cur | |
case "$cur" in | |
--*) | |
__gitcomp " | |
$__git_log_common_options | |
$__git_log_gitk_options | |
$merge | |
" | |
return | |
;; | |
esac | |
__git_complete_revlist | |
} | |
complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \ | |
|| complete -o default -o nospace -F _git git | |
complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \ | |
|| complete -o default -o nospace -F _gitk gitk | |
# 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 | |
complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \ | |
|| complete -o default -o nospace -F _git git.exe | |
fi | |
if [[ -n ${ZSH_VERSION-} ]]; then | |
shopt () { | |
local option | |
if [ $# -ne 2 ]; then | |
echo "USAGE: $0 (-q|-s|-u) <option>" >&2 | |
return 1 | |
fi | |
case "$2" in | |
nullglob) | |
option="$2" | |
;; | |
*) | |
echo "$0: invalid option: $2" >&2 | |
return 1 | |
esac | |
case "$1" in | |
-q) setopt | grep -q "$option" ;; | |
-u) unsetopt "$option" ;; | |
-s) setopt "$option" ;; | |
*) | |
echo "$0: invalid flag: $1" >&2 | |
return 1 | |
esac | |
} | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment