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