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