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