bash completion: Add completion for 'git help'
[git] / contrib / completion / git-completion.bash
1 #
2 # bash completion support for core Git.
3 #
4 # Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
5 # Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
6 # Distributed under the GNU General Public License, version 2.0.
7 #
8 # The contained completion routines provide support for completing:
9 #
10 #    *) local and remote branch names
11 #    *) local and remote tag names
12 #    *) .git/remotes file names
13 #    *) git 'subcommands'
14 #    *) tree paths within 'ref:path/to/file' expressions
15 #    *) common --long-options
16 #
17 # To use these routines:
18 #
19 #    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
20 #    2) Added the following line to your .bashrc:
21 #        source ~/.git-completion.sh
22 #
23 #    3) You may want to make sure the git executable is available
24 #       in your PATH before this script is sourced, as some caching
25 #       is performed while the script loads.  If git isn't found
26 #       at source time then all lookups will be done on demand,
27 #       which may be slightly slower.
28 #
29 #    4) Consider changing your PS1 to also show the current branch:
30 #        PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
31 #
32 #       The argument to __git_ps1 will be displayed only if you
33 #       are currently in a git repository.  The %s token will be
34 #       the name of the current branch.
35 #
36 # To submit patches:
37 #
38 #    *) Read Documentation/SubmittingPatches
39 #    *) Send all patches to the current maintainer:
40 #
41 #       "Shawn O. Pearce" <spearce@spearce.org>
42 #
43 #    *) Always CC the Git mailing list:
44 #
45 #       git@vger.kernel.org
46 #
47
48 case "$COMP_WORDBREAKS" in
49 *:*) : great ;;
50 *)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
51 esac
52
53 __gitdir ()
54 {
55         if [ -z "$1" ]; then
56                 if [ -n "$__git_dir" ]; then
57                         echo "$__git_dir"
58                 elif [ -d .git ]; then
59                         echo .git
60                 else
61                         git rev-parse --git-dir 2>/dev/null
62                 fi
63         elif [ -d "$1/.git" ]; then
64                 echo "$1/.git"
65         else
66                 echo "$1"
67         fi
68 }
69
70 __git_ps1 ()
71 {
72         local g="$(git rev-parse --git-dir 2>/dev/null)"
73         if [ -n "$g" ]; then
74                 local r
75                 local b
76                 if [ -d "$g/rebase-apply" ]
77                 then
78                         if test -f "$g/rebase-apply/rebasing"
79                         then
80                                 r="|REBASE"
81                         elif test -f "$g/rebase-apply/applying"
82                         then
83                                 r="|AM"
84                         else
85                                 r="|AM/REBASE"
86                         fi
87                         b="$(git symbolic-ref HEAD 2>/dev/null)"
88                 elif [ -f "$g/rebase-merge/interactive" ]
89                 then
90                         r="|REBASE-i"
91                         b="$(cat "$g/rebase-merge/head-name")"
92                 elif [ -d "$g/rebase-merge" ]
93                 then
94                         r="|REBASE-m"
95                         b="$(cat "$g/rebase-merge/head-name")"
96                 elif [ -f "$g/MERGE_HEAD" ]
97                 then
98                         r="|MERGING"
99                         b="$(git symbolic-ref HEAD 2>/dev/null)"
100                 else
101                         if [ -f "$g/BISECT_LOG" ]
102                         then
103                                 r="|BISECTING"
104                         fi
105                         if ! b="$(git symbolic-ref HEAD 2>/dev/null)"
106                         then
107                                 if ! b="$(git describe --exact-match HEAD 2>/dev/null)"
108                                 then
109                                         b="$(cut -c1-7 "$g/HEAD")..."
110                                 fi
111                         fi
112                 fi
113
114                 if [ -n "$1" ]; then
115                         printf "$1" "${b##refs/heads/}$r"
116                 else
117                         printf " (%s)" "${b##refs/heads/}$r"
118                 fi
119         fi
120 }
121
122 __gitcomp_1 ()
123 {
124         local c IFS=' '$'\t'$'\n'
125         for c in $1; do
126                 case "$c$2" in
127                 --*=*) printf %s$'\n' "$c$2" ;;
128                 *.)    printf %s$'\n' "$c$2" ;;
129                 *)     printf %s$'\n' "$c$2 " ;;
130                 esac
131         done
132 }
133
134 __gitcomp ()
135 {
136         local cur="${COMP_WORDS[COMP_CWORD]}"
137         if [ $# -gt 2 ]; then
138                 cur="$3"
139         fi
140         case "$cur" in
141         --*=)
142                 COMPREPLY=()
143                 ;;
144         *)
145                 local IFS=$'\n'
146                 COMPREPLY=($(compgen -P "$2" \
147                         -W "$(__gitcomp_1 "$1" "$4")" \
148                         -- "$cur"))
149                 ;;
150         esac
151 }
152
153 __git_heads ()
154 {
155         local cmd i is_hash=y dir="$(__gitdir "$1")"
156         if [ -d "$dir" ]; then
157                 for i in $(git --git-dir="$dir" \
158                         for-each-ref --format='%(refname)' \
159                         refs/heads ); do
160                         echo "${i#refs/heads/}"
161                 done
162                 return
163         fi
164         for i in $(git ls-remote "$1" 2>/dev/null); do
165                 case "$is_hash,$i" in
166                 y,*) is_hash=n ;;
167                 n,*^{}) is_hash=y ;;
168                 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
169                 n,*) is_hash=y; echo "$i" ;;
170                 esac
171         done
172 }
173
174 __git_tags ()
175 {
176         local cmd i is_hash=y dir="$(__gitdir "$1")"
177         if [ -d "$dir" ]; then
178                 for i in $(git --git-dir="$dir" \
179                         for-each-ref --format='%(refname)' \
180                         refs/tags ); do
181                         echo "${i#refs/tags/}"
182                 done
183                 return
184         fi
185         for i in $(git ls-remote "$1" 2>/dev/null); do
186                 case "$is_hash,$i" in
187                 y,*) is_hash=n ;;
188                 n,*^{}) is_hash=y ;;
189                 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
190                 n,*) is_hash=y; echo "$i" ;;
191                 esac
192         done
193 }
194
195 __git_refs ()
196 {
197         local cmd i is_hash=y dir="$(__gitdir "$1")"
198         if [ -d "$dir" ]; then
199                 if [ -e "$dir/HEAD" ]; then echo HEAD; fi
200                 for i in $(git --git-dir="$dir" \
201                         for-each-ref --format='%(refname)' \
202                         refs/tags refs/heads refs/remotes); do
203                         case "$i" in
204                                 refs/tags/*)    echo "${i#refs/tags/}" ;;
205                                 refs/heads/*)   echo "${i#refs/heads/}" ;;
206                                 refs/remotes/*) echo "${i#refs/remotes/}" ;;
207                                 *)              echo "$i" ;;
208                         esac
209                 done
210                 return
211         fi
212         for i in $(git ls-remote "$dir" 2>/dev/null); do
213                 case "$is_hash,$i" in
214                 y,*) is_hash=n ;;
215                 n,*^{}) is_hash=y ;;
216                 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
217                 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
218                 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
219                 n,*) is_hash=y; echo "$i" ;;
220                 esac
221         done
222 }
223
224 __git_refs2 ()
225 {
226         local i
227         for i in $(__git_refs "$1"); do
228                 echo "$i:$i"
229         done
230 }
231
232 __git_refs_remotes ()
233 {
234         local cmd i is_hash=y
235         for i in $(git ls-remote "$1" 2>/dev/null); do
236                 case "$is_hash,$i" in
237                 n,refs/heads/*)
238                         is_hash=y
239                         echo "$i:refs/remotes/$1/${i#refs/heads/}"
240                         ;;
241                 y,*) is_hash=n ;;
242                 n,*^{}) is_hash=y ;;
243                 n,refs/tags/*) is_hash=y;;
244                 n,*) is_hash=y; ;;
245                 esac
246         done
247 }
248
249 __git_remotes ()
250 {
251         local i ngoff IFS=$'\n' d="$(__gitdir)"
252         shopt -q nullglob || ngoff=1
253         shopt -s nullglob
254         for i in "$d/remotes"/*; do
255                 echo ${i#$d/remotes/}
256         done
257         [ "$ngoff" ] && shopt -u nullglob
258         for i in $(git --git-dir="$d" config --list); do
259                 case "$i" in
260                 remote.*.url=*)
261                         i="${i#remote.}"
262                         echo "${i/.url=*/}"
263                         ;;
264                 esac
265         done
266 }
267
268 __git_merge_strategies ()
269 {
270         if [ -n "$__git_merge_strategylist" ]; then
271                 echo "$__git_merge_strategylist"
272                 return
273         fi
274         sed -n "/^all_strategies='/{
275                 s/^all_strategies='//
276                 s/'//
277                 p
278                 q
279                 }" "$(git --exec-path)/git-merge"
280 }
281 __git_merge_strategylist=
282 __git_merge_strategylist="$(__git_merge_strategies 2>/dev/null)"
283
284 __git_complete_file ()
285 {
286         local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
287         case "$cur" in
288         ?*:*)
289                 ref="${cur%%:*}"
290                 cur="${cur#*:}"
291                 case "$cur" in
292                 ?*/*)
293                         pfx="${cur%/*}"
294                         cur="${cur##*/}"
295                         ls="$ref:$pfx"
296                         pfx="$pfx/"
297                         ;;
298                 *)
299                         ls="$ref"
300                         ;;
301             esac
302
303                 case "$COMP_WORDBREAKS" in
304                 *:*) : great ;;
305                 *)   pfx="$ref:$pfx" ;;
306                 esac
307
308                 local IFS=$'\n'
309                 COMPREPLY=($(compgen -P "$pfx" \
310                         -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
311                                 | sed '/^100... blob /{
312                                            s,^.*        ,,
313                                            s,$, ,
314                                        }
315                                        /^120000 blob /{
316                                            s,^.*        ,,
317                                            s,$, ,
318                                        }
319                                        /^040000 tree /{
320                                            s,^.*        ,,
321                                            s,$,/,
322                                        }
323                                        s/^.*    //')" \
324                         -- "$cur"))
325                 ;;
326         *)
327                 __gitcomp "$(__git_refs)"
328                 ;;
329         esac
330 }
331
332 __git_complete_revlist ()
333 {
334         local pfx cur="${COMP_WORDS[COMP_CWORD]}"
335         case "$cur" in
336         *...*)
337                 pfx="${cur%...*}..."
338                 cur="${cur#*...}"
339                 __gitcomp "$(__git_refs)" "$pfx" "$cur"
340                 ;;
341         *..*)
342                 pfx="${cur%..*}.."
343                 cur="${cur#*..}"
344                 __gitcomp "$(__git_refs)" "$pfx" "$cur"
345                 ;;
346         *)
347                 __gitcomp "$(__git_refs)"
348                 ;;
349         esac
350 }
351
352 __git_all_commands ()
353 {
354         if [ -n "$__git_all_commandlist" ]; then
355                 echo "$__git_all_commandlist"
356                 return
357         fi
358         local i IFS=" "$'\n'
359         for i in $(git help -a|egrep '^ ')
360         do
361                 case $i in
362                 *--*)             : helper pattern;;
363                 *) echo $i;;
364                 esac
365         done
366 }
367 __git_all_commandlist=
368 __git_all_commandlist="$(__git_all_commands 2>/dev/null)"
369
370 __git_porcelain_commands ()
371 {
372         if [ -n "$__git_porcelain_commandlist" ]; then
373                 echo "$__git_porcelain_commandlist"
374                 return
375         fi
376         local i IFS=" "$'\n'
377         for i in "help" $(__git_all_commands)
378         do
379                 case $i in
380                 *--*)             : helper pattern;;
381                 applymbox)        : ask gittus;;
382                 applypatch)       : ask gittus;;
383                 archimport)       : import;;
384                 cat-file)         : plumbing;;
385                 check-attr)       : plumbing;;
386                 check-ref-format) : plumbing;;
387                 commit-tree)      : plumbing;;
388                 cvsexportcommit)  : export;;
389                 cvsimport)        : import;;
390                 cvsserver)        : daemon;;
391                 daemon)           : daemon;;
392                 diff-files)       : plumbing;;
393                 diff-index)       : plumbing;;
394                 diff-tree)        : plumbing;;
395                 fast-import)      : import;;
396                 fsck-objects)     : plumbing;;
397                 fetch-pack)       : plumbing;;
398                 fmt-merge-msg)    : plumbing;;
399                 for-each-ref)     : plumbing;;
400                 hash-object)      : plumbing;;
401                 http-*)           : transport;;
402                 index-pack)       : plumbing;;
403                 init-db)          : deprecated;;
404                 local-fetch)      : plumbing;;
405                 mailinfo)         : plumbing;;
406                 mailsplit)        : plumbing;;
407                 merge-*)          : plumbing;;
408                 mktree)           : plumbing;;
409                 mktag)            : plumbing;;
410                 pack-objects)     : plumbing;;
411                 pack-redundant)   : plumbing;;
412                 pack-refs)        : plumbing;;
413                 parse-remote)     : plumbing;;
414                 patch-id)         : plumbing;;
415                 peek-remote)      : plumbing;;
416                 prune)            : plumbing;;
417                 prune-packed)     : plumbing;;
418                 quiltimport)      : import;;
419                 read-tree)        : plumbing;;
420                 receive-pack)     : plumbing;;
421                 reflog)           : plumbing;;
422                 repo-config)      : deprecated;;
423                 rerere)           : plumbing;;
424                 rev-list)         : plumbing;;
425                 rev-parse)        : plumbing;;
426                 runstatus)        : plumbing;;
427                 sh-setup)         : internal;;
428                 shell)            : daemon;;
429                 send-pack)        : plumbing;;
430                 show-index)       : plumbing;;
431                 ssh-*)            : transport;;
432                 stripspace)       : plumbing;;
433                 symbolic-ref)     : plumbing;;
434                 tar-tree)         : deprecated;;
435                 unpack-file)      : plumbing;;
436                 unpack-objects)   : plumbing;;
437                 update-index)     : plumbing;;
438                 update-ref)       : plumbing;;
439                 update-server-info) : daemon;;
440                 upload-archive)   : plumbing;;
441                 upload-pack)      : plumbing;;
442                 write-tree)       : plumbing;;
443                 verify-tag)       : plumbing;;
444                 *) echo $i;;
445                 esac
446         done
447 }
448 __git_porcelain_commandlist=
449 __git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)"
450
451 __git_aliases ()
452 {
453         local i IFS=$'\n'
454         for i in $(git --git-dir="$(__gitdir)" config --list); do
455                 case "$i" in
456                 alias.*)
457                         i="${i#alias.}"
458                         echo "${i/=*/}"
459                         ;;
460                 esac
461         done
462 }
463
464 __git_aliased_command ()
465 {
466         local word cmdline=$(git --git-dir="$(__gitdir)" \
467                 config --get "alias.$1")
468         for word in $cmdline; do
469                 if [ "${word##-*}" ]; then
470                         echo $word
471                         return
472                 fi
473         done
474 }
475
476 __git_find_subcommand ()
477 {
478         local word subcommand c=1
479
480         while [ $c -lt $COMP_CWORD ]; do
481                 word="${COMP_WORDS[c]}"
482                 for subcommand in $1; do
483                         if [ "$subcommand" = "$word" ]; then
484                                 echo "$subcommand"
485                                 return
486                         fi
487                 done
488                 c=$((++c))
489         done
490 }
491
492 __git_has_doubledash ()
493 {
494         local c=1
495         while [ $c -lt $COMP_CWORD ]; do
496                 if [ "--" = "${COMP_WORDS[c]}" ]; then
497                         return 0
498                 fi
499                 c=$((++c))
500         done
501         return 1
502 }
503
504 __git_whitespacelist="nowarn warn error error-all strip"
505
506 _git_am ()
507 {
508         local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
509         if [ -d "$dir"/rebase-apply ]; then
510                 __gitcomp "--skip --resolved --abort"
511                 return
512         fi
513         case "$cur" in
514         --whitespace=*)
515                 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
516                 return
517                 ;;
518         --*)
519                 __gitcomp "
520                         --signoff --utf8 --binary --3way --interactive
521                         --whitespace=
522                         "
523                 return
524         esac
525         COMPREPLY=()
526 }
527
528 _git_apply ()
529 {
530         local cur="${COMP_WORDS[COMP_CWORD]}"
531         case "$cur" in
532         --whitespace=*)
533                 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
534                 return
535                 ;;
536         --*)
537                 __gitcomp "
538                         --stat --numstat --summary --check --index
539                         --cached --index-info --reverse --reject --unidiff-zero
540                         --apply --no-add --exclude=
541                         --whitespace= --inaccurate-eof --verbose
542                         "
543                 return
544         esac
545         COMPREPLY=()
546 }
547
548 _git_add ()
549 {
550         __git_has_doubledash && return
551
552         local cur="${COMP_WORDS[COMP_CWORD]}"
553         case "$cur" in
554         --*)
555                 __gitcomp "
556                         --interactive --refresh --patch --update --dry-run
557                         --ignore-errors
558                         "
559                 return
560         esac
561         COMPREPLY=()
562 }
563
564 _git_bisect ()
565 {
566         __git_has_doubledash && return
567
568         local subcommands="start bad good skip reset visualize replay log run"
569         local subcommand="$(__git_find_subcommand "$subcommands")"
570         if [ -z "$subcommand" ]; then
571                 __gitcomp "$subcommands"
572                 return
573         fi
574
575         case "$subcommand" in
576         bad|good|reset|skip)
577                 __gitcomp "$(__git_refs)"
578                 ;;
579         *)
580                 COMPREPLY=()
581                 ;;
582         esac
583 }
584
585 _git_branch ()
586 {
587         local i c=1 only_local_ref="n" has_r="n"
588
589         while [ $c -lt $COMP_CWORD ]; do
590                 i="${COMP_WORDS[c]}"
591                 case "$i" in
592                 -d|-m)  only_local_ref="y" ;;
593                 -r)     has_r="y" ;;
594                 esac
595                 c=$((++c))
596         done
597
598         case "${COMP_WORDS[COMP_CWORD]}" in
599         --*=*)  COMPREPLY=() ;;
600         --*)
601                 __gitcomp "
602                         --color --no-color --verbose --abbrev= --no-abbrev
603                         --track --no-track --contains --merged --no-merged
604                         "
605                 ;;
606         *)
607                 if [ $only_local_ref = "y" -a $has_r = "n" ]; then
608                         __gitcomp "$(__git_heads)"
609                 else
610                         __gitcomp "$(__git_refs)"
611                 fi
612                 ;;
613         esac
614 }
615
616 _git_bundle ()
617 {
618         local mycword="$COMP_CWORD"
619         case "${COMP_WORDS[0]}" in
620         git)
621                 local cmd="${COMP_WORDS[2]}"
622                 mycword="$((mycword-1))"
623                 ;;
624         git-bundle*)
625                 local cmd="${COMP_WORDS[1]}"
626                 ;;
627         esac
628         case "$mycword" in
629         1)
630                 __gitcomp "create list-heads verify unbundle"
631                 ;;
632         2)
633                 # looking for a file
634                 ;;
635         *)
636                 case "$cmd" in
637                         create)
638                                 __git_complete_revlist
639                         ;;
640                 esac
641                 ;;
642         esac
643 }
644
645 _git_checkout ()
646 {
647         __git_has_doubledash && return
648
649         __gitcomp "$(__git_refs)"
650 }
651
652 _git_cherry ()
653 {
654         __gitcomp "$(__git_refs)"
655 }
656
657 _git_cherry_pick ()
658 {
659         local cur="${COMP_WORDS[COMP_CWORD]}"
660         case "$cur" in
661         --*)
662                 __gitcomp "--edit --no-commit"
663                 ;;
664         *)
665                 __gitcomp "$(__git_refs)"
666                 ;;
667         esac
668 }
669
670 _git_commit ()
671 {
672         __git_has_doubledash && return
673
674         local cur="${COMP_WORDS[COMP_CWORD]}"
675         case "$cur" in
676         --*)
677                 __gitcomp "
678                         --all --author= --signoff --verify --no-verify
679                         --edit --amend --include --only
680                         "
681                 return
682         esac
683         COMPREPLY=()
684 }
685
686 _git_describe ()
687 {
688         local cur="${COMP_WORDS[COMP_CWORD]}"
689         case "$cur" in
690         --*)
691                 __gitcomp "
692                         --all --tags --contains --abbrev= --candidates=
693                         --exact-match --debug --long --match --always
694                         "
695                 return
696         esac
697         __gitcomp "$(__git_refs)"
698 }
699
700 _git_diff ()
701 {
702         __git_has_doubledash && return
703
704         local cur="${COMP_WORDS[COMP_CWORD]}"
705         case "$cur" in
706         --*)
707                 __gitcomp "--cached --stat --numstat --shortstat --summary
708                         --patch-with-stat --name-only --name-status --color
709                         --no-color --color-words --no-renames --check
710                         --full-index --binary --abbrev --diff-filter
711                         --find-copies-harder --pickaxe-all --pickaxe-regex
712                         --text --ignore-space-at-eol --ignore-space-change
713                         --ignore-all-space --exit-code --quiet --ext-diff
714                         --no-ext-diff
715                         --no-prefix --src-prefix= --dst-prefix=
716                         --base --ours --theirs
717                         "
718                 return
719                 ;;
720         esac
721         __git_complete_file
722 }
723
724 _git_diff_tree ()
725 {
726         __gitcomp "$(__git_refs)"
727 }
728
729 _git_fetch ()
730 {
731         local cur="${COMP_WORDS[COMP_CWORD]}"
732
733         case "${COMP_WORDS[0]},$COMP_CWORD" in
734         git-fetch*,1)
735                 __gitcomp "$(__git_remotes)"
736                 ;;
737         git,2)
738                 __gitcomp "$(__git_remotes)"
739                 ;;
740         *)
741                 case "$cur" in
742                 *:*)
743                         local pfx=""
744                         case "$COMP_WORDBREAKS" in
745                         *:*) : great ;;
746                         *)   pfx="${cur%%:*}:" ;;
747                         esac
748                         __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
749                         ;;
750                 *)
751                         local remote
752                         case "${COMP_WORDS[0]}" in
753                         git-fetch) remote="${COMP_WORDS[1]}" ;;
754                         git)       remote="${COMP_WORDS[2]}" ;;
755                         esac
756                         __gitcomp "$(__git_refs2 "$remote")"
757                         ;;
758                 esac
759                 ;;
760         esac
761 }
762
763 _git_format_patch ()
764 {
765         local cur="${COMP_WORDS[COMP_CWORD]}"
766         case "$cur" in
767         --*)
768                 __gitcomp "
769                         --stdout --attach --thread
770                         --output-directory
771                         --numbered --start-number
772                         --numbered-files
773                         --keep-subject
774                         --signoff
775                         --in-reply-to=
776                         --full-index --binary
777                         --not --all
778                         --cover-letter
779                         --no-prefix --src-prefix= --dst-prefix=
780                         "
781                 return
782                 ;;
783         esac
784         __git_complete_revlist
785 }
786
787 _git_gc ()
788 {
789         local cur="${COMP_WORDS[COMP_CWORD]}"
790         case "$cur" in
791         --*)
792                 __gitcomp "--prune --aggressive"
793                 return
794                 ;;
795         esac
796         COMPREPLY=()
797 }
798
799 _git_help ()
800 {
801         local cur="${COMP_WORDS[COMP_CWORD]}"
802         case "$cur" in
803         --*)
804                 __gitcomp "--all --info --man --web"
805                 return
806                 ;;
807         esac
808         __gitcomp "$(__git_all_commands)"
809 }
810
811 _git_ls_remote ()
812 {
813         __gitcomp "$(__git_remotes)"
814 }
815
816 _git_ls_tree ()
817 {
818         __git_complete_file
819 }
820
821 _git_log ()
822 {
823         __git_has_doubledash && return
824
825         local cur="${COMP_WORDS[COMP_CWORD]}"
826         case "$cur" in
827         --pretty=*)
828                 __gitcomp "
829                         oneline short medium full fuller email raw
830                         " "" "${cur##--pretty=}"
831                 return
832                 ;;
833         --date=*)
834                 __gitcomp "
835                         relative iso8601 rfc2822 short local default
836                 " "" "${cur##--date=}"
837                 return
838                 ;;
839         --*)
840                 __gitcomp "
841                         --max-count= --max-age= --since= --after=
842                         --min-age= --before= --until=
843                         --root --topo-order --date-order --reverse
844                         --no-merges --follow
845                         --abbrev-commit --abbrev=
846                         --relative-date --date=
847                         --author= --committer= --grep=
848                         --all-match
849                         --pretty= --name-status --name-only --raw
850                         --not --all
851                         --left-right --cherry-pick
852                         --graph
853                         --stat --numstat --shortstat
854                         --decorate --diff-filter=
855                         --color-words --walk-reflogs
856                         "
857                 return
858                 ;;
859         esac
860         __git_complete_revlist
861 }
862
863 _git_merge ()
864 {
865         local cur="${COMP_WORDS[COMP_CWORD]}"
866         case "${COMP_WORDS[COMP_CWORD-1]}" in
867         -s|--strategy)
868                 __gitcomp "$(__git_merge_strategies)"
869                 return
870         esac
871         case "$cur" in
872         --strategy=*)
873                 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
874                 return
875                 ;;
876         --*)
877                 __gitcomp "
878                         --no-commit --no-stat --log --no-log --squash --strategy
879                         "
880                 return
881         esac
882         __gitcomp "$(__git_refs)"
883 }
884
885 _git_merge_base ()
886 {
887         __gitcomp "$(__git_refs)"
888 }
889
890 _git_name_rev ()
891 {
892         __gitcomp "--tags --all --stdin"
893 }
894
895 _git_pull ()
896 {
897         local cur="${COMP_WORDS[COMP_CWORD]}"
898
899         case "${COMP_WORDS[0]},$COMP_CWORD" in
900         git-pull*,1)
901                 __gitcomp "$(__git_remotes)"
902                 ;;
903         git,2)
904                 __gitcomp "$(__git_remotes)"
905                 ;;
906         *)
907                 local remote
908                 case "${COMP_WORDS[0]}" in
909                 git-pull)  remote="${COMP_WORDS[1]}" ;;
910                 git)       remote="${COMP_WORDS[2]}" ;;
911                 esac
912                 __gitcomp "$(__git_refs "$remote")"
913                 ;;
914         esac
915 }
916
917 _git_push ()
918 {
919         local cur="${COMP_WORDS[COMP_CWORD]}"
920
921         case "${COMP_WORDS[0]},$COMP_CWORD" in
922         git-push*,1)
923                 __gitcomp "$(__git_remotes)"
924                 ;;
925         git,2)
926                 __gitcomp "$(__git_remotes)"
927                 ;;
928         *)
929                 case "$cur" in
930                 *:*)
931                         local remote
932                         case "${COMP_WORDS[0]}" in
933                         git-push)  remote="${COMP_WORDS[1]}" ;;
934                         git)       remote="${COMP_WORDS[2]}" ;;
935                         esac
936
937                         local pfx=""
938                         case "$COMP_WORDBREAKS" in
939                         *:*) : great ;;
940                         *)   pfx="${cur%%:*}:" ;;
941                         esac
942
943                         __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
944                         ;;
945                 +*)
946                         __gitcomp "$(__git_refs)" + "${cur#+}"
947                         ;;
948                 *)
949                         __gitcomp "$(__git_refs)"
950                         ;;
951                 esac
952                 ;;
953         esac
954 }
955
956 _git_rebase ()
957 {
958         local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
959         if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
960                 __gitcomp "--continue --skip --abort"
961                 return
962         fi
963         case "${COMP_WORDS[COMP_CWORD-1]}" in
964         -s|--strategy)
965                 __gitcomp "$(__git_merge_strategies)"
966                 return
967         esac
968         case "$cur" in
969         --strategy=*)
970                 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
971                 return
972                 ;;
973         --*)
974                 __gitcomp "--onto --merge --strategy --interactive"
975                 return
976         esac
977         __gitcomp "$(__git_refs)"
978 }
979
980 _git_send_email ()
981 {
982         local cur="${COMP_WORDS[COMP_CWORD]}"
983         case "$cur" in
984         --*)
985                 __gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
986                         --dry-run --envelope-sender --from --identity
987                         --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
988                         --no-suppress-from --no-thread --quiet
989                         --signed-off-by-cc --smtp-pass --smtp-server
990                         --smtp-server-port --smtp-ssl --smtp-user --subject
991                         --suppress-cc --suppress-from --thread --to"
992                 return
993                 ;;
994         esac
995         COMPREPLY=()
996 }
997
998 _git_config ()
999 {
1000         local cur="${COMP_WORDS[COMP_CWORD]}"
1001         local prv="${COMP_WORDS[COMP_CWORD-1]}"
1002         case "$prv" in
1003         branch.*.remote)
1004                 __gitcomp "$(__git_remotes)"
1005                 return
1006                 ;;
1007         branch.*.merge)
1008                 __gitcomp "$(__git_refs)"
1009                 return
1010                 ;;
1011         remote.*.fetch)
1012                 local remote="${prv#remote.}"
1013                 remote="${remote%.fetch}"
1014                 __gitcomp "$(__git_refs_remotes "$remote")"
1015                 return
1016                 ;;
1017         remote.*.push)
1018                 local remote="${prv#remote.}"
1019                 remote="${remote%.push}"
1020                 __gitcomp "$(git --git-dir="$(__gitdir)" \
1021                         for-each-ref --format='%(refname):%(refname)' \
1022                         refs/heads)"
1023                 return
1024                 ;;
1025         pull.twohead|pull.octopus)
1026                 __gitcomp "$(__git_merge_strategies)"
1027                 return
1028                 ;;
1029         color.branch|color.diff|color.status)
1030                 __gitcomp "always never auto"
1031                 return
1032                 ;;
1033         color.*.*)
1034                 __gitcomp "
1035                         black red green yellow blue magenta cyan white
1036                         bold dim ul blink reverse
1037                         "
1038                 return
1039                 ;;
1040         *.*)
1041                 COMPREPLY=()
1042                 return
1043                 ;;
1044         esac
1045         case "$cur" in
1046         --*)
1047                 __gitcomp "
1048                         --global --system --file=
1049                         --list --replace-all
1050                         --get --get-all --get-regexp
1051                         --add --unset --unset-all
1052                         --remove-section --rename-section
1053                         "
1054                 return
1055                 ;;
1056         branch.*.*)
1057                 local pfx="${cur%.*}."
1058                 cur="${cur##*.}"
1059                 __gitcomp "remote merge" "$pfx" "$cur"
1060                 return
1061                 ;;
1062         branch.*)
1063                 local pfx="${cur%.*}."
1064                 cur="${cur#*.}"
1065                 __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1066                 return
1067                 ;;
1068         remote.*.*)
1069                 local pfx="${cur%.*}."
1070                 cur="${cur##*.}"
1071                 __gitcomp "
1072                         url fetch push skipDefaultUpdate
1073                         receivepack uploadpack tagopt
1074                         " "$pfx" "$cur"
1075                 return
1076                 ;;
1077         remote.*)
1078                 local pfx="${cur%.*}."
1079                 cur="${cur#*.}"
1080                 __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1081                 return
1082                 ;;
1083         esac
1084         __gitcomp "
1085                 apply.whitespace
1086                 core.fileMode
1087                 core.gitProxy
1088                 core.ignoreStat
1089                 core.preferSymlinkRefs
1090                 core.logAllRefUpdates
1091                 core.loosecompression
1092                 core.repositoryFormatVersion
1093                 core.sharedRepository
1094                 core.warnAmbiguousRefs
1095                 core.compression
1096                 core.packedGitWindowSize
1097                 core.packedGitLimit
1098                 clean.requireForce
1099                 color.branch
1100                 color.branch.current
1101                 color.branch.local
1102                 color.branch.remote
1103                 color.branch.plain
1104                 color.diff
1105                 color.diff.plain
1106                 color.diff.meta
1107                 color.diff.frag
1108                 color.diff.old
1109                 color.diff.new
1110                 color.diff.commit
1111                 color.diff.whitespace
1112                 color.pager
1113                 color.status
1114                 color.status.header
1115                 color.status.added
1116                 color.status.changed
1117                 color.status.untracked
1118                 diff.renameLimit
1119                 diff.renames
1120                 fetch.unpackLimit
1121                 format.headers
1122                 format.subjectprefix
1123                 gitcvs.enabled
1124                 gitcvs.logfile
1125                 gitcvs.allbinary
1126                 gitcvs.dbname gitcvs.dbdriver gitcvs.dbuser gitcvs.dbpass
1127                 gitcvs.dbtablenameprefix
1128                 gc.packrefs
1129                 gc.reflogexpire
1130                 gc.reflogexpireunreachable
1131                 gc.rerereresolved
1132                 gc.rerereunresolved
1133                 http.sslVerify
1134                 http.sslCert
1135                 http.sslKey
1136                 http.sslCAInfo
1137                 http.sslCAPath
1138                 http.maxRequests
1139                 http.lowSpeedLimit
1140                 http.lowSpeedTime
1141                 http.noEPSV
1142                 i18n.commitEncoding
1143                 i18n.logOutputEncoding
1144                 log.showroot
1145                 merge.tool
1146                 merge.summary
1147                 merge.verbosity
1148                 pack.window
1149                 pack.depth
1150                 pack.windowMemory
1151                 pack.compression
1152                 pack.deltaCacheSize
1153                 pack.deltaCacheLimit
1154                 pull.octopus
1155                 pull.twohead
1156                 repack.useDeltaBaseOffset
1157                 showbranch.default
1158                 tar.umask
1159                 transfer.unpackLimit
1160                 receive.unpackLimit
1161                 receive.denyNonFastForwards
1162                 user.name
1163                 user.email
1164                 user.signingkey
1165                 branch. remote.
1166         "
1167 }
1168
1169 _git_remote ()
1170 {
1171         local subcommands="add rm show prune update"
1172         local subcommand="$(__git_find_subcommand "$subcommands")"
1173         if [ -z "$subcommand" ]; then
1174                 __gitcomp "$subcommands"
1175                 return
1176         fi
1177
1178         case "$subcommand" in
1179         rm|show|prune)
1180                 __gitcomp "$(__git_remotes)"
1181                 ;;
1182         update)
1183                 local i c='' IFS=$'\n'
1184                 for i in $(git --git-dir="$(__gitdir)" config --list); do
1185                         case "$i" in
1186                         remotes.*)
1187                                 i="${i#remotes.}"
1188                                 c="$c ${i/=*/}"
1189                                 ;;
1190                         esac
1191                 done
1192                 __gitcomp "$c"
1193                 ;;
1194         *)
1195                 COMPREPLY=()
1196                 ;;
1197         esac
1198 }
1199
1200 _git_reset ()
1201 {
1202         __git_has_doubledash && return
1203
1204         local cur="${COMP_WORDS[COMP_CWORD]}"
1205         case "$cur" in
1206         --*)
1207                 __gitcomp "--mixed --hard --soft"
1208                 return
1209                 ;;
1210         esac
1211         __gitcomp "$(__git_refs)"
1212 }
1213
1214 _git_rm ()
1215 {
1216         __git_has_doubledash && return
1217
1218         local cur="${COMP_WORDS[COMP_CWORD]}"
1219         case "$cur" in
1220         --*)
1221                 __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
1222                 return
1223                 ;;
1224         esac
1225         COMPREPLY=()
1226 }
1227
1228 _git_shortlog ()
1229 {
1230         __git_has_doubledash && return
1231
1232         local cur="${COMP_WORDS[COMP_CWORD]}"
1233         case "$cur" in
1234         --*)
1235                 __gitcomp "
1236                         --max-count= --max-age= --since= --after=
1237                         --min-age= --before= --until=
1238                         --no-merges
1239                         --author= --committer= --grep=
1240                         --all-match
1241                         --not --all
1242                         --numbered --summary
1243                         "
1244                 return
1245                 ;;
1246         esac
1247         __git_complete_revlist
1248 }
1249
1250 _git_show ()
1251 {
1252         local cur="${COMP_WORDS[COMP_CWORD]}"
1253         case "$cur" in
1254         --pretty=*)
1255                 __gitcomp "
1256                         oneline short medium full fuller email raw
1257                         " "" "${cur##--pretty=}"
1258                 return
1259                 ;;
1260         --*)
1261                 __gitcomp "--pretty="
1262                 return
1263                 ;;
1264         esac
1265         __git_complete_file
1266 }
1267
1268 _git_show_branch ()
1269 {
1270         local cur="${COMP_WORDS[COMP_CWORD]}"
1271         case "$cur" in
1272         --*)
1273                 __gitcomp "
1274                         --all --remotes --topo-order --current --more=
1275                         --list --independent --merge-base --no-name
1276                         --sha1-name --topics --reflog
1277                         "
1278                 return
1279                 ;;
1280         esac
1281         __git_complete_revlist
1282 }
1283
1284 _git_stash ()
1285 {
1286         local subcommands='save list show apply clear drop pop create'
1287         local subcommand="$(__git_find_subcommand "$subcommands")"
1288         if [ -z "$subcommand" ]; then
1289                 __gitcomp "$subcommands"
1290         else
1291                 local cur="${COMP_WORDS[COMP_CWORD]}"
1292                 case "$subcommand,$cur" in
1293                 save,--*)
1294                         __gitcomp "--keep-index"
1295                         ;;
1296                 *)
1297                         COMPREPLY=()
1298                         ;;
1299                 esac
1300         fi
1301 }
1302
1303 _git_submodule ()
1304 {
1305         __git_has_doubledash && return
1306
1307         local subcommands="add status init update"
1308         if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1309                 local cur="${COMP_WORDS[COMP_CWORD]}"
1310                 case "$cur" in
1311                 --*)
1312                         __gitcomp "--quiet --cached"
1313                         ;;
1314                 *)
1315                         __gitcomp "$subcommands"
1316                         ;;
1317                 esac
1318                 return
1319         fi
1320 }
1321
1322 _git_svn ()
1323 {
1324         local subcommands="
1325                 init fetch clone rebase dcommit log find-rev
1326                 set-tree commit-diff info create-ignore propget
1327                 proplist show-ignore show-externals
1328                 "
1329         local subcommand="$(__git_find_subcommand "$subcommands")"
1330         if [ -z "$subcommand" ]; then
1331                 __gitcomp "$subcommands"
1332         else
1333                 local remote_opts="--username= --config-dir= --no-auth-cache"
1334                 local fc_opts="
1335                         --follow-parent --authors-file= --repack=
1336                         --no-metadata --use-svm-props --use-svnsync-props
1337                         --log-window-size= --no-checkout --quiet
1338                         --repack-flags --user-log-author $remote_opts
1339                         "
1340                 local init_opts="
1341                         --template= --shared= --trunk= --tags=
1342                         --branches= --stdlayout --minimize-url
1343                         --no-metadata --use-svm-props --use-svnsync-props
1344                         --rewrite-root= $remote_opts
1345                         "
1346                 local cmt_opts="
1347                         --edit --rmdir --find-copies-harder --copy-similarity=
1348                         "
1349
1350                 local cur="${COMP_WORDS[COMP_CWORD]}"
1351                 case "$subcommand,$cur" in
1352                 fetch,--*)
1353                         __gitcomp "--revision= --fetch-all $fc_opts"
1354                         ;;
1355                 clone,--*)
1356                         __gitcomp "--revision= $fc_opts $init_opts"
1357                         ;;
1358                 init,--*)
1359                         __gitcomp "$init_opts"
1360                         ;;
1361                 dcommit,--*)
1362                         __gitcomp "
1363                                 --merge --strategy= --verbose --dry-run
1364                                 --fetch-all --no-rebase $cmt_opts $fc_opts
1365                                 "
1366                         ;;
1367                 set-tree,--*)
1368                         __gitcomp "--stdin $cmt_opts $fc_opts"
1369                         ;;
1370                 create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
1371                 show-externals,--*)
1372                         __gitcomp "--revision="
1373                         ;;
1374                 log,--*)
1375                         __gitcomp "
1376                                 --limit= --revision= --verbose --incremental
1377                                 --oneline --show-commit --non-recursive
1378                                 --authors-file=
1379                                 "
1380                         ;;
1381                 rebase,--*)
1382                         __gitcomp "
1383                                 --merge --verbose --strategy= --local
1384                                 --fetch-all $fc_opts
1385                                 "
1386                         ;;
1387                 commit-diff,--*)
1388                         __gitcomp "--message= --file= --revision= $cmt_opts"
1389                         ;;
1390                 info,--*)
1391                         __gitcomp "--url"
1392                         ;;
1393                 *)
1394                         COMPREPLY=()
1395                         ;;
1396                 esac
1397         fi
1398 }
1399
1400 _git_tag ()
1401 {
1402         local i c=1 f=0
1403         while [ $c -lt $COMP_CWORD ]; do
1404                 i="${COMP_WORDS[c]}"
1405                 case "$i" in
1406                 -d|-v)
1407                         __gitcomp "$(__git_tags)"
1408                         return
1409                         ;;
1410                 -f)
1411                         f=1
1412                         ;;
1413                 esac
1414                 c=$((++c))
1415         done
1416
1417         case "${COMP_WORDS[COMP_CWORD-1]}" in
1418         -m|-F)
1419                 COMPREPLY=()
1420                 ;;
1421         -*|tag|git-tag)
1422                 if [ $f = 1 ]; then
1423                         __gitcomp "$(__git_tags)"
1424                 else
1425                         COMPREPLY=()
1426                 fi
1427                 ;;
1428         *)
1429                 __gitcomp "$(__git_refs)"
1430                 ;;
1431         esac
1432 }
1433
1434 _git ()
1435 {
1436         local i c=1 command __git_dir
1437
1438         while [ $c -lt $COMP_CWORD ]; do
1439                 i="${COMP_WORDS[c]}"
1440                 case "$i" in
1441                 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
1442                 --bare)      __git_dir="." ;;
1443                 --version|-p|--paginate) ;;
1444                 --help) command="help"; break ;;
1445                 *) command="$i"; break ;;
1446                 esac
1447                 c=$((++c))
1448         done
1449
1450         if [ -z "$command" ]; then
1451                 case "${COMP_WORDS[COMP_CWORD]}" in
1452                 --*=*) COMPREPLY=() ;;
1453                 --*)   __gitcomp "
1454                         --paginate
1455                         --no-pager
1456                         --git-dir=
1457                         --bare
1458                         --version
1459                         --exec-path
1460                         --work-tree=
1461                         --help
1462                         "
1463                         ;;
1464                 *)     __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
1465                 esac
1466                 return
1467         fi
1468
1469         local expansion=$(__git_aliased_command "$command")
1470         [ "$expansion" ] && command="$expansion"
1471
1472         case "$command" in
1473         am)          _git_am ;;
1474         add)         _git_add ;;
1475         apply)       _git_apply ;;
1476         bisect)      _git_bisect ;;
1477         bundle)      _git_bundle ;;
1478         branch)      _git_branch ;;
1479         checkout)    _git_checkout ;;
1480         cherry)      _git_cherry ;;
1481         cherry-pick) _git_cherry_pick ;;
1482         commit)      _git_commit ;;
1483         config)      _git_config ;;
1484         describe)    _git_describe ;;
1485         diff)        _git_diff ;;
1486         fetch)       _git_fetch ;;
1487         format-patch) _git_format_patch ;;
1488         gc)          _git_gc ;;
1489         help)        _git_help ;;
1490         log)         _git_log ;;
1491         ls-remote)   _git_ls_remote ;;
1492         ls-tree)     _git_ls_tree ;;
1493         merge)       _git_merge;;
1494         merge-base)  _git_merge_base ;;
1495         name-rev)    _git_name_rev ;;
1496         pull)        _git_pull ;;
1497         push)        _git_push ;;
1498         rebase)      _git_rebase ;;
1499         remote)      _git_remote ;;
1500         reset)       _git_reset ;;
1501         rm)          _git_rm ;;
1502         send-email)  _git_send_email ;;
1503         shortlog)    _git_shortlog ;;
1504         show)        _git_show ;;
1505         show-branch) _git_show_branch ;;
1506         stash)       _git_stash ;;
1507         submodule)   _git_submodule ;;
1508         svn)         _git_svn ;;
1509         tag)         _git_tag ;;
1510         whatchanged) _git_log ;;
1511         *)           COMPREPLY=() ;;
1512         esac
1513 }
1514
1515 _gitk ()
1516 {
1517         __git_has_doubledash && return
1518
1519         local cur="${COMP_WORDS[COMP_CWORD]}"
1520         local g="$(git rev-parse --git-dir 2>/dev/null)"
1521         local merge=""
1522         if [ -f $g/MERGE_HEAD ]; then
1523                 merge="--merge"
1524         fi
1525         case "$cur" in
1526         --*)
1527                 __gitcomp "--not --all $merge"
1528                 return
1529                 ;;
1530         esac
1531         __git_complete_revlist
1532 }
1533
1534 complete -o default -o nospace -F _git git
1535 complete -o default -o nospace -F _gitk gitk
1536
1537 # The following are necessary only for Cygwin, and only are needed
1538 # when the user has tab-completed the executable name and consequently
1539 # included the '.exe' suffix.
1540 #
1541 if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1542 complete -o default -o nospace -F _git git.exe
1543 fi