]> git.ipfire.org Git - thirdparty/git.git/blame - contrib/completion/git-completion.bash
completion: don't declare 'local words' to make zsh happy
[thirdparty/git.git] / contrib / completion / git-completion.bash
CommitLineData
a42577d4 1#!bash
690d8824 2#
b5a49471 3# bash/zsh completion support for core Git.
690d8824 4#
c70680ce 5# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
690d8824 6# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
c70680ce 7# Distributed under the GNU General Public License, version 2.0.
690d8824
JH
8#
9# The contained completion routines provide support for completing:
10#
11# *) local and remote branch names
12# *) local and remote tag names
13# *) .git/remotes file names
14# *) git 'subcommands'
15# *) tree paths within 'ref:path/to/file' expressions
c70680ce 16# *) common --long-options
690d8824
JH
17#
18# To use these routines:
19#
20# 1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
b5a49471 21# 2) Add the following line to your .bashrc/.zshrc:
06f44c3c
ML
22# source ~/.git-completion.sh
23#
eaa4e6ee 24# 3) Consider changing your PS1 to also show the current branch:
b5a49471
MSO
25# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
26# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
d3d717a4
SP
27#
28# The argument to __git_ps1 will be displayed only if you
29# are currently in a git repository. The %s token will be
30# the name of the current branch.
31#
a9ee90d7
TP
32# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty
33# value, unstaged (*) and staged (+) changes will be shown next
34# to the branch name. You can configure this per-repository
35# with the bash.showDirtyState variable, which defaults to true
36# once GIT_PS1_SHOWDIRTYSTATE is enabled.
738a94a9 37#
2414b45c
DT
38# You can also see if currently something is stashed, by setting
39# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
40# then a '$' will be shown next to the branch name.
41#
397f7c63
DT
42# If you would like to see if there're untracked files, then you can
43# set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
44# untracked files, then a '%' will be shown next to the branch name.
45#
6d158cba
AS
46# If you would like to see the difference between HEAD and its
47# upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates
48# you are behind, ">" indicates you are ahead, and "<>"
49# indicates you have diverged. You can further control
50# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated
51# list of values:
52# verbose show number of commits ahead/behind (+/-) upstream
53# legacy don't use the '--count' option available in recent
54# versions of git-rev-list
55# git always compare HEAD to @{upstream}
56# svn always compare HEAD to your SVN upstream
57# By default, __git_ps1 will compare HEAD to your SVN upstream
58# if it can find one, or @{upstream} otherwise. Once you have
59# set GIT_PS1_SHOWUPSTREAM, you can override it on a
60# per-repository basis by setting the bash.showUpstream config
61# variable.
62#
63#
c70680ce
SP
64# To submit patches:
65#
66# *) Read Documentation/SubmittingPatches
67# *) Send all patches to the current maintainer:
68#
69# "Shawn O. Pearce" <spearce@spearce.org>
70#
71# *) Always CC the Git mailing list:
72#
73# git@vger.kernel.org
74#
690d8824 75
b5a49471
MSO
76if [[ -n ${ZSH_VERSION-} ]]; then
77 autoload -U +X bashcompinit && bashcompinit
78fi
79
db8a9ff0
SP
80case "$COMP_WORDBREAKS" in
81*:*) : great ;;
82*) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
83esac
84
a42577d4
TP
85# __gitdir accepts 0 or 1 arguments (i.e., location)
86# returns location of .git repo
873537fa
SP
87__gitdir ()
88{
25a31f81 89 if [ -z "${1-}" ]; then
5c9cc64a 90 if [ -n "${__git_dir-}" ]; then
67ffa114
SP
91 echo "$__git_dir"
92 elif [ -d .git ]; then
93 echo .git
94 else
95 git rev-parse --git-dir 2>/dev/null
96 fi
97 elif [ -d "$1/.git" ]; then
98 echo "$1/.git"
99 else
100 echo "$1"
101 fi
873537fa
SP
102}
103
6d158cba
AS
104# stores the divergence from upstream in $p
105# used by GIT_PS1_SHOWUPSTREAM
106__git_ps1_show_upstream ()
107{
108 local key value
109 local svn_remote=() svn_url_pattern count n
110 local upstream=git legacy="" verbose=""
111
112 # get some config options from git-config
113 while read key value; do
114 case "$key" in
115 bash.showupstream)
116 GIT_PS1_SHOWUPSTREAM="$value"
117 if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
118 p=""
119 return
120 fi
121 ;;
122 svn-remote.*.url)
123 svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
124 svn_url_pattern+="\\|$value"
125 upstream=svn+git # default upstream is SVN if available, else git
126 ;;
127 esac
128 done < <(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')
129
130 # parse configuration values
131 for option in ${GIT_PS1_SHOWUPSTREAM}; do
132 case "$option" in
133 git|svn) upstream="$option" ;;
134 verbose) verbose=1 ;;
135 legacy) legacy=1 ;;
136 esac
137 done
138
139 # Find our upstream
140 case "$upstream" in
141 git) upstream="@{upstream}" ;;
142 svn*)
143 # get the upstream from the "git-svn-id: ..." in a commit message
144 # (git-svn uses essentially the same procedure internally)
145 local svn_upstream=($(git log --first-parent -1 \
06f44c3c 146 --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
6d158cba
AS
147 if [[ 0 -ne ${#svn_upstream[@]} ]]; then
148 svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
149 svn_upstream=${svn_upstream%@*}
06f44c3c
ML
150 local n_stop="${#svn_remote[@]}"
151 for ((n=1; n <= n_stop; ++n)); do
6d158cba
AS
152 svn_upstream=${svn_upstream#${svn_remote[$n]}}
153 done
154
155 if [[ -z "$svn_upstream" ]]; then
156 # default branch name for checkouts with no layout:
157 upstream=${GIT_SVN_ID:-git-svn}
158 else
159 upstream=${svn_upstream#/}
160 fi
161 elif [[ "svn+git" = "$upstream" ]]; then
162 upstream="@{upstream}"
163 fi
164 ;;
165 esac
166
167 # Find how many commits we are ahead/behind our upstream
168 if [[ -z "$legacy" ]]; then
169 count="$(git rev-list --count --left-right \
170 "$upstream"...HEAD 2>/dev/null)"
171 else
172 # produce equivalent output to --count for older versions of git
173 local commits
174 if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
175 then
176 local commit behind=0 ahead=0
177 for commit in $commits
178 do
179 case "$commit" in
180 "<"*) let ++behind
181 ;;
182 *) let ++ahead
183 ;;
184 esac
185 done
186 count="$behind $ahead"
187 else
188 count=""
189 fi
190 fi
191
192 # calculate the result
193 if [[ -z "$verbose" ]]; then
194 case "$count" in
195 "") # no upstream
196 p="" ;;
197 "0 0") # equal to upstream
198 p="=" ;;
199 "0 "*) # ahead of upstream
200 p=">" ;;
201 *" 0") # behind upstream
202 p="<" ;;
203 *) # diverged from upstream
204 p="<>" ;;
205 esac
206 else
207 case "$count" in
208 "") # no upstream
209 p="" ;;
210 "0 0") # equal to upstream
211 p=" u=" ;;
212 "0 "*) # ahead of upstream
213 p=" u+${count#0 }" ;;
214 *" 0") # behind upstream
215 p=" u-${count% 0}" ;;
216 *) # diverged from upstream
217 p=" u+${count#* }-${count% *}" ;;
218 esac
219 fi
220
221}
222
223
a42577d4
TP
224# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
225# returns text to add to bash PS1 prompt (includes branch name)
d3d717a4
SP
226__git_ps1 ()
227{
fa26a401 228 local g="$(__gitdir)"
e7520196 229 if [ -n "$g" ]; then
6c44b640
AS
230 local r=""
231 local b=""
d7107ca6 232 if [ -f "$g/rebase-merge/interactive" ]; then
e7520196 233 r="|REBASE-i"
28ed6e7b 234 b="$(cat "$g/rebase-merge/head-name")"
ad244d25 235 elif [ -d "$g/rebase-merge" ]; then
e7520196 236 r="|REBASE-m"
28ed6e7b 237 b="$(cat "$g/rebase-merge/head-name")"
e7520196 238 else
d7107ca6
JH
239 if [ -d "$g/rebase-apply" ]; then
240 if [ -f "$g/rebase-apply/rebasing" ]; then
241 r="|REBASE"
242 elif [ -f "$g/rebase-apply/applying" ]; then
243 r="|AM"
244 else
245 r="|AM/REBASE"
246 fi
247 elif [ -f "$g/MERGE_HEAD" ]; then
8763dbb1 248 r="|MERGING"
5b2af8ca
JS
249 elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
250 r="|CHERRY-PICKING"
d7107ca6 251 elif [ -f "$g/BISECT_LOG" ]; then
e7520196
RR
252 r="|BISECTING"
253 fi
ff790b6a
JH
254
255 b="$(git symbolic-ref HEAD 2>/dev/null)" || {
dd42c2f0
JH
256
257 b="$(
258 case "${GIT_PS1_DESCRIBE_STYLE-}" in
259 (contains)
260 git describe --contains HEAD ;;
261 (branch)
262 git describe --contains --all HEAD ;;
263 (describe)
264 git describe HEAD ;;
265 (* | default)
bd40d252 266 git describe --tags --exact-match HEAD ;;
dd42c2f0
JH
267 esac 2>/dev/null)" ||
268
ff790b6a
JH
269 b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
270 b="unknown"
ff790b6a
JH
271 b="($b)"
272 }
e7520196
RR
273 fi
274
6c44b640
AS
275 local w=""
276 local i=""
277 local s=""
278 local u=""
279 local c=""
6d158cba 280 local p=""
738a94a9 281
e5dd864a 282 if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
8dfb17e1 283 if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
ddb6d010
MSO
284 c="BARE:"
285 else
286 b="GIT_DIR!"
287 fi
e5dd864a
TP
288 elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
289 if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
290 if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
cf6e7ba1 291 git diff --no-ext-diff --quiet --exit-code || w="*"
e5dd864a 292 if git rev-parse --quiet --verify HEAD >/dev/null; then
cf6e7ba1 293 git diff-index --cached --quiet HEAD -- || i="+"
e5dd864a
TP
294 else
295 i="#"
296 fi
738a94a9
TR
297 fi
298 fi
2414b45c
DT
299 if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
300 git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
301 fi
397f7c63
DT
302
303 if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
304 if [ -n "$(git ls-files --others --exclude-standard)" ]; then
305 u="%"
306 fi
307 fi
6d158cba
AS
308
309 if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
310 __git_ps1_show_upstream
311 fi
738a94a9
TR
312 fi
313
4cc47382 314 local f="$w$i$s$u"
6d158cba 315 printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
d3d717a4
SP
316 fi
317}
318
a42577d4 319# __gitcomp_1 requires 2 arguments
ab02dfe5
SP
320__gitcomp_1 ()
321{
322 local c IFS=' '$'\t'$'\n'
323 for c in $1; do
324 case "$c$2" in
325 --*=*) printf %s$'\n' "$c$2" ;;
326 *.) printf %s$'\n' "$c$2" ;;
327 *) printf %s$'\n' "$c$2 " ;;
328 esac
329 done
330}
331
dbda3b10
JN
332# The following function is based on code from:
333#
334# bash_completion - programmable completion functions for bash 3.2+
335#
336# Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
337# © 2009-2010, Bash Completion Maintainers
338# <bash-completion-devel@lists.alioth.debian.org>
339#
340# This program is free software; you can redistribute it and/or modify
341# it under the terms of the GNU General Public License as published by
342# the Free Software Foundation; either version 2, or (at your option)
343# any later version.
344#
345# This program is distributed in the hope that it will be useful,
346# but WITHOUT ANY WARRANTY; without even the implied warranty of
347# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
348# GNU General Public License for more details.
349#
350# You should have received a copy of the GNU General Public License
351# along with this program; if not, write to the Free Software Foundation,
352# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
353#
354# The latest version of this software can be obtained here:
355#
356# http://bash-completion.alioth.debian.org/
357#
358# RELEASE: 2.x
359
360# This function can be used to access a tokenized list of words
361# on the command line:
362#
363# __git_reassemble_comp_words_by_ref '=:'
364# if test "${words_[cword_-1]}" = -w
365# then
366# ...
367# fi
368#
369# The argument should be a collection of characters from the list of
370# word completion separators (COMP_WORDBREAKS) to treat as ordinary
371# characters.
372#
373# This is roughly equivalent to going back in time and setting
374# COMP_WORDBREAKS to exclude those characters. The intent is to
375# make option types like --date=<type> and <rev>:<path> easy to
376# recognize by treating each shell word as a single token.
377#
378# It is best not to set COMP_WORDBREAKS directly because the value is
379# shared with other completion scripts. By the time the completion
380# function gets called, COMP_WORDS has already been populated so local
381# changes to COMP_WORDBREAKS have no effect.
382#
383# Output: words_, cword_, cur_.
384
385__git_reassemble_comp_words_by_ref()
386{
387 local exclude i j first
388 # Which word separators to exclude?
389 exclude="${1//[^$COMP_WORDBREAKS]}"
390 cword_=$COMP_CWORD
391 if [ -z "$exclude" ]; then
392 words_=("${COMP_WORDS[@]}")
393 return
394 fi
395 # List of word completion separators has shrunk;
396 # re-assemble words to complete.
397 for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
398 # Append each nonempty word consisting of just
399 # word separator characters to the current word.
400 first=t
401 while
402 [ $i -gt 0 ] &&
403 [ -n "${COMP_WORDS[$i]}" ] &&
404 # word consists of excluded word separators
405 [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
406 do
407 # Attach to the previous token,
408 # unless the previous token is the command name.
409 if [ $j -ge 2 ] && [ -n "$first" ]; then
410 ((j--))
411 fi
412 first=
413 words_[$j]=${words_[j]}${COMP_WORDS[i]}
414 if [ $i = $COMP_CWORD ]; then
415 cword_=$j
416 fi
417 if (($i < ${#COMP_WORDS[@]} - 1)); then
418 ((i++))
419 else
420 # Done.
421 return
422 fi
423 done
424 words_[$j]=${words_[j]}${COMP_WORDS[i]}
425 if [ $i = $COMP_CWORD ]; then
426 cword_=$j
427 fi
428 done
429}
430
da48616f 431if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
52c9d8e2 432if [[ -z ${ZSH_VERSION:+set} ]]; then
da48616f
PD
433_get_comp_words_by_ref ()
434{
dbda3b10
JN
435 local exclude cur_ words_ cword_
436 if [ "$1" = "-n" ]; then
437 exclude=$2
438 shift 2
439 fi
440 __git_reassemble_comp_words_by_ref "$exclude"
441 cur_=${words_[cword_]}
da48616f
PD
442 while [ $# -gt 0 ]; do
443 case "$1" in
444 cur)
dbda3b10 445 cur=$cur_
da48616f
PD
446 ;;
447 prev)
dbda3b10 448 prev=${words_[$cword_-1]}
da48616f
PD
449 ;;
450 words)
dbda3b10 451 words=("${words_[@]}")
da48616f
PD
452 ;;
453 cword)
dbda3b10 454 cword=$cword_
da48616f
PD
455 ;;
456 esac
457 shift
458 done
459}
52c9d8e2
JN
460else
461_get_comp_words_by_ref ()
462{
463 while [ $# -gt 0 ]; do
464 case "$1" in
465 cur)
466 cur=${COMP_WORDS[COMP_CWORD]}
467 ;;
468 prev)
469 prev=${COMP_WORDS[COMP_CWORD-1]}
470 ;;
471 words)
472 words=("${COMP_WORDS[@]}")
473 ;;
474 cword)
475 cword=$COMP_CWORD
476 ;;
477 -n)
478 # assume COMP_WORDBREAKS is already set sanely
479 shift
480 ;;
481 esac
482 shift
483 done
484}
485fi
da48616f
PD
486fi
487
a42577d4
TP
488# __gitcomp accepts 1, 2, 3, or 4 arguments
489# generates completion reply with compgen
72e5e989
SP
490__gitcomp ()
491{
9244d69b
SG
492 local cur_="$cur"
493
b3391775 494 if [ $# -gt 2 ]; then
9244d69b 495 cur_="$3"
78d4d6a2 496 fi
9244d69b 497 case "$cur_" in
5447aac7
SG
498 --*=)
499 COMPREPLY=()
5447aac7
SG
500 ;;
501 *)
ab02dfe5 502 local IFS=$'\n'
25a31f81
TP
503 COMPREPLY=($(compgen -P "${2-}" \
504 -W "$(__gitcomp_1 "${1-}" "${4-}")" \
9244d69b 505 -- "$cur_"))
5447aac7
SG
506 ;;
507 esac
72e5e989
SP
508}
509
a42577d4 510# __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
5de40f59
SP
511__git_heads ()
512{
25a31f81 513 local cmd i is_hash=y dir="$(__gitdir "${1-}")"
5de40f59 514 if [ -d "$dir" ]; then
05e8b3d6
SG
515 git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
516 refs/heads
5de40f59
SP
517 return
518 fi
25a31f81 519 for i in $(git ls-remote "${1-}" 2>/dev/null); do
5de40f59
SP
520 case "$is_hash,$i" in
521 y,*) is_hash=n ;;
522 n,*^{}) is_hash=y ;;
523 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
524 n,*) is_hash=y; echo "$i" ;;
525 esac
526 done
527}
528
a42577d4 529# __git_tags accepts 0 or 1 arguments (to pass to __gitdir)
88e21dc7
SP
530__git_tags ()
531{
25a31f81 532 local cmd i is_hash=y dir="$(__gitdir "${1-}")"
88e21dc7 533 if [ -d "$dir" ]; then
05e8b3d6
SG
534 git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
535 refs/tags
88e21dc7
SP
536 return
537 fi
25a31f81 538 for i in $(git ls-remote "${1-}" 2>/dev/null); do
88e21dc7
SP
539 case "$is_hash,$i" in
540 y,*) is_hash=n ;;
541 n,*^{}) is_hash=y ;;
542 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
543 n,*) is_hash=y; echo "$i" ;;
544 esac
545 done
546}
547
34a6bbb5
KB
548# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
549# presence of 2nd argument means use the guess heuristic employed
550# by checkout for tracking branches
690d8824
JH
551__git_refs ()
552{
34a6bbb5 553 local i is_hash=y dir="$(__gitdir "${1-}")" track="${2-}"
da4902a7 554 local format refs
873537fa 555 if [ -d "$dir" ]; then
608efb87
SG
556 case "$cur" in
557 refs|refs/*)
558 format="refname"
559 refs="${cur%/*}"
34a6bbb5 560 track=""
608efb87
SG
561 ;;
562 *)
d23e7570
IWC
563 for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
564 if [ -e "$dir/$i" ]; then echo $i; fi
565 done
608efb87
SG
566 format="refname:short"
567 refs="refs/tags refs/heads refs/remotes"
568 ;;
569 esac
570 git --git-dir="$dir" for-each-ref --format="%($format)" \
571 $refs
34a6bbb5
KB
572 if [ -n "$track" ]; then
573 # employ the heuristic used by git checkout
574 # Try to find a remote branch that matches the completion word
575 # but only output if the branch name is unique
576 local ref entry
577 git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \
578 "refs/remotes/" | \
579 while read entry; do
580 eval "$entry"
581 ref="${ref#*/}"
582 if [[ "$ref" == "$cur"* ]]; then
583 echo "$ref"
584 fi
585 done | uniq -u
586 fi
35e65ecc 587 return
690d8824 588 fi
799596a5 589 for i in $(git ls-remote "$dir" 2>/dev/null); do
690d8824
JH
590 case "$is_hash,$i" in
591 y,*) is_hash=n ;;
592 n,*^{}) is_hash=y ;;
593 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
594 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
35e65ecc 595 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
690d8824
JH
596 n,*) is_hash=y; echo "$i" ;;
597 esac
598 done
599}
600
a42577d4 601# __git_refs2 requires 1 argument (to pass to __git_refs)
690d8824
JH
602__git_refs2 ()
603{
67ffa114
SP
604 local i
605 for i in $(__git_refs "$1"); do
606 echo "$i:$i"
690d8824
JH
607 done
608}
609
a42577d4 610# __git_refs_remotes requires 1 argument (to pass to ls-remote)
5de40f59
SP
611__git_refs_remotes ()
612{
613 local cmd i is_hash=y
799596a5 614 for i in $(git ls-remote "$1" 2>/dev/null); do
5de40f59
SP
615 case "$is_hash,$i" in
616 n,refs/heads/*)
617 is_hash=y
618 echo "$i:refs/remotes/$1/${i#refs/heads/}"
619 ;;
620 y,*) is_hash=n ;;
621 n,*^{}) is_hash=y ;;
622 n,refs/tags/*) is_hash=y;;
623 n,*) is_hash=y; ;;
624 esac
625 done
626}
627
690d8824
JH
628__git_remotes ()
629{
873537fa 630 local i ngoff IFS=$'\n' d="$(__gitdir)"
56fc25f2 631 shopt -q nullglob || ngoff=1
690d8824 632 shopt -s nullglob
873537fa
SP
633 for i in "$d/remotes"/*; do
634 echo ${i#$d/remotes/}
690d8824 635 done
56fc25f2 636 [ "$ngoff" ] && shopt -u nullglob
518ef8f0
TZ
637 for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
638 i="${i#remote.}"
639 echo "${i/.url*/}"
56fc25f2 640 done
690d8824
JH
641}
642
eaa4e6ee 643__git_list_merge_strategies ()
4ad91321 644{
25b3d4d6
JH
645 git merge -s help 2>&1 |
646 sed -n -e '/[Aa]vailable strategies are: /,/^$/{
647 s/\.$//
648 s/.*://
649 s/^[ ]*//
650 s/[ ]*$//
4ad91321 651 p
25b3d4d6 652 }'
4ad91321 653}
eaa4e6ee
JN
654
655__git_merge_strategies=
656# 'git merge -s help' (and thus detection of the merge strategy
657# list) fails, unfortunately, if run outside of any git working
658# tree. __git_merge_strategies is set to the empty string in
659# that case, and the detection will be repeated the next time it
660# is needed.
661__git_compute_merge_strategies ()
662{
663 : ${__git_merge_strategies:=$(__git_list_merge_strategies)}
664}
4ad91321 665
1d66ec58 666__git_complete_revlist_file ()
690d8824 667{
da4902a7 668 local pfx ls ref cur_="$cur"
9244d69b 669 case "$cur_" in
1d66ec58
SG
670 *..?*:*)
671 return
672 ;;
690d8824 673 ?*:*)
9244d69b
SG
674 ref="${cur_%%:*}"
675 cur_="${cur_#*:}"
676 case "$cur_" in
690d8824 677 ?*/*)
9244d69b
SG
678 pfx="${cur_%/*}"
679 cur_="${cur_##*/}"
690d8824
JH
680 ls="$ref:$pfx"
681 pfx="$pfx/"
682 ;;
683 *)
684 ls="$ref"
685 ;;
80152b09 686 esac
db8a9ff0
SP
687
688 case "$COMP_WORDBREAKS" in
689 *:*) : great ;;
690 *) pfx="$ref:$pfx" ;;
691 esac
692
778306e4 693 local IFS=$'\n'
690d8824 694 COMPREPLY=($(compgen -P "$pfx" \
873537fa 695 -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
778306e4
SP
696 | sed '/^100... blob /{
697 s,^.* ,,
698 s,$, ,
699 }
700 /^120000 blob /{
701 s,^.* ,,
702 s,$, ,
703 }
690d8824
JH
704 /^040000 tree /{
705 s,^.* ,,
706 s,$,/,
707 }
708 s/^.* //')" \
9244d69b 709 -- "$cur_"))
690d8824 710 ;;
f53352fb 711 *...*)
9244d69b
SG
712 pfx="${cur_%...*}..."
713 cur_="${cur_#*...}"
714 __gitcomp "$(__git_refs)" "$pfx" "$cur_"
f53352fb
SP
715 ;;
716 *..*)
9244d69b
SG
717 pfx="${cur_%..*}.."
718 cur_="${cur_#*..}"
719 __gitcomp "$(__git_refs)" "$pfx" "$cur_"
b3391775 720 ;;
f53352fb 721 *)
b3391775 722 __gitcomp "$(__git_refs)"
f53352fb
SP
723 ;;
724 esac
725}
726
1d66ec58
SG
727
728__git_complete_file ()
729{
730 __git_complete_revlist_file
731}
732
733__git_complete_revlist ()
734{
735 __git_complete_revlist_file
736}
737
52d5c3b5
JS
738__git_complete_remote_or_refspec ()
739{
9244d69b 740 local cur_="$cur" cmd="${words[1]}"
0a4e1472 741 local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
da48616f
PD
742 while [ $c -lt $cword ]; do
743 i="${words[c]}"
52d5c3b5 744 case "$i" in
e25e2b42
BG
745 --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
746 --all)
747 case "$cmd" in
748 push) no_complete_refspec=1 ;;
749 fetch)
750 COMPREPLY=()
751 return
752 ;;
753 *) ;;
754 esac
755 ;;
52d5c3b5
JS
756 -*) ;;
757 *) remote="$i"; break ;;
758 esac
759 c=$((++c))
760 done
761 if [ -z "$remote" ]; then
762 __gitcomp "$(__git_remotes)"
763 return
764 fi
0a4e1472
JS
765 if [ $no_complete_refspec = 1 ]; then
766 COMPREPLY=()
767 return
768 fi
52d5c3b5 769 [ "$remote" = "." ] && remote=
9244d69b 770 case "$cur_" in
52d5c3b5
JS
771 *:*)
772 case "$COMP_WORDBREAKS" in
773 *:*) : great ;;
9244d69b 774 *) pfx="${cur_%%:*}:" ;;
52d5c3b5 775 esac
9244d69b 776 cur_="${cur_#*:}"
52d5c3b5
JS
777 lhs=0
778 ;;
779 +*)
780 pfx="+"
9244d69b 781 cur_="${cur_#+}"
52d5c3b5
JS
782 ;;
783 esac
784 case "$cmd" in
785 fetch)
786 if [ $lhs = 1 ]; then
9244d69b 787 __gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur_"
52d5c3b5 788 else
9244d69b 789 __gitcomp "$(__git_refs)" "$pfx" "$cur_"
52d5c3b5
JS
790 fi
791 ;;
792 pull)
793 if [ $lhs = 1 ]; then
9244d69b 794 __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
52d5c3b5 795 else
9244d69b 796 __gitcomp "$(__git_refs)" "$pfx" "$cur_"
52d5c3b5
JS
797 fi
798 ;;
799 push)
800 if [ $lhs = 1 ]; then
9244d69b 801 __gitcomp "$(__git_refs)" "$pfx" "$cur_"
52d5c3b5 802 else
9244d69b 803 __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
52d5c3b5
JS
804 fi
805 ;;
806 esac
807}
808
3c7b480a
JS
809__git_complete_strategy ()
810{
eaa4e6ee 811 __git_compute_merge_strategies
da48616f 812 case "$prev" in
3c7b480a 813 -s|--strategy)
eaa4e6ee 814 __gitcomp "$__git_merge_strategies"
3c7b480a
JS
815 return 0
816 esac
3c7b480a
JS
817 case "$cur" in
818 --strategy=*)
eaa4e6ee 819 __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
3c7b480a
JS
820 return 0
821 ;;
822 esac
823 return 1
824}
825
eaa4e6ee 826__git_list_all_commands ()
f2bb9f88
SP
827{
828 local i IFS=" "$'\n'
427e586b 829 for i in $(git help -a|egrep '^ [a-zA-Z0-9]')
1eb7e2f8
LM
830 do
831 case $i in
832 *--*) : helper pattern;;
833 *) echo $i;;
834 esac
835 done
836}
1eb7e2f8 837
eaa4e6ee
JN
838__git_all_commands=
839__git_compute_all_commands ()
840{
841 : ${__git_all_commands:=$(__git_list_all_commands)}
842}
843
844__git_list_porcelain_commands ()
1eb7e2f8 845{
1eb7e2f8 846 local i IFS=" "$'\n'
eaa4e6ee
JN
847 __git_compute_all_commands
848 for i in "help" $__git_all_commands
f2bb9f88
SP
849 do
850 case $i in
718a087a 851 *--*) : helper pattern;;
a925c6f1
SP
852 applymbox) : ask gittus;;
853 applypatch) : ask gittus;;
854 archimport) : import;;
2e3a430a 855 cat-file) : plumbing;;
56d99c67 856 check-attr) : plumbing;;
f2bb9f88 857 check-ref-format) : plumbing;;
ff2549dc 858 checkout-index) : plumbing;;
f2bb9f88 859 commit-tree) : plumbing;;
ff2549dc 860 count-objects) : infrequent;;
a925c6f1
SP
861 cvsexportcommit) : export;;
862 cvsimport) : import;;
f2bb9f88
SP
863 cvsserver) : daemon;;
864 daemon) : daemon;;
5cfb4fe5
SP
865 diff-files) : plumbing;;
866 diff-index) : plumbing;;
867 diff-tree) : plumbing;;
c6ec3b13 868 fast-import) : import;;
ff2549dc 869 fast-export) : export;;
a925c6f1 870 fsck-objects) : plumbing;;
f2bb9f88 871 fetch-pack) : plumbing;;
a925c6f1 872 fmt-merge-msg) : plumbing;;
56d99c67 873 for-each-ref) : plumbing;;
f2bb9f88
SP
874 hash-object) : plumbing;;
875 http-*) : transport;;
876 index-pack) : plumbing;;
a925c6f1 877 init-db) : deprecated;;
f2bb9f88 878 local-fetch) : plumbing;;
ff2549dc
PB
879 lost-found) : infrequent;;
880 ls-files) : plumbing;;
881 ls-remote) : plumbing;;
882 ls-tree) : plumbing;;
f2bb9f88
SP
883 mailinfo) : plumbing;;
884 mailsplit) : plumbing;;
885 merge-*) : plumbing;;
886 mktree) : plumbing;;
887 mktag) : plumbing;;
888 pack-objects) : plumbing;;
889 pack-redundant) : plumbing;;
890 pack-refs) : plumbing;;
891 parse-remote) : plumbing;;
892 patch-id) : plumbing;;
893 peek-remote) : plumbing;;
a925c6f1
SP
894 prune) : plumbing;;
895 prune-packed) : plumbing;;
896 quiltimport) : import;;
f2bb9f88
SP
897 read-tree) : plumbing;;
898 receive-pack) : plumbing;;
63d04a78 899 remote-*) : transport;;
5c66d0d4 900 repo-config) : deprecated;;
f2bb9f88
SP
901 rerere) : plumbing;;
902 rev-list) : plumbing;;
903 rev-parse) : plumbing;;
904 runstatus) : plumbing;;
905 sh-setup) : internal;;
906 shell) : daemon;;
ff2549dc 907 show-ref) : plumbing;;
f2bb9f88
SP
908 send-pack) : plumbing;;
909 show-index) : plumbing;;
910 ssh-*) : transport;;
911 stripspace) : plumbing;;
912 symbolic-ref) : plumbing;;
a925c6f1 913 tar-tree) : deprecated;;
f2bb9f88
SP
914 unpack-file) : plumbing;;
915 unpack-objects) : plumbing;;
a925c6f1 916 update-index) : plumbing;;
f2bb9f88
SP
917 update-ref) : plumbing;;
918 update-server-info) : daemon;;
919 upload-archive) : plumbing;;
920 upload-pack) : plumbing;;
921 write-tree) : plumbing;;
ff2549dc
PB
922 var) : infrequent;;
923 verify-pack) : infrequent;;
a925c6f1 924 verify-tag) : plumbing;;
f2bb9f88
SP
925 *) echo $i;;
926 esac
927 done
928}
eaa4e6ee
JN
929
930__git_porcelain_commands=
931__git_compute_porcelain_commands ()
932{
933 __git_compute_all_commands
934 : ${__git_porcelain_commands:=$(__git_list_porcelain_commands)}
935}
f2bb9f88 936
c3898111
SG
937__git_pretty_aliases ()
938{
939 local i IFS=$'\n'
940 for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do
941 case "$i" in
942 pretty.*)
943 i="${i#pretty.}"
944 echo "${i/ */}"
945 ;;
946 esac
947 done
948}
949
367dce2a
DS
950__git_aliases ()
951{
56fc25f2 952 local i IFS=$'\n'
518ef8f0 953 for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
e0d78059
SB
954 case "$i" in
955 alias.*)
956 i="${i#alias.}"
957 echo "${i/ */}"
958 ;;
959 esac
56fc25f2 960 done
367dce2a
DS
961}
962
a42577d4 963# __git_aliased_command requires 1 argument
367dce2a
DS
964__git_aliased_command ()
965{
873537fa 966 local word cmdline=$(git --git-dir="$(__gitdir)" \
e0d10e1c 967 config --get "alias.$1")
367dce2a 968 for word in $cmdline; do
c63437cb 969 case "$word" in
66729509
SG
970 \!gitk|gitk)
971 echo "gitk"
367dce2a 972 return
66729509 973 ;;
c63437cb
SG
974 \!*) : shell command alias ;;
975 -*) : option ;;
976 *=*) : setting env ;;
977 git) : git itself ;;
978 *)
979 echo "$word"
367dce2a 980 return
c63437cb 981 esac
367dce2a
DS
982 done
983}
984
918c03c2
SG
985# __git_find_on_cmdline requires 1 argument
986__git_find_on_cmdline ()
3ff1320d 987{
da4902a7 988 local word subcommand c=1
da48616f
PD
989 while [ $c -lt $cword ]; do
990 word="${words[c]}"
3ff1320d
SG
991 for subcommand in $1; do
992 if [ "$subcommand" = "$word" ]; then
993 echo "$subcommand"
994 return
995 fi
996 done
997 c=$((++c))
998 done
999}
1000
d773c631
SG
1001__git_has_doubledash ()
1002{
da4902a7 1003 local c=1
da48616f
PD
1004 while [ $c -lt $cword ]; do
1005 if [ "--" = "${words[c]}" ]; then
d773c631
SG
1006 return 0
1007 fi
1008 c=$((++c))
1009 done
1010 return 1
1011}
1012
7950659d 1013__git_whitespacelist="nowarn warn error error-all fix"
88329195
SP
1014
1015_git_am ()
1016{
da4902a7 1017 local dir="$(__gitdir)"
51ef1daa 1018 if [ -d "$dir"/rebase-apply ]; then
85f6b439 1019 __gitcomp "--skip --continue --resolved --abort"
88329195
SP
1020 return
1021 fi
1022 case "$cur" in
1023 --whitespace=*)
b3391775 1024 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
88329195
SP
1025 return
1026 ;;
1027 --*)
b3391775 1028 __gitcomp "
43acdf24 1029 --3way --committer-date-is-author-date --ignore-date
86c91f91 1030 --ignore-whitespace --ignore-space-change
43acdf24 1031 --interactive --keep --no-utf8 --signoff --utf8
af4e9e8c 1032 --whitespace= --scissors
b3391775 1033 "
88329195
SP
1034 return
1035 esac
1036 COMPREPLY=()
1037}
1038
1039_git_apply ()
1040{
88329195
SP
1041 case "$cur" in
1042 --whitespace=*)
b3391775 1043 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
88329195
SP
1044 return
1045 ;;
1046 --*)
b3391775 1047 __gitcomp "
88329195
SP
1048 --stat --numstat --summary --check --index
1049 --cached --index-info --reverse --reject --unidiff-zero
1050 --apply --no-add --exclude=
86c91f91 1051 --ignore-whitespace --ignore-space-change
88329195 1052 --whitespace= --inaccurate-eof --verbose
b3391775 1053 "
88329195
SP
1054 return
1055 esac
1056 COMPREPLY=()
1057}
1058
8435b548
SP
1059_git_add ()
1060{
d773c631
SG
1061 __git_has_doubledash && return
1062
8435b548
SP
1063 case "$cur" in
1064 --*)
1d284cba
SG
1065 __gitcomp "
1066 --interactive --refresh --patch --update --dry-run
c9a114b5 1067 --ignore-errors --intent-to-add
1d284cba 1068 "
8435b548
SP
1069 return
1070 esac
1071 COMPREPLY=()
1072}
1073
b3191ce2
LM
1074_git_archive ()
1075{
b3191ce2
LM
1076 case "$cur" in
1077 --format=*)
1078 __gitcomp "$(git archive --list)" "" "${cur##--format=}"
1079 return
1080 ;;
1081 --remote=*)
1082 __gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
1083 return
1084 ;;
1085 --*)
1086 __gitcomp "
1087 --format= --list --verbose
1088 --prefix= --remote= --exec=
1089 "
1090 return
1091 ;;
1092 esac
1093 __git_complete_file
1094}
1095
b2e69f62
SP
1096_git_bisect ()
1097{
d773c631
SG
1098 __git_has_doubledash && return
1099
bf11d461 1100 local subcommands="start bad good skip reset visualize replay log run"
918c03c2 1101 local subcommand="$(__git_find_on_cmdline "$subcommands")"
3ff1320d 1102 if [ -z "$subcommand" ]; then
128191f5
SG
1103 if [ -f "$(__gitdir)"/BISECT_START ]; then
1104 __gitcomp "$subcommands"
1105 else
1106 __gitcomp "replay start"
1107 fi
b2e69f62
SP
1108 return
1109 fi
1110
3ff1320d 1111 case "$subcommand" in
8205ff8e 1112 bad|good|reset|skip|start)
b2e69f62
SP
1113 __gitcomp "$(__git_refs)"
1114 ;;
1115 *)
1116 COMPREPLY=()
1117 ;;
1118 esac
1119}
1120
690d8824
JH
1121_git_branch ()
1122{
da4902a7 1123 local i c=1 only_local_ref="n" has_r="n"
b9217642 1124
da48616f
PD
1125 while [ $c -lt $cword ]; do
1126 i="${words[c]}"
b9217642
SG
1127 case "$i" in
1128 -d|-m) only_local_ref="y" ;;
1129 -r) has_r="y" ;;
1130 esac
1131 c=$((++c))
1132 done
1133
da48616f 1134 case "$cur" in
3b376b0c
SG
1135 --*)
1136 __gitcomp "
1137 --color --no-color --verbose --abbrev= --no-abbrev
50e61025 1138 --track --no-track --contains --merged --no-merged
ff9c0825 1139 --set-upstream
3b376b0c
SG
1140 "
1141 ;;
b9217642
SG
1142 *)
1143 if [ $only_local_ref = "y" -a $has_r = "n" ]; then
1144 __gitcomp "$(__git_heads)"
1145 else
1146 __gitcomp "$(__git_refs)"
1147 fi
1148 ;;
3b376b0c 1149 esac
690d8824
JH
1150}
1151
374a58c9
ML
1152_git_bundle ()
1153{
da48616f
PD
1154 local cmd="${words[2]}"
1155 case "$cword" in
8d8163f3 1156 2)
374a58c9
ML
1157 __gitcomp "create list-heads verify unbundle"
1158 ;;
8d8163f3 1159 3)
374a58c9
ML
1160 # looking for a file
1161 ;;
1162 *)
1163 case "$cmd" in
1164 create)
1165 __git_complete_revlist
1166 ;;
1167 esac
1168 ;;
1169 esac
1170}
1171
690d8824
JH
1172_git_checkout ()
1173{
c84bb14c
SG
1174 __git_has_doubledash && return
1175
e648f8b6
SG
1176 case "$cur" in
1177 --conflict=*)
1178 __gitcomp "diff3 merge" "" "${cur##--conflict=}"
1179 ;;
1180 --*)
1181 __gitcomp "
1182 --quiet --ours --theirs --track --no-track --merge
86e8e7a5 1183 --conflict= --orphan --patch
e648f8b6
SG
1184 "
1185 ;;
1186 *)
34a6bbb5
KB
1187 # check if --track, --no-track, or --no-guess was specified
1188 # if so, disable DWIM mode
1189 local flags="--track --no-track --no-guess" track=1
1190 if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
1191 track=''
1192 fi
1193 __gitcomp "$(__git_refs '' $track)"
e648f8b6
SG
1194 ;;
1195 esac
690d8824
JH
1196}
1197
d8a9fea5
SP
1198_git_cherry ()
1199{
1200 __gitcomp "$(__git_refs)"
1201}
1202
1273231e
SP
1203_git_cherry_pick ()
1204{
1273231e
SP
1205 case "$cur" in
1206 --*)
b3391775 1207 __gitcomp "--edit --no-commit"
1273231e
SP
1208 ;;
1209 *)
b3391775 1210 __gitcomp "$(__git_refs)"
1273231e
SP
1211 ;;
1212 esac
1213}
1214
4181c7e8
LM
1215_git_clean ()
1216{
1217 __git_has_doubledash && return
1218
4181c7e8
LM
1219 case "$cur" in
1220 --*)
1221 __gitcomp "--dry-run --quiet"
1222 return
1223 ;;
1224 esac
1225 COMPREPLY=()
1226}
1227
3eb11012
LM
1228_git_clone ()
1229{
3eb11012
LM
1230 case "$cur" in
1231 --*)
1232 __gitcomp "
1233 --local
1234 --no-hardlinks
1235 --shared
1236 --reference
1237 --quiet
1238 --no-checkout
1239 --bare
1240 --mirror
1241 --origin
1242 --upload-pack
1243 --template=
1244 --depth
1245 "
1246 return
1247 ;;
1248 esac
1249 COMPREPLY=()
1250}
1251
4548e855
SP
1252_git_commit ()
1253{
d773c631
SG
1254 __git_has_doubledash && return
1255
4548e855 1256 case "$cur" in
9a424b27
SG
1257 --cleanup=*)
1258 __gitcomp "default strip verbatim whitespace
1259 " "" "${cur##--cleanup=}"
1260 return
1261 ;;
1262 --reuse-message=*)
1263 __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
1264 return
1265 ;;
1266 --reedit-message=*)
1267 __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
1268 return
1269 ;;
1270 --untracked-files=*)
1271 __gitcomp "all no normal" "" "${cur##--untracked-files=}"
1272 return
1273 ;;
4548e855 1274 --*)
b3391775 1275 __gitcomp "
4548e855 1276 --all --author= --signoff --verify --no-verify
aa5735be 1277 --edit --amend --include --only --interactive
9a424b27
SG
1278 --dry-run --reuse-message= --reedit-message=
1279 --reset-author --file= --message= --template=
1280 --cleanup= --untracked-files --untracked-files=
1281 --verbose --quiet
b3391775 1282 "
4548e855
SP
1283 return
1284 esac
1285 COMPREPLY=()
1286}
1287
217926c0
SP
1288_git_describe ()
1289{
cbb504c9
TR
1290 case "$cur" in
1291 --*)
1292 __gitcomp "
1293 --all --tags --contains --abbrev= --candidates=
1294 --exact-match --debug --long --match --always
1295 "
1296 return
1297 esac
217926c0
SP
1298 __gitcomp "$(__git_refs)"
1299}
1300
20bf7292 1301__git_diff_common_options="--stat --numstat --shortstat --summary
b3a4f858
JS
1302 --patch-with-stat --name-only --name-status --color
1303 --no-color --color-words --no-renames --check
f135aacb 1304 --full-index --binary --abbrev --diff-filter=
47d5a8fa 1305 --find-copies-harder
b3a4f858
JS
1306 --text --ignore-space-at-eol --ignore-space-change
1307 --ignore-all-space --exit-code --quiet --ext-diff
aba201c6
PO
1308 --no-ext-diff
1309 --no-prefix --src-prefix= --dst-prefix=
6d0e674a 1310 --inter-hunk-context=
cc545709 1311 --patience
20bf7292 1312 --raw
8fd2cfa7
SB
1313 --dirstat --dirstat= --dirstat-by-file
1314 --dirstat-by-file= --cumulative
20bf7292
TR
1315"
1316
1317_git_diff ()
1318{
1319 __git_has_doubledash && return
1320
20bf7292
TR
1321 case "$cur" in
1322 --*)
ebd15bf0 1323 __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
861514d3 1324 --base --ours --theirs --no-index
20bf7292 1325 $__git_diff_common_options
aba201c6 1326 "
b3a4f858
JS
1327 return
1328 ;;
1329 esac
1d66ec58 1330 __git_complete_revlist_file
690d8824
JH
1331}
1332
e2dc2de9 1333__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
ffe6dc08 1334 tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3
e2dc2de9
DA
1335"
1336
1337_git_difftool ()
1338{
f7ad96cf
MH
1339 __git_has_doubledash && return
1340
e2dc2de9
DA
1341 case "$cur" in
1342 --tool=*)
1343 __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
1344 return
1345 ;;
1346 --*)
f7ad96cf
MH
1347 __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1348 --base --ours --theirs
1349 --no-renames --diff-filter= --find-copies-harder
1350 --relative --ignore-submodules
1351 --tool="
e2dc2de9
DA
1352 return
1353 ;;
1354 esac
f7ad96cf 1355 __git_complete_file
e2dc2de9
DA
1356}
1357
0a4e1472
JS
1358__git_fetch_options="
1359 --quiet --verbose --append --upload-pack --force --keep --depth=
e25e2b42 1360 --tags --no-tags --all --prune --dry-run
0a4e1472
JS
1361"
1362
690d8824
JH
1363_git_fetch ()
1364{
0a4e1472
JS
1365 case "$cur" in
1366 --*)
1367 __gitcomp "$__git_fetch_options"
1368 return
1369 ;;
1370 esac
52d5c3b5 1371 __git_complete_remote_or_refspec
690d8824
JH
1372}
1373
f53352fb
SP
1374_git_format_patch ()
1375{
f53352fb 1376 case "$cur" in
e1d37937
SB
1377 --thread=*)
1378 __gitcomp "
1379 deep shallow
1380 " "" "${cur##--thread=}"
1381 return
1382 ;;
f53352fb 1383 --*)
b3391775 1384 __gitcomp "
e1d37937 1385 --stdout --attach --no-attach --thread --thread=
f53352fb
SP
1386 --output-directory
1387 --numbered --start-number
47e98eec 1388 --numbered-files
f53352fb 1389 --keep-subject
d8e1e5df 1390 --signoff --signature --no-signature
3f7df3a7 1391 --in-reply-to= --cc=
f53352fb 1392 --full-index --binary
ec804891 1393 --not --all
be5f5bf0 1394 --cover-letter
aba201c6 1395 --no-prefix --src-prefix= --dst-prefix=
81085134
SG
1396 --inline --suffix= --ignore-if-in-upstream
1397 --subject-prefix=
b3391775 1398 "
f53352fb
SP
1399 return
1400 ;;
1401 esac
1402 __git_complete_revlist
1403}
1404
4bca8636
AJ
1405_git_fsck ()
1406{
4bca8636
AJ
1407 case "$cur" in
1408 --*)
1409 __gitcomp "
1410 --tags --root --unreachable --cache --no-reflogs --full
1411 --strict --verbose --lost-found
1412 "
1413 return
1414 ;;
1415 esac
1416 COMPREPLY=()
1417}
1418
b26c8748
SP
1419_git_gc ()
1420{
b26c8748
SP
1421 case "$cur" in
1422 --*)
47e98eec 1423 __gitcomp "--prune --aggressive"
b26c8748
SP
1424 return
1425 ;;
1426 esac
1427 COMPREPLY=()
1428}
1429
66729509
SG
1430_git_gitk ()
1431{
1432 _gitk
1433}
1434
c72e0db1
LM
1435_git_grep ()
1436{
1437 __git_has_doubledash && return
1438
c72e0db1
LM
1439 case "$cur" in
1440 --*)
1441 __gitcomp "
1442 --cached
1443 --text --ignore-case --word-regexp --invert-match
1444 --full-name
1445 --extended-regexp --basic-regexp --fixed-strings
1446 --files-with-matches --name-only
1447 --files-without-match
a91f453f 1448 --max-depth
c72e0db1
LM
1449 --count
1450 --and --or --not --all-match
1451 "
1452 return
1453 ;;
1454 esac
17225c49
TR
1455
1456 __gitcomp "$(__git_refs)"
c72e0db1
LM
1457}
1458
1eb7e2f8
LM
1459_git_help ()
1460{
1eb7e2f8
LM
1461 case "$cur" in
1462 --*)
1463 __gitcomp "--all --info --man --web"
1464 return
1465 ;;
1466 esac
eaa4e6ee 1467 __git_compute_all_commands
f85a6f0b 1468 __gitcomp "$__git_all_commands $(__git_aliases)
2946cccf
MG
1469 attributes cli core-tutorial cvs-migration
1470 diffcore gitk glossary hooks ignore modules
1471 repository-layout tutorial tutorial-2
99f0b599 1472 workflows
2946cccf 1473 "
1eb7e2f8
LM
1474}
1475
5dad868b
LM
1476_git_init ()
1477{
5dad868b
LM
1478 case "$cur" in
1479 --shared=*)
1480 __gitcomp "
1481 false true umask group all world everybody
1482 " "" "${cur##--shared=}"
1483 return
1484 ;;
1485 --*)
1486 __gitcomp "--quiet --bare --template= --shared --shared="
1487 return
1488 ;;
1489 esac
1490 COMPREPLY=()
1491}
1492
b1bc1494
LM
1493_git_ls_files ()
1494{
1495 __git_has_doubledash && return
1496
b1bc1494
LM
1497 case "$cur" in
1498 --*)
1499 __gitcomp "--cached --deleted --modified --others --ignored
1500 --stage --directory --no-empty-directory --unmerged
1501 --killed --exclude= --exclude-from=
1502 --exclude-per-directory= --exclude-standard
1503 --error-unmatch --with-tree= --full-name
1504 --abbrev --ignored --exclude-per-directory
1505 "
1506 return
1507 ;;
1508 esac
1509 COMPREPLY=()
1510}
1511
690d8824
JH
1512_git_ls_remote ()
1513{
b3391775 1514 __gitcomp "$(__git_remotes)"
690d8824
JH
1515}
1516
1517_git_ls_tree ()
1518{
1519 __git_complete_file
1520}
1521
a393777e
TR
1522# Options that go well for log, shortlog and gitk
1523__git_log_common_options="
1524 --not --all
1525 --branches --tags --remotes
4fe1a619 1526 --first-parent --merges --no-merges
a393777e
TR
1527 --max-count=
1528 --max-age= --since= --after=
1529 --min-age= --until= --before=
6a6ebded
MG
1530 --min-parents= --max-parents=
1531 --no-min-parents --no-max-parents
a393777e
TR
1532"
1533# Options that go well for log and gitk (not shortlog)
1534__git_log_gitk_options="
1535 --dense --sparse --full-history
1536 --simplify-merges --simplify-by-decoration
1537 --left-right
1538"
1539# Options that go well for log and shortlog (not gitk)
1540__git_log_shortlog_options="
1541 --author= --committer= --grep=
1542 --all-match
1543"
1544
3d279863 1545__git_log_pretty_formats="oneline short medium full fuller email raw format:"
672c68cb 1546__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
3d279863 1547
690d8824
JH
1548_git_log ()
1549{
d773c631
SG
1550 __git_has_doubledash && return
1551
bf3c20f6
TR
1552 local g="$(git rev-parse --git-dir 2>/dev/null)"
1553 local merge=""
ba7906f2 1554 if [ -f "$g/MERGE_HEAD" ]; then
bf3c20f6
TR
1555 merge="--merge"
1556 fi
6e31b866
SP
1557 case "$cur" in
1558 --pretty=*)
c3898111 1559 __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
b3391775 1560 " "" "${cur##--pretty=}"
6e31b866
SP
1561 return
1562 ;;
72de29c2 1563 --format=*)
c3898111 1564 __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
72de29c2
TL
1565 " "" "${cur##--format=}"
1566 return
1567 ;;
47e98eec 1568 --date=*)
672c68cb 1569 __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
47e98eec
SP
1570 return
1571 ;;
af4e9e8c
SB
1572 --decorate=*)
1573 __gitcomp "long short" "" "${cur##--decorate=}"
1574 return
1575 ;;
6e31b866 1576 --*)
b3391775 1577 __gitcomp "
a393777e
TR
1578 $__git_log_common_options
1579 $__git_log_shortlog_options
1580 $__git_log_gitk_options
8f87fae6 1581 --root --topo-order --date-order --reverse
5d0e6343 1582 --follow --full-diff
6e31b866 1583 --abbrev-commit --abbrev=
47e98eec 1584 --relative-date --date=
72de29c2 1585 --pretty= --format= --oneline
a393777e 1586 --cherry-pick
20827d99 1587 --graph
af4e9e8c 1588 --decorate --decorate=
20bf7292 1589 --walk-reflogs
a393777e 1590 --parents --children
bf3c20f6 1591 $merge
20bf7292 1592 $__git_diff_common_options
47d5a8fa 1593 --pickaxe-all --pickaxe-regex
b3391775 1594 "
6e31b866
SP
1595 return
1596 ;;
1597 esac
f53352fb 1598 __git_complete_revlist
690d8824
JH
1599}
1600
0a4e1472
JS
1601__git_merge_options="
1602 --no-commit --no-stat --log --no-log --squash --strategy
9858b87f 1603 --commit --stat --no-squash --ff --no-ff --ff-only
0a4e1472
JS
1604"
1605
4ad91321
SP
1606_git_merge ()
1607{
3c7b480a
JS
1608 __git_complete_strategy && return
1609
4ad91321
SP
1610 case "$cur" in
1611 --*)
0a4e1472 1612 __gitcomp "$__git_merge_options"
4ad91321
SP
1613 return
1614 esac
b3391775 1615 __gitcomp "$(__git_refs)"
4ad91321
SP
1616}
1617
b4c72162
LM
1618_git_mergetool ()
1619{
b4c72162
LM
1620 case "$cur" in
1621 --tool=*)
e2dc2de9 1622 __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
b4c72162
LM
1623 return
1624 ;;
1625 --*)
1626 __gitcomp "--tool="
1627 return
1628 ;;
1629 esac
1630 COMPREPLY=()
1631}
1632
690d8824
JH
1633_git_merge_base ()
1634{
b3391775 1635 __gitcomp "$(__git_refs)"
690d8824
JH
1636}
1637
1127c51c
LM
1638_git_mv ()
1639{
1127c51c
LM
1640 case "$cur" in
1641 --*)
1642 __gitcomp "--dry-run"
1643 return
1644 ;;
1645 esac
1646 COMPREPLY=()
1647}
1648
d33909bf
SP
1649_git_name_rev ()
1650{
b3391775 1651 __gitcomp "--tags --all --stdin"
d33909bf
SP
1652}
1653
00f09d0e
SG
1654_git_notes ()
1655{
2a5da755
SG
1656 local subcommands='add append copy edit list prune remove show'
1657 local subcommand="$(__git_find_on_cmdline "$subcommands")"
00f09d0e 1658
2a5da755
SG
1659 case "$subcommand,$cur" in
1660 ,--*)
1661 __gitcomp '--ref'
1662 ;;
1663 ,*)
02fedc0f 1664 case "${words[cword-1]}" in
2a5da755
SG
1665 --ref)
1666 __gitcomp "$(__git_refs)"
1667 ;;
1668 *)
1669 __gitcomp "$subcommands --ref"
1670 ;;
1671 esac
1672 ;;
1673 add,--reuse-message=*|append,--reuse-message=*)
1674 __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
1675 ;;
1676 add,--reedit-message=*|append,--reedit-message=*)
1677 __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
1678 ;;
1679 add,--*|append,--*)
1680 __gitcomp '--file= --message= --reedit-message=
1681 --reuse-message='
1682 ;;
1683 copy,--*)
1684 __gitcomp '--stdin'
1685 ;;
1686 prune,--*)
1687 __gitcomp '--dry-run --verbose'
1688 ;;
1689 prune,*)
00f09d0e
SG
1690 ;;
1691 *)
02fedc0f 1692 case "${words[cword-1]}" in
2a5da755
SG
1693 -m|-F)
1694 ;;
1695 *)
1696 __gitcomp "$(__git_refs)"
1697 ;;
1698 esac
00f09d0e
SG
1699 ;;
1700 esac
1701}
1702
690d8824
JH
1703_git_pull ()
1704{
0a4e1472
JS
1705 __git_complete_strategy && return
1706
0a4e1472
JS
1707 case "$cur" in
1708 --*)
1709 __gitcomp "
1710 --rebase --no-rebase
1711 $__git_merge_options
1712 $__git_fetch_options
1713 "
1714 return
1715 ;;
1716 esac
52d5c3b5 1717 __git_complete_remote_or_refspec
690d8824
JH
1718}
1719
1720_git_push ()
1721{
da48616f 1722 case "$prev" in
0a4e1472
JS
1723 --repo)
1724 __gitcomp "$(__git_remotes)"
1725 return
1726 esac
1727 case "$cur" in
1728 --repo=*)
1729 __gitcomp "$(__git_remotes)" "" "${cur##--repo=}"
1730 return
1731 ;;
1732 --*)
1733 __gitcomp "
1734 --all --mirror --tags --dry-run --force --verbose
1735 --receive-pack= --repo=
1736 "
1737 return
1738 ;;
1739 esac
52d5c3b5 1740 __git_complete_remote_or_refspec
690d8824
JH
1741}
1742
61d926a3
SP
1743_git_rebase ()
1744{
da48616f 1745 local dir="$(__gitdir)"
51ef1daa 1746 if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
b3391775 1747 __gitcomp "--continue --skip --abort"
61d926a3
SP
1748 return
1749 fi
3c7b480a 1750 __git_complete_strategy && return
61d926a3 1751 case "$cur" in
93cf50a4
BG
1752 --whitespace=*)
1753 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1754 return
1755 ;;
61d926a3 1756 --*)
93cf50a4
BG
1757 __gitcomp "
1758 --onto --merge --strategy --interactive
1759 --preserve-merges --stat --no-stat
1760 --committer-date-is-author-date --ignore-date
1761 --ignore-whitespace --whitespace=
6d0d465e 1762 --autosquash
93cf50a4
BG
1763 "
1764
61d926a3
SP
1765 return
1766 esac
b3391775 1767 __gitcomp "$(__git_refs)"
61d926a3
SP
1768}
1769
057f3279
TRC
1770_git_reflog ()
1771{
1772 local subcommands="show delete expire"
1773 local subcommand="$(__git_find_on_cmdline "$subcommands")"
1774
1775 if [ -z "$subcommand" ]; then
1776 __gitcomp "$subcommands"
1777 else
1778 __gitcomp "$(__git_refs)"
1779 fi
1780}
1781
ae616de6 1782__git_send_email_confirm_options="always never auto cc compose"
cb8a9bd5 1783__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
ae616de6 1784
25a1f374
TL
1785_git_send_email ()
1786{
25a1f374 1787 case "$cur" in
ae616de6
SB
1788 --confirm=*)
1789 __gitcomp "
1790 $__git_send_email_confirm_options
1791 " "" "${cur##--confirm=}"
1792 return
1793 ;;
1794 --suppress-cc=*)
1795 __gitcomp "
1796 $__git_send_email_suppresscc_options
1797 " "" "${cur##--suppress-cc=}"
1798
1799 return
1800 ;;
1801 --smtp-encryption=*)
1802 __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
1803 return
1804 ;;
25a1f374 1805 --*)
77813151 1806 __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
ae616de6
SB
1807 --compose --confirm= --dry-run --envelope-sender
1808 --from --identity
25a1f374
TL
1809 --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1810 --no-suppress-from --no-thread --quiet
1811 --signed-off-by-cc --smtp-pass --smtp-server
ae616de6
SB
1812 --smtp-server-port --smtp-encryption= --smtp-user
1813 --subject --suppress-cc= --suppress-from --thread --to
fd3a8dcb 1814 --validate --no-validate"
25a1f374
TL
1815 return
1816 ;;
1817 esac
1818 COMPREPLY=()
1819}
1820
424cce83
SG
1821_git_stage ()
1822{
1823 _git_add
1824}
1825
00652369
SB
1826__git_config_get_set_variables ()
1827{
da48616f 1828 local prevword word config_file= c=$cword
00652369 1829 while [ $c -gt 1 ]; do
da48616f 1830 word="${words[c]}"
00652369
SB
1831 case "$word" in
1832 --global|--system|--file=*)
1833 config_file="$word"
1834 break
1835 ;;
1836 -f|--file)
1837 config_file="$word $prevword"
1838 break
1839 ;;
1840 esac
1841 prevword=$word
1842 c=$((--c))
1843 done
1844
f581de1b
SB
1845 git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1846 while read line
1847 do
1848 case "$line" in
1849 *.*=*)
1850 echo "${line/=*/}"
00652369
SB
1851 ;;
1852 esac
1853 done
1854}
1855
e0d10e1c 1856_git_config ()
5de40f59 1857{
da48616f 1858 case "$prev" in
5de40f59 1859 branch.*.remote)
78d4d6a2 1860 __gitcomp "$(__git_remotes)"
5de40f59
SP
1861 return
1862 ;;
1863 branch.*.merge)
78d4d6a2 1864 __gitcomp "$(__git_refs)"
5de40f59
SP
1865 return
1866 ;;
1867 remote.*.fetch)
da48616f 1868 local remote="${prev#remote.}"
5de40f59 1869 remote="${remote%.fetch}"
78d4d6a2 1870 __gitcomp "$(__git_refs_remotes "$remote")"
5de40f59
SP
1871 return
1872 ;;
1873 remote.*.push)
da48616f 1874 local remote="${prev#remote.}"
5de40f59 1875 remote="${remote%.push}"
78d4d6a2 1876 __gitcomp "$(git --git-dir="$(__gitdir)" \
5de40f59 1877 for-each-ref --format='%(refname):%(refname)' \
78d4d6a2
SP
1878 refs/heads)"
1879 return
1880 ;;
1881 pull.twohead|pull.octopus)
eaa4e6ee
JN
1882 __git_compute_merge_strategies
1883 __gitcomp "$__git_merge_strategies"
78d4d6a2
SP
1884 return
1885 ;;
6123d719
MH
1886 color.branch|color.diff|color.interactive|\
1887 color.showbranch|color.status|color.ui)
78d4d6a2
SP
1888 __gitcomp "always never auto"
1889 return
1890 ;;
901d615c
MK
1891 color.pager)
1892 __gitcomp "false true"
1893 return
1894 ;;
78d4d6a2
SP
1895 color.*.*)
1896 __gitcomp "
98171a07 1897 normal black red green yellow blue magenta cyan white
78d4d6a2
SP
1898 bold dim ul blink reverse
1899 "
5de40f59
SP
1900 return
1901 ;;
9b82d63b
SB
1902 help.format)
1903 __gitcomp "man info web html"
1904 return
1905 ;;
672c68cb
SB
1906 log.date)
1907 __gitcomp "$__git_log_date_formats"
1908 return
1909 ;;
ae616de6
SB
1910 sendemail.aliasesfiletype)
1911 __gitcomp "mutt mailrc pine elm gnus"
1912 return
1913 ;;
1914 sendemail.confirm)
1915 __gitcomp "$__git_send_email_confirm_options"
1916 return
1917 ;;
1918 sendemail.suppresscc)
1919 __gitcomp "$__git_send_email_suppresscc_options"
1920 return
1921 ;;
00652369
SB
1922 --get|--get-all|--unset|--unset-all)
1923 __gitcomp "$(__git_config_get_set_variables)"
1924 return
1925 ;;
5de40f59
SP
1926 *.*)
1927 COMPREPLY=()
1928 return
1929 ;;
1930 esac
1931 case "$cur" in
1932 --*)
78d4d6a2 1933 __gitcomp "
47e98eec 1934 --global --system --file=
12977705 1935 --list --replace-all
5de40f59 1936 --get --get-all --get-regexp
1b71eb35 1937 --add --unset --unset-all
12977705 1938 --remove-section --rename-section
78d4d6a2 1939 "
5de40f59
SP
1940 return
1941 ;;
1942 branch.*.*)
9244d69b
SG
1943 local pfx="${cur%.*}." cur_="${cur##*.}"
1944 __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur_"
5de40f59
SP
1945 return
1946 ;;
1947 branch.*)
9244d69b
SG
1948 local pfx="${cur%.*}." cur_="${cur#*.}"
1949 __gitcomp "$(__git_heads)" "$pfx" "$cur_" "."
5de40f59
SP
1950 return
1951 ;;
0aa62fd0 1952 guitool.*.*)
9244d69b 1953 local pfx="${cur%.*}." cur_="${cur##*.}"
0aa62fd0
SB
1954 __gitcomp "
1955 argprompt cmd confirm needsfile noconsole norescan
1956 prompt revprompt revunmerged title
9244d69b 1957 " "$pfx" "$cur_"
0aa62fd0
SB
1958 return
1959 ;;
1960 difftool.*.*)
9244d69b
SG
1961 local pfx="${cur%.*}." cur_="${cur##*.}"
1962 __gitcomp "cmd path" "$pfx" "$cur_"
0aa62fd0
SB
1963 return
1964 ;;
1965 man.*.*)
9244d69b
SG
1966 local pfx="${cur%.*}." cur_="${cur##*.}"
1967 __gitcomp "cmd path" "$pfx" "$cur_"
0aa62fd0
SB
1968 return
1969 ;;
1970 mergetool.*.*)
9244d69b
SG
1971 local pfx="${cur%.*}." cur_="${cur##*.}"
1972 __gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
0aa62fd0
SB
1973 return
1974 ;;
1975 pager.*)
9244d69b 1976 local pfx="${cur%.*}." cur_="${cur#*.}"
eaa4e6ee 1977 __git_compute_all_commands
9244d69b 1978 __gitcomp "$__git_all_commands" "$pfx" "$cur_"
0aa62fd0
SB
1979 return
1980 ;;
5de40f59 1981 remote.*.*)
9244d69b 1982 local pfx="${cur%.*}." cur_="${cur##*.}"
12977705 1983 __gitcomp "
98171a07 1984 url proxy fetch push mirror skipDefaultUpdate
6fac1b83 1985 receivepack uploadpack tagopt pushurl
9244d69b 1986 " "$pfx" "$cur_"
5de40f59
SP
1987 return
1988 ;;
1989 remote.*)
9244d69b
SG
1990 local pfx="${cur%.*}." cur_="${cur#*.}"
1991 __gitcomp "$(__git_remotes)" "$pfx" "$cur_" "."
5de40f59
SP
1992 return
1993 ;;
0aa62fd0 1994 url.*.*)
9244d69b
SG
1995 local pfx="${cur%.*}." cur_="${cur##*.}"
1996 __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
0aa62fd0
SB
1997 return
1998 ;;
5de40f59 1999 esac
78d4d6a2 2000 __gitcomp "
6068ac88
MZ
2001 add.ignoreErrors
2002 advice.commitBeforeMerge
2003 advice.detachedHead
2004 advice.implicitIdentity
2005 advice.pushNonFastForward
2006 advice.resolveConflict
2007 advice.statusHints
226b343c 2008 alias.
6068ac88 2009 am.keepcr
86c91f91 2010 apply.ignorewhitespace
5de40f59 2011 apply.whitespace
98171a07
LM
2012 branch.autosetupmerge
2013 branch.autosetuprebase
6068ac88 2014 browser.
2122591b 2015 clean.requireForce
78d4d6a2
SP
2016 color.branch
2017 color.branch.current
2018 color.branch.local
78d4d6a2 2019 color.branch.plain
025a1929 2020 color.branch.remote
6068ac88
MZ
2021 color.decorate.HEAD
2022 color.decorate.branch
2023 color.decorate.remoteBranch
2024 color.decorate.stash
2025 color.decorate.tag
a159ca0c 2026 color.diff
025a1929 2027 color.diff.commit
78d4d6a2 2028 color.diff.frag
6068ac88 2029 color.diff.func
025a1929 2030 color.diff.meta
78d4d6a2 2031 color.diff.new
025a1929
LM
2032 color.diff.old
2033 color.diff.plain
78d4d6a2 2034 color.diff.whitespace
226b343c 2035 color.grep
6068ac88
MZ
2036 color.grep.context
2037 color.grep.filename
2038 color.grep.function
2039 color.grep.linenumber
226b343c 2040 color.grep.match
6068ac88
MZ
2041 color.grep.selected
2042 color.grep.separator
98171a07 2043 color.interactive
6068ac88 2044 color.interactive.error
98171a07
LM
2045 color.interactive.header
2046 color.interactive.help
2047 color.interactive.prompt
a159ca0c 2048 color.pager
6123d719 2049 color.showbranch
a159ca0c 2050 color.status
78d4d6a2
SP
2051 color.status.added
2052 color.status.changed
025a1929 2053 color.status.header
98171a07 2054 color.status.nobranch
78d4d6a2 2055 color.status.untracked
98171a07
LM
2056 color.status.updated
2057 color.ui
6068ac88 2058 commit.status
98171a07 2059 commit.template
6068ac88
MZ
2060 core.abbrevguard
2061 core.askpass
2062 core.attributesfile
98171a07
LM
2063 core.autocrlf
2064 core.bare
6068ac88 2065 core.bigFileThreshold
025a1929 2066 core.compression
226b343c 2067 core.createObject
98171a07
LM
2068 core.deltaBaseCacheLimit
2069 core.editor
6068ac88 2070 core.eol
98171a07 2071 core.excludesfile
025a1929 2072 core.fileMode
98171a07 2073 core.fsyncobjectfiles
025a1929 2074 core.gitProxy
98171a07 2075 core.ignoreCygwinFSTricks
025a1929 2076 core.ignoreStat
6068ac88 2077 core.ignorecase
025a1929
LM
2078 core.logAllRefUpdates
2079 core.loosecompression
6068ac88 2080 core.notesRef
025a1929
LM
2081 core.packedGitLimit
2082 core.packedGitWindowSize
98171a07 2083 core.pager
025a1929 2084 core.preferSymlinkRefs
98171a07
LM
2085 core.preloadindex
2086 core.quotepath
025a1929 2087 core.repositoryFormatVersion
98171a07 2088 core.safecrlf
025a1929 2089 core.sharedRepository
6068ac88 2090 core.sparseCheckout
98171a07
LM
2091 core.symlinks
2092 core.trustctime
025a1929 2093 core.warnAmbiguousRefs
98171a07
LM
2094 core.whitespace
2095 core.worktree
2096 diff.autorefreshindex
2097 diff.external
6068ac88 2098 diff.ignoreSubmodules
98171a07 2099 diff.mnemonicprefix
6068ac88 2100 diff.noprefix
78d4d6a2
SP
2101 diff.renameLimit
2102 diff.renames
226b343c
SB
2103 diff.suppressBlankEmpty
2104 diff.tool
2105 diff.wordRegex
0aa62fd0 2106 difftool.
226b343c 2107 difftool.prompt
6068ac88 2108 fetch.recurseSubmodules
78d4d6a2 2109 fetch.unpackLimit
226b343c
SB
2110 format.attach
2111 format.cc
78d4d6a2 2112 format.headers
98171a07
LM
2113 format.numbered
2114 format.pretty
d8e1e5df 2115 format.signature
226b343c
SB
2116 format.signoff
2117 format.subjectprefix
98171a07 2118 format.suffix
226b343c 2119 format.thread
6068ac88
MZ
2120 format.to
2121 gc.
98171a07
LM
2122 gc.aggressiveWindow
2123 gc.auto
2124 gc.autopacklimit
12977705 2125 gc.packrefs
98171a07 2126 gc.pruneexpire
78d4d6a2
SP
2127 gc.reflogexpire
2128 gc.reflogexpireunreachable
2129 gc.rerereresolved
2130 gc.rerereunresolved
025a1929 2131 gitcvs.allbinary
226b343c 2132 gitcvs.commitmsgannotation
98171a07 2133 gitcvs.dbTableNamePrefix
025a1929
LM
2134 gitcvs.dbdriver
2135 gitcvs.dbname
2136 gitcvs.dbpass
025a1929
LM
2137 gitcvs.dbuser
2138 gitcvs.enabled
2139 gitcvs.logfile
98171a07 2140 gitcvs.usecrlfattr
0aa62fd0 2141 guitool.
98171a07
LM
2142 gui.blamehistoryctx
2143 gui.commitmsgwidth
2144 gui.copyblamethreshold
2145 gui.diffcontext
2146 gui.encoding
2147 gui.fastcopyblame
2148 gui.matchtrackingbranch
2149 gui.newbranchtemplate
2150 gui.pruneduringfetch
2151 gui.spellingdictionary
2152 gui.trustmtime
2153 help.autocorrect
2154 help.browser
2155 help.format
78d4d6a2
SP
2156 http.lowSpeedLimit
2157 http.lowSpeedTime
025a1929 2158 http.maxRequests
6068ac88 2159 http.minSessions
5de40f59 2160 http.noEPSV
6068ac88 2161 http.postBuffer
98171a07 2162 http.proxy
025a1929
LM
2163 http.sslCAInfo
2164 http.sslCAPath
2165 http.sslCert
6068ac88 2166 http.sslCertPasswordProtected
025a1929
LM
2167 http.sslKey
2168 http.sslVerify
6068ac88 2169 http.useragent
78d4d6a2
SP
2170 i18n.commitEncoding
2171 i18n.logOutputEncoding
6068ac88 2172 imap.authMethod
226b343c
SB
2173 imap.folder
2174 imap.host
2175 imap.pass
2176 imap.port
2177 imap.preformattedHTML
2178 imap.sslverify
2179 imap.tunnel
2180 imap.user
6068ac88 2181 init.templatedir
98171a07
LM
2182 instaweb.browser
2183 instaweb.httpd
2184 instaweb.local
2185 instaweb.modulepath
2186 instaweb.port
226b343c 2187 interactive.singlekey
98171a07 2188 log.date
6068ac88 2189 log.decorate
78d4d6a2 2190 log.showroot
226b343c 2191 mailmap.file
0aa62fd0 2192 man.
98171a07 2193 man.viewer
6068ac88 2194 merge.
98171a07
LM
2195 merge.conflictstyle
2196 merge.log
2197 merge.renameLimit
6068ac88 2198 merge.renormalize
98171a07 2199 merge.stat
025a1929 2200 merge.tool
78d4d6a2 2201 merge.verbosity
0aa62fd0 2202 mergetool.
98171a07 2203 mergetool.keepBackup
6068ac88 2204 mergetool.keepTemporaries
226b343c 2205 mergetool.prompt
6068ac88
MZ
2206 notes.displayRef
2207 notes.rewrite.
2208 notes.rewrite.amend
2209 notes.rewrite.rebase
2210 notes.rewriteMode
2211 notes.rewriteRef
47e98eec 2212 pack.compression
47e98eec 2213 pack.deltaCacheLimit
025a1929
LM
2214 pack.deltaCacheSize
2215 pack.depth
98171a07
LM
2216 pack.indexVersion
2217 pack.packSizeLimit
2218 pack.threads
025a1929
LM
2219 pack.window
2220 pack.windowMemory
0aa62fd0 2221 pager.
6068ac88 2222 pretty.
78d4d6a2
SP
2223 pull.octopus
2224 pull.twohead
226b343c 2225 push.default
6068ac88 2226 rebase.autosquash
226b343c 2227 rebase.stat
6068ac88 2228 receive.autogc
98171a07 2229 receive.denyCurrentBranch
6068ac88 2230 receive.denyDeleteCurrent
98171a07 2231 receive.denyDeletes
025a1929 2232 receive.denyNonFastForwards
98171a07 2233 receive.fsckObjects
025a1929 2234 receive.unpackLimit
6068ac88
MZ
2235 receive.updateserverinfo
2236 remotes.
98171a07
LM
2237 repack.usedeltabaseoffset
2238 rerere.autoupdate
2239 rerere.enabled
6068ac88 2240 sendemail.
226b343c 2241 sendemail.aliasesfile
6068ac88 2242 sendemail.aliasfiletype
226b343c
SB
2243 sendemail.bcc
2244 sendemail.cc
2245 sendemail.cccmd
2246 sendemail.chainreplyto
2247 sendemail.confirm
2248 sendemail.envelopesender
6068ac88
MZ
2249 sendemail.from
2250 sendemail.identity
226b343c
SB
2251 sendemail.multiedit
2252 sendemail.signedoffbycc
6068ac88 2253 sendemail.smtpdomain
226b343c
SB
2254 sendemail.smtpencryption
2255 sendemail.smtppass
2256 sendemail.smtpserver
6068ac88 2257 sendemail.smtpserveroption
226b343c
SB
2258 sendemail.smtpserverport
2259 sendemail.smtpuser
2260 sendemail.suppresscc
2261 sendemail.suppressfrom
2262 sendemail.thread
2263 sendemail.to
2264 sendemail.validate
78d4d6a2 2265 showbranch.default
98171a07
LM
2266 status.relativePaths
2267 status.showUntrackedFiles
6068ac88
MZ
2268 status.submodulesummary
2269 submodule.
78d4d6a2
SP
2270 tar.umask
2271 transfer.unpackLimit
0aa62fd0 2272 url.
78d4d6a2 2273 user.email
025a1929 2274 user.name
78d4d6a2 2275 user.signingkey
98171a07 2276 web.browser
5de40f59 2277 branch. remote.
78d4d6a2 2278 "
5de40f59
SP
2279}
2280
88293c67
SP
2281_git_remote ()
2282{
bc14fac8 2283 local subcommands="add rename rm show prune update set-head"
918c03c2 2284 local subcommand="$(__git_find_on_cmdline "$subcommands")"
3ff1320d 2285 if [ -z "$subcommand" ]; then
3903c618 2286 __gitcomp "$subcommands"
88293c67
SP
2287 return
2288 fi
2289
3ff1320d 2290 case "$subcommand" in
f135e72d 2291 rename|rm|show|prune)
88293c67
SP
2292 __gitcomp "$(__git_remotes)"
2293 ;;
fb72759b
SP
2294 update)
2295 local i c='' IFS=$'\n'
518ef8f0
TZ
2296 for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
2297 i="${i#remotes.}"
2298 c="$c ${i/ */}"
fb72759b
SP
2299 done
2300 __gitcomp "$c"
2301 ;;
88293c67
SP
2302 *)
2303 COMPREPLY=()
2304 ;;
2305 esac
2306}
2307
e1c1a067
BG
2308_git_replace ()
2309{
2310 __gitcomp "$(__git_refs)"
2311}
2312
67e78c3b
SP
2313_git_reset ()
2314{
d773c631
SG
2315 __git_has_doubledash && return
2316
b3391775
SP
2317 case "$cur" in
2318 --*)
9f040e95 2319 __gitcomp "--merge --mixed --hard --soft --patch"
b3391775
SP
2320 return
2321 ;;
2322 esac
2323 __gitcomp "$(__git_refs)"
67e78c3b
SP
2324}
2325
a6c2be24
LM
2326_git_revert ()
2327{
a6c2be24
LM
2328 case "$cur" in
2329 --*)
2330 __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
2331 return
2332 ;;
2333 esac
c0783837 2334 __gitcomp "$(__git_refs)"
a6c2be24
LM
2335}
2336
08c701d4
LM
2337_git_rm ()
2338{
2339 __git_has_doubledash && return
2340
08c701d4
LM
2341 case "$cur" in
2342 --*)
2343 __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
2344 return
2345 ;;
2346 esac
2347 COMPREPLY=()
2348}
2349
1fd6bec9
SP
2350_git_shortlog ()
2351{
d773c631
SG
2352 __git_has_doubledash && return
2353
1fd6bec9
SP
2354 case "$cur" in
2355 --*)
2356 __gitcomp "
a393777e
TR
2357 $__git_log_common_options
2358 $__git_log_shortlog_options
1fd6bec9
SP
2359 --numbered --summary
2360 "
2361 return
2362 ;;
2363 esac
2364 __git_complete_revlist
2365}
2366
90131924
SP
2367_git_show ()
2368{
41d8cf7d
MH
2369 __git_has_doubledash && return
2370
90131924
SP
2371 case "$cur" in
2372 --pretty=*)
c3898111 2373 __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
b3391775 2374 " "" "${cur##--pretty=}"
90131924
SP
2375 return
2376 ;;
72de29c2 2377 --format=*)
c3898111 2378 __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
72de29c2
TL
2379 " "" "${cur##--format=}"
2380 return
2381 ;;
90131924 2382 --*)
076c3237 2383 __gitcomp "--pretty= --format= --abbrev-commit --oneline
20bf7292
TR
2384 $__git_diff_common_options
2385 "
90131924
SP
2386 return
2387 ;;
2388 esac
2389 __git_complete_file
2390}
2391
2ca880fe
TR
2392_git_show_branch ()
2393{
2ca880fe
TR
2394 case "$cur" in
2395 --*)
2396 __gitcomp "
2397 --all --remotes --topo-order --current --more=
2398 --list --independent --merge-base --no-name
6123d719 2399 --color --no-color
076c3237 2400 --sha1-name --sparse --topics --reflog
2ca880fe
TR
2401 "
2402 return
2403 ;;
2404 esac
2405 __git_complete_revlist
2406}
2407
7fd53fce
JH
2408_git_stash ()
2409{
59d5eeee 2410 local save_opts='--keep-index --no-keep-index --quiet --patch'
95d43780 2411 local subcommands='save list show apply clear drop pop create branch'
918c03c2 2412 local subcommand="$(__git_find_on_cmdline "$subcommands")"
7bedebca 2413 if [ -z "$subcommand" ]; then
59d5eeee
SG
2414 case "$cur" in
2415 --*)
2416 __gitcomp "$save_opts"
2417 ;;
2418 *)
2419 if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
2420 __gitcomp "$subcommands"
2421 else
2422 COMPREPLY=()
2423 fi
2424 ;;
2425 esac
7bedebca 2426 else
7bedebca
SG
2427 case "$subcommand,$cur" in
2428 save,--*)
59d5eeee 2429 __gitcomp "$save_opts"
7bedebca 2430 ;;
8513c54b 2431 apply,--*|pop,--*)
59d5eeee 2432 __gitcomp "--index --quiet"
95d43780 2433 ;;
8513c54b 2434 show,--*|drop,--*|branch,--*)
95d43780
LM
2435 COMPREPLY=()
2436 ;;
2437 show,*|apply,*|drop,*|pop,*|branch,*)
2438 __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
2439 | sed -n -e 's/:.*//p')"
2440 ;;
7bedebca
SG
2441 *)
2442 COMPREPLY=()
2443 ;;
2444 esac
3ff1320d 2445 fi
7fd53fce
JH
2446}
2447
be86f7a0
SP
2448_git_submodule ()
2449{
d773c631
SG
2450 __git_has_doubledash && return
2451
1b0f7978 2452 local subcommands="add status init update summary foreach sync"
918c03c2 2453 if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
be86f7a0
SP
2454 case "$cur" in
2455 --*)
2456 __gitcomp "--quiet --cached"
2457 ;;
2458 *)
3ff1320d 2459 __gitcomp "$subcommands"
be86f7a0
SP
2460 ;;
2461 esac
2462 return
2463 fi
2464}
2465
47f6ee28
SG
2466_git_svn ()
2467{
2468 local subcommands="
2469 init fetch clone rebase dcommit log find-rev
2470 set-tree commit-diff info create-ignore propget
4a5856cb 2471 proplist show-ignore show-externals branch tag blame
c18d5d82 2472 migrate mkdirs reset gc
47f6ee28 2473 "
918c03c2 2474 local subcommand="$(__git_find_on_cmdline "$subcommands")"
47f6ee28
SG
2475 if [ -z "$subcommand" ]; then
2476 __gitcomp "$subcommands"
2477 else
2478 local remote_opts="--username= --config-dir= --no-auth-cache"
2479 local fc_opts="
2480 --follow-parent --authors-file= --repack=
2481 --no-metadata --use-svm-props --use-svnsync-props
2482 --log-window-size= --no-checkout --quiet
4a5856cb
SG
2483 --repack-flags --use-log-author --localtime
2484 --ignore-paths= $remote_opts
47f6ee28
SG
2485 "
2486 local init_opts="
2487 --template= --shared= --trunk= --tags=
2488 --branches= --stdlayout --minimize-url
2489 --no-metadata --use-svm-props --use-svnsync-props
4a5856cb
SG
2490 --rewrite-root= --prefix= --use-log-author
2491 --add-author-from $remote_opts
47f6ee28
SG
2492 "
2493 local cmt_opts="
2494 --edit --rmdir --find-copies-harder --copy-similarity=
2495 "
2496
47f6ee28
SG
2497 case "$subcommand,$cur" in
2498 fetch,--*)
2499 __gitcomp "--revision= --fetch-all $fc_opts"
2500 ;;
2501 clone,--*)
2502 __gitcomp "--revision= $fc_opts $init_opts"
2503 ;;
2504 init,--*)
2505 __gitcomp "$init_opts"
2506 ;;
2507 dcommit,--*)
2508 __gitcomp "
2509 --merge --strategy= --verbose --dry-run
4a5856cb
SG
2510 --fetch-all --no-rebase --commit-url
2511 --revision $cmt_opts $fc_opts
47f6ee28
SG
2512 "
2513 ;;
2514 set-tree,--*)
2515 __gitcomp "--stdin $cmt_opts $fc_opts"
2516 ;;
2517 create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
c18d5d82 2518 show-externals,--*|mkdirs,--*)
47f6ee28
SG
2519 __gitcomp "--revision="
2520 ;;
2521 log,--*)
2522 __gitcomp "
2523 --limit= --revision= --verbose --incremental
2524 --oneline --show-commit --non-recursive
4a5856cb 2525 --authors-file= --color
47f6ee28
SG
2526 "
2527 ;;
2528 rebase,--*)
2529 __gitcomp "
2530 --merge --verbose --strategy= --local
4a5856cb 2531 --fetch-all --dry-run $fc_opts
47f6ee28
SG
2532 "
2533 ;;
2534 commit-diff,--*)
2535 __gitcomp "--message= --file= --revision= $cmt_opts"
2536 ;;
2537 info,--*)
2538 __gitcomp "--url"
2539 ;;
4a5856cb
SG
2540 branch,--*)
2541 __gitcomp "--dry-run --message --tag"
2542 ;;
2543 tag,--*)
2544 __gitcomp "--dry-run --message"
2545 ;;
2546 blame,--*)
2547 __gitcomp "--git-format"
2548 ;;
2549 migrate,--*)
2550 __gitcomp "
2551 --config-dir= --ignore-paths= --minimize
2552 --no-auth-cache --username=
2553 "
2554 ;;
c18d5d82
RZ
2555 reset,--*)
2556 __gitcomp "--revision= --parent"
2557 ;;
47f6ee28
SG
2558 *)
2559 COMPREPLY=()
2560 ;;
2561 esac
2562 fi
2563}
2564
88e21dc7
SP
2565_git_tag ()
2566{
2567 local i c=1 f=0
da48616f
PD
2568 while [ $c -lt $cword ]; do
2569 i="${words[c]}"
88e21dc7
SP
2570 case "$i" in
2571 -d|-v)
2572 __gitcomp "$(__git_tags)"
2573 return
2574 ;;
2575 -f)
2576 f=1
2577 ;;
2578 esac
2579 c=$((++c))
2580 done
2581
da48616f 2582 case "$prev" in
88e21dc7
SP
2583 -m|-F)
2584 COMPREPLY=()
2585 ;;
8d8163f3 2586 -*|tag)
88e21dc7
SP
2587 if [ $f = 1 ]; then
2588 __gitcomp "$(__git_tags)"
2589 else
2590 COMPREPLY=()
2591 fi
2592 ;;
2593 *)
2594 __gitcomp "$(__git_refs)"
2595 ;;
2596 esac
2597}
2598
424cce83
SG
2599_git_whatchanged ()
2600{
2601 _git_log
2602}
2603
690d8824
JH
2604_git ()
2605{
873537fa
SP
2606 local i c=1 command __git_dir
2607
ca209065 2608 if [[ -n ${ZSH_VERSION-} ]]; then
06f44c3c
ML
2609 emulate -L bash
2610 setopt KSH_TYPESET
3bee6a47
SG
2611 else
2612 local words
06f44c3c
ML
2613 fi
2614
3bee6a47 2615 local cur cword prev
da4902a7 2616 _get_comp_words_by_ref -n =: cur words cword prev
da48616f
PD
2617 while [ $c -lt $cword ]; do
2618 i="${words[c]}"
873537fa
SP
2619 case "$i" in
2620 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
2621 --bare) __git_dir="." ;;
1eb7e2f8
LM
2622 --version|-p|--paginate) ;;
2623 --help) command="help"; break ;;
873537fa
SP
2624 *) command="$i"; break ;;
2625 esac
2626 c=$((++c))
2627 done
2628
1d17b22e 2629 if [ -z "$command" ]; then
da48616f 2630 case "$cur" in
47e98eec 2631 --*) __gitcomp "
ce5a2c95 2632 --paginate
47e98eec
SP
2633 --no-pager
2634 --git-dir=
2635 --bare
2636 --version
2637 --exec-path
89a56bfb 2638 --html-path
ce5a2c95
TL
2639 --work-tree=
2640 --help
47e98eec
SP
2641 "
2642 ;;
eaa4e6ee
JN
2643 *) __git_compute_porcelain_commands
2644 __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
72e5e989
SP
2645 esac
2646 return
873537fa 2647 fi
367dce2a 2648
424cce83 2649 local completion_func="_git_${command//-/_}"
06f44c3c 2650 declare -f $completion_func >/dev/null && $completion_func && return
8024ea60 2651
873537fa 2652 local expansion=$(__git_aliased_command "$command")
8024ea60
SG
2653 if [ -n "$expansion" ]; then
2654 completion_func="_git_${expansion//-/_}"
06f44c3c 2655 declare -f $completion_func >/dev/null && $completion_func
8024ea60 2656 fi
690d8824
JH
2657}
2658
2659_gitk ()
2660{
ca209065 2661 if [[ -n ${ZSH_VERSION-} ]]; then
06f44c3c
ML
2662 emulate -L bash
2663 setopt KSH_TYPESET
3bee6a47
SG
2664 else
2665 local words
06f44c3c
ML
2666 fi
2667
3bee6a47 2668 local cur cword prev
da4902a7
SG
2669 _get_comp_words_by_ref -n =: cur words cword prev
2670
d773c631
SG
2671 __git_has_doubledash && return
2672
fa26a401 2673 local g="$(__gitdir)"
07ba53f7 2674 local merge=""
ba7906f2 2675 if [ -f "$g/MERGE_HEAD" ]; then
07ba53f7
RQ
2676 merge="--merge"
2677 fi
b3391775
SP
2678 case "$cur" in
2679 --*)
a393777e
TR
2680 __gitcomp "
2681 $__git_log_common_options
2682 $__git_log_gitk_options
2683 $merge
2684 "
b3391775
SP
2685 return
2686 ;;
2687 esac
ec804891 2688 __git_complete_revlist
690d8824
JH
2689}
2690
50e126e1
TP
2691complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \
2692 || complete -o default -o nospace -F _git git
2693complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \
2694 || complete -o default -o nospace -F _gitk gitk
690d8824
JH
2695
2696# The following are necessary only for Cygwin, and only are needed
2697# when the user has tab-completed the executable name and consequently
2698# included the '.exe' suffix.
2699#
76c3eb51 2700if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
50e126e1
TP
2701complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
2702 || complete -o default -o nospace -F _git git.exe
76c3eb51 2703fi
06f44c3c 2704
ca209065 2705if [[ -n ${ZSH_VERSION-} ]]; then
06f44c3c
ML
2706 shopt () {
2707 local option
2708 if [ $# -ne 2 ]; then
2709 echo "USAGE: $0 (-q|-s|-u) <option>" >&2
2710 return 1
2711 fi
2712 case "$2" in
2713 nullglob)
2714 option="$2"
2715 ;;
2716 *)
2717 echo "$0: invalid option: $2" >&2
2718 return 1
2719 esac
2720 case "$1" in
2721 -q) setopt | grep -q "$option" ;;
2722 -u) unsetopt "$option" ;;
2723 -s) setopt "$option" ;;
2724 *)
2725 echo "$0: invalid flag: $1" >&2
2726 return 1
2727 esac
2728 }
2729fi