2fb88a8feff5dbfa368785e8872b42742b257eec
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
48case "$COMP_WORDBREAKS" in
49*:*) : great ;;
50*) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
51esac
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_commands ()
353{
354 if [ -n "$__git_commandlist" ]; then
355 echo "$__git_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 applymbox) : ask gittus;;
364 applypatch) : ask gittus;;
365 archimport) : import;;
366 cat-file) : plumbing;;
367 check-attr) : plumbing;;
368 check-ref-format) : plumbing;;
369 commit-tree) : plumbing;;
370 cvsexportcommit) : export;;
371 cvsimport) : import;;
372 cvsserver) : daemon;;
373 daemon) : daemon;;
374 diff-files) : plumbing;;
375 diff-index) : plumbing;;
376 diff-tree) : plumbing;;
377 fast-import) : import;;
378 fsck-objects) : plumbing;;
379 fetch-pack) : plumbing;;
380 fmt-merge-msg) : plumbing;;
381 for-each-ref) : plumbing;;
382 hash-object) : plumbing;;
383 http-*) : transport;;
384 index-pack) : plumbing;;
385 init-db) : deprecated;;
386 local-fetch) : plumbing;;
387 mailinfo) : plumbing;;
388 mailsplit) : plumbing;;
389 merge-*) : plumbing;;
390 mktree) : plumbing;;
391 mktag) : plumbing;;
392 pack-objects) : plumbing;;
393 pack-redundant) : plumbing;;
394 pack-refs) : plumbing;;
395 parse-remote) : plumbing;;
396 patch-id) : plumbing;;
397 peek-remote) : plumbing;;
398 prune) : plumbing;;
399 prune-packed) : plumbing;;
400 quiltimport) : import;;
401 read-tree) : plumbing;;
402 receive-pack) : plumbing;;
403 reflog) : plumbing;;
404 repo-config) : deprecated;;
405 rerere) : plumbing;;
406 rev-list) : plumbing;;
407 rev-parse) : plumbing;;
408 runstatus) : plumbing;;
409 sh-setup) : internal;;
410 shell) : daemon;;
411 send-pack) : plumbing;;
412 show-index) : plumbing;;
413 ssh-*) : transport;;
414 stripspace) : plumbing;;
415 symbolic-ref) : plumbing;;
416 tar-tree) : deprecated;;
417 unpack-file) : plumbing;;
418 unpack-objects) : plumbing;;
419 update-index) : plumbing;;
420 update-ref) : plumbing;;
421 update-server-info) : daemon;;
422 upload-archive) : plumbing;;
423 upload-pack) : plumbing;;
424 write-tree) : plumbing;;
425 verify-tag) : plumbing;;
426 *) echo $i;;
427 esac
428 done
429}
430__git_commandlist=
431__git_commandlist="$(__git_commands 2>/dev/null)"
432
433__git_aliases ()
434{
435 local i IFS=$'\n'
436 for i in $(git --git-dir="$(__gitdir)" config --list); do
437 case "$i" in
438 alias.*)
439 i="${i#alias.}"
440 echo "${i/=*/}"
441 ;;
442 esac
443 done
444}
445
446__git_aliased_command ()
447{
448 local word cmdline=$(git --git-dir="$(__gitdir)" \
449 config --get "alias.$1")
450 for word in $cmdline; do
451 if [ "${word##-*}" ]; then
452 echo $word
453 return
454 fi
455 done
456}
457
458__git_find_subcommand ()
459{
460 local word subcommand c=1
461
462 while [ $c -lt $COMP_CWORD ]; do
463 word="${COMP_WORDS[c]}"
464 for subcommand in $1; do
465 if [ "$subcommand" = "$word" ]; then
466 echo "$subcommand"
467 return
468 fi
469 done
470 c=$((++c))
471 done
472}
473
474__git_has_doubledash ()
475{
476 local c=1
477 while [ $c -lt $COMP_CWORD ]; do
478 if [ "--" = "${COMP_WORDS[c]}" ]; then
479 return 0
480 fi
481 c=$((++c))
482 done
483 return 1
484}
485
486__git_whitespacelist="nowarn warn error error-all strip"
487
488_git_am ()
489{
490 local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
491 if [ -d "$dir"/rebase-apply ]; then
492 __gitcomp "--skip --resolved --abort"
493 return
494 fi
495 case "$cur" in
496 --whitespace=*)
497 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
498 return
499 ;;
500 --*)
501 __gitcomp "
502 --signoff --utf8 --binary --3way --interactive
503 --whitespace=
504 "
505 return
506 esac
507 COMPREPLY=()
508}
509
510_git_apply ()
511{
512 local cur="${COMP_WORDS[COMP_CWORD]}"
513 case "$cur" in
514 --whitespace=*)
515 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
516 return
517 ;;
518 --*)
519 __gitcomp "
520 --stat --numstat --summary --check --index
521 --cached --index-info --reverse --reject --unidiff-zero
522 --apply --no-add --exclude=
523 --whitespace= --inaccurate-eof --verbose
524 "
525 return
526 esac
527 COMPREPLY=()
528}
529
530_git_add ()
531{
532 __git_has_doubledash && return
533
534 local cur="${COMP_WORDS[COMP_CWORD]}"
535 case "$cur" in
536 --*)
537 __gitcomp "
538 --interactive --refresh --patch --update --dry-run
539 --ignore-errors
540 "
541 return
542 esac
543 COMPREPLY=()
544}
545
546_git_bisect ()
547{
548 __git_has_doubledash && return
549
550 local subcommands="start bad good skip reset visualize replay log run"
551 local subcommand="$(__git_find_subcommand "$subcommands")"
552 if [ -z "$subcommand" ]; then
553 __gitcomp "$subcommands"
554 return
555 fi
556
557 case "$subcommand" in
558 bad|good|reset|skip)
559 __gitcomp "$(__git_refs)"
560 ;;
561 *)
562 COMPREPLY=()
563 ;;
564 esac
565}
566
567_git_branch ()
568{
569 local i c=1 only_local_ref="n" has_r="n"
570
571 while [ $c -lt $COMP_CWORD ]; do
572 i="${COMP_WORDS[c]}"
573 case "$i" in
574 -d|-m) only_local_ref="y" ;;
575 -r) has_r="y" ;;
576 esac
577 c=$((++c))
578 done
579
580 case "${COMP_WORDS[COMP_CWORD]}" in
581 --*=*) COMPREPLY=() ;;
582 --*)
583 __gitcomp "
584 --color --no-color --verbose --abbrev= --no-abbrev
585 --track --no-track --contains --merged --no-merged
586 "
587 ;;
588 *)
589 if [ $only_local_ref = "y" -a $has_r = "n" ]; then
590 __gitcomp "$(__git_heads)"
591 else
592 __gitcomp "$(__git_refs)"
593 fi
594 ;;
595 esac
596}
597
598_git_bundle ()
599{
600 local mycword="$COMP_CWORD"
601 case "${COMP_WORDS[0]}" in
602 git)
603 local cmd="${COMP_WORDS[2]}"
604 mycword="$((mycword-1))"
605 ;;
606 git-bundle*)
607 local cmd="${COMP_WORDS[1]}"
608 ;;
609 esac
610 case "$mycword" in
611 1)
612 __gitcomp "create list-heads verify unbundle"
613 ;;
614 2)
615 # looking for a file
616 ;;
617 *)
618 case "$cmd" in
619 create)
620 __git_complete_revlist
621 ;;
622 esac
623 ;;
624 esac
625}
626
627_git_checkout ()
628{
629 __git_has_doubledash && return
630
631 __gitcomp "$(__git_refs)"
632}
633
634_git_cherry ()
635{
636 __gitcomp "$(__git_refs)"
637}
638
639_git_cherry_pick ()
640{
641 local cur="${COMP_WORDS[COMP_CWORD]}"
642 case "$cur" in
643 --*)
644 __gitcomp "--edit --no-commit"
645 ;;
646 *)
647 __gitcomp "$(__git_refs)"
648 ;;
649 esac
650}
651
652_git_commit ()
653{
654 __git_has_doubledash && return
655
656 local cur="${COMP_WORDS[COMP_CWORD]}"
657 case "$cur" in
658 --*)
659 __gitcomp "
660 --all --author= --signoff --verify --no-verify
661 --edit --amend --include --only
662 "
663 return
664 esac
665 COMPREPLY=()
666}
667
668_git_describe ()
669{
670 local cur="${COMP_WORDS[COMP_CWORD]}"
671 case "$cur" in
672 --*)
673 __gitcomp "
674 --all --tags --contains --abbrev= --candidates=
675 --exact-match --debug --long --match --always
676 "
677 return
678 esac
679 __gitcomp "$(__git_refs)"
680}
681
682_git_diff ()
683{
684 __git_has_doubledash && return
685
686 local cur="${COMP_WORDS[COMP_CWORD]}"
687 case "$cur" in
688 --*)
689 __gitcomp "--cached --stat --numstat --shortstat --summary
690 --patch-with-stat --name-only --name-status --color
691 --no-color --color-words --no-renames --check
692 --full-index --binary --abbrev --diff-filter
693 --find-copies-harder --pickaxe-all --pickaxe-regex
694 --text --ignore-space-at-eol --ignore-space-change
695 --ignore-all-space --exit-code --quiet --ext-diff
696 --no-ext-diff
697 --no-prefix --src-prefix= --dst-prefix=
698 --base --ours --theirs
699 "
700 return
701 ;;
702 esac
703 __git_complete_file
704}
705
706_git_diff_tree ()
707{
708 __gitcomp "$(__git_refs)"
709}
710
711_git_fetch ()
712{
713 local cur="${COMP_WORDS[COMP_CWORD]}"
714
715 case "${COMP_WORDS[0]},$COMP_CWORD" in
716 git-fetch*,1)
717 __gitcomp "$(__git_remotes)"
718 ;;
719 git,2)
720 __gitcomp "$(__git_remotes)"
721 ;;
722 *)
723 case "$cur" in
724 *:*)
725 local pfx=""
726 case "$COMP_WORDBREAKS" in
727 *:*) : great ;;
728 *) pfx="${cur%%:*}:" ;;
729 esac
730 __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
731 ;;
732 *)
733 local remote
734 case "${COMP_WORDS[0]}" in
735 git-fetch) remote="${COMP_WORDS[1]}" ;;
736 git) remote="${COMP_WORDS[2]}" ;;
737 esac
738 __gitcomp "$(__git_refs2 "$remote")"
739 ;;
740 esac
741 ;;
742 esac
743}
744
745_git_format_patch ()
746{
747 local cur="${COMP_WORDS[COMP_CWORD]}"
748 case "$cur" in
749 --*)
750 __gitcomp "
751 --stdout --attach --thread
752 --output-directory
753 --numbered --start-number
754 --numbered-files
755 --keep-subject
756 --signoff
757 --in-reply-to=
758 --full-index --binary
759 --not --all
760 --cover-letter
761 --no-prefix --src-prefix= --dst-prefix=
762 "
763 return
764 ;;
765 esac
766 __git_complete_revlist
767}
768
769_git_gc ()
770{
771 local cur="${COMP_WORDS[COMP_CWORD]}"
772 case "$cur" in
773 --*)
774 __gitcomp "--prune --aggressive"
775 return
776 ;;
777 esac
778 COMPREPLY=()
779}
780
781_git_ls_remote ()
782{
783 __gitcomp "$(__git_remotes)"
784}
785
786_git_ls_tree ()
787{
788 __git_complete_file
789}
790
791_git_log ()
792{
793 __git_has_doubledash && return
794
795 local cur="${COMP_WORDS[COMP_CWORD]}"
796 case "$cur" in
797 --pretty=*)
798 __gitcomp "
799 oneline short medium full fuller email raw
800 " "" "${cur##--pretty=}"
801 return
802 ;;
803 --date=*)
804 __gitcomp "
805 relative iso8601 rfc2822 short local default
806 " "" "${cur##--date=}"
807 return
808 ;;
809 --*)
810 __gitcomp "
811 --max-count= --max-age= --since= --after=
812 --min-age= --before= --until=
813 --root --topo-order --date-order --reverse
814 --no-merges --follow
815 --abbrev-commit --abbrev=
816 --relative-date --date=
817 --author= --committer= --grep=
818 --all-match
819 --pretty= --name-status --name-only --raw
820 --not --all
821 --left-right --cherry-pick
822 --graph
823 --stat --numstat --shortstat
824 --decorate --diff-filter=
825 --color-words --walk-reflogs
826 "
827 return
828 ;;
829 esac
830 __git_complete_revlist
831}
832
833_git_merge ()
834{
835 local cur="${COMP_WORDS[COMP_CWORD]}"
836 case "${COMP_WORDS[COMP_CWORD-1]}" in
837 -s|--strategy)
838 __gitcomp "$(__git_merge_strategies)"
839 return
840 esac
841 case "$cur" in
842 --strategy=*)
843 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
844 return
845 ;;
846 --*)
847 __gitcomp "
848 --no-commit --no-stat --log --no-log --squash --strategy
849 "
850 return
851 esac
852 __gitcomp "$(__git_refs)"
853}
854
855_git_merge_base ()
856{
857 __gitcomp "$(__git_refs)"
858}
859
860_git_name_rev ()
861{
862 __gitcomp "--tags --all --stdin"
863}
864
865_git_pull ()
866{
867 local cur="${COMP_WORDS[COMP_CWORD]}"
868
869 case "${COMP_WORDS[0]},$COMP_CWORD" in
870 git-pull*,1)
871 __gitcomp "$(__git_remotes)"
872 ;;
873 git,2)
874 __gitcomp "$(__git_remotes)"
875 ;;
876 *)
877 local remote
878 case "${COMP_WORDS[0]}" in
879 git-pull) remote="${COMP_WORDS[1]}" ;;
880 git) remote="${COMP_WORDS[2]}" ;;
881 esac
882 __gitcomp "$(__git_refs "$remote")"
883 ;;
884 esac
885}
886
887_git_push ()
888{
889 local cur="${COMP_WORDS[COMP_CWORD]}"
890
891 case "${COMP_WORDS[0]},$COMP_CWORD" in
892 git-push*,1)
893 __gitcomp "$(__git_remotes)"
894 ;;
895 git,2)
896 __gitcomp "$(__git_remotes)"
897 ;;
898 *)
899 case "$cur" in
900 *:*)
901 local remote
902 case "${COMP_WORDS[0]}" in
903 git-push) remote="${COMP_WORDS[1]}" ;;
904 git) remote="${COMP_WORDS[2]}" ;;
905 esac
906
907 local pfx=""
908 case "$COMP_WORDBREAKS" in
909 *:*) : great ;;
910 *) pfx="${cur%%:*}:" ;;
911 esac
912
913 __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
914 ;;
915 +*)
916 __gitcomp "$(__git_refs)" + "${cur#+}"
917 ;;
918 *)
919 __gitcomp "$(__git_refs)"
920 ;;
921 esac
922 ;;
923 esac
924}
925
926_git_rebase ()
927{
928 local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
929 if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
930 __gitcomp "--continue --skip --abort"
931 return
932 fi
933 case "${COMP_WORDS[COMP_CWORD-1]}" in
934 -s|--strategy)
935 __gitcomp "$(__git_merge_strategies)"
936 return
937 esac
938 case "$cur" in
939 --strategy=*)
940 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
941 return
942 ;;
943 --*)
944 __gitcomp "--onto --merge --strategy --interactive"
945 return
946 esac
947 __gitcomp "$(__git_refs)"
948}
949
950_git_send_email ()
951{
952 local cur="${COMP_WORDS[COMP_CWORD]}"
953 case "$cur" in
954 --*)
955 __gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
956 --dry-run --envelope-sender --from --identity
957 --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
958 --no-suppress-from --no-thread --quiet
959 --signed-off-by-cc --smtp-pass --smtp-server
960 --smtp-server-port --smtp-ssl --smtp-user --subject
961 --suppress-cc --suppress-from --thread --to"
962 return
963 ;;
964 esac
965 COMPREPLY=()
966}
967
968_git_config ()
969{
970 local cur="${COMP_WORDS[COMP_CWORD]}"
971 local prv="${COMP_WORDS[COMP_CWORD-1]}"
972 case "$prv" in
973 branch.*.remote)
974 __gitcomp "$(__git_remotes)"
975 return
976 ;;
977 branch.*.merge)
978 __gitcomp "$(__git_refs)"
979 return
980 ;;
981 remote.*.fetch)
982 local remote="${prv#remote.}"
983 remote="${remote%.fetch}"
984 __gitcomp "$(__git_refs_remotes "$remote")"
985 return
986 ;;
987 remote.*.push)
988 local remote="${prv#remote.}"
989 remote="${remote%.push}"
990 __gitcomp "$(git --git-dir="$(__gitdir)" \
991 for-each-ref --format='%(refname):%(refname)' \
992 refs/heads)"
993 return
994 ;;
995 pull.twohead|pull.octopus)
996 __gitcomp "$(__git_merge_strategies)"
997 return
998 ;;
999 color.branch|color.diff|color.status)
1000 __gitcomp "always never auto"
1001 return
1002 ;;
1003 color.*.*)
1004 __gitcomp "
1005 black red green yellow blue magenta cyan white
1006 bold dim ul blink reverse
1007 "
1008 return
1009 ;;
1010 *.*)
1011 COMPREPLY=()
1012 return
1013 ;;
1014 esac
1015 case "$cur" in
1016 --*)
1017 __gitcomp "
1018 --global --system --file=
1019 --list --replace-all
1020 --get --get-all --get-regexp
1021 --add --unset --unset-all
1022 --remove-section --rename-section
1023 "
1024 return
1025 ;;
1026 branch.*.*)
1027 local pfx="${cur%.*}."
1028 cur="${cur##*.}"
1029 __gitcomp "remote merge" "$pfx" "$cur"
1030 return
1031 ;;
1032 branch.*)
1033 local pfx="${cur%.*}."
1034 cur="${cur#*.}"
1035 __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1036 return
1037 ;;
1038 remote.*.*)
1039 local pfx="${cur%.*}."
1040 cur="${cur##*.}"
1041 __gitcomp "
1042 url fetch push skipDefaultUpdate
1043 receivepack uploadpack tagopt
1044 " "$pfx" "$cur"
1045 return
1046 ;;
1047 remote.*)
1048 local pfx="${cur%.*}."
1049 cur="${cur#*.}"
1050 __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1051 return
1052 ;;
1053 esac
1054 __gitcomp "
1055 apply.whitespace
1056 core.fileMode
1057 core.gitProxy
1058 core.ignoreStat
1059 core.preferSymlinkRefs
1060 core.logAllRefUpdates
1061 core.loosecompression
1062 core.repositoryFormatVersion
1063 core.sharedRepository
1064 core.warnAmbiguousRefs
1065 core.compression
1066 core.packedGitWindowSize
1067 core.packedGitLimit
1068 clean.requireForce
1069 color.branch
1070 color.branch.current
1071 color.branch.local
1072 color.branch.remote
1073 color.branch.plain
1074 color.diff
1075 color.diff.plain
1076 color.diff.meta
1077 color.diff.frag
1078 color.diff.old
1079 color.diff.new
1080 color.diff.commit
1081 color.diff.whitespace
1082 color.pager
1083 color.status
1084 color.status.header
1085 color.status.added
1086 color.status.changed
1087 color.status.untracked
1088 diff.renameLimit
1089 diff.renames
1090 fetch.unpackLimit
1091 format.headers
1092 format.subjectprefix
1093 gitcvs.enabled
1094 gitcvs.logfile
1095 gitcvs.allbinary
1096 gitcvs.dbname gitcvs.dbdriver gitcvs.dbuser gitcvs.dbpass
1097 gitcvs.dbtablenameprefix
1098 gc.packrefs
1099 gc.reflogexpire
1100 gc.reflogexpireunreachable
1101 gc.rerereresolved
1102 gc.rerereunresolved
1103 http.sslVerify
1104 http.sslCert
1105 http.sslKey
1106 http.sslCAInfo
1107 http.sslCAPath
1108 http.maxRequests
1109 http.lowSpeedLimit
1110 http.lowSpeedTime
1111 http.noEPSV
1112 i18n.commitEncoding
1113 i18n.logOutputEncoding
1114 log.showroot
1115 merge.tool
1116 merge.summary
1117 merge.verbosity
1118 pack.window
1119 pack.depth
1120 pack.windowMemory
1121 pack.compression
1122 pack.deltaCacheSize
1123 pack.deltaCacheLimit
1124 pull.octopus
1125 pull.twohead
1126 repack.useDeltaBaseOffset
1127 showbranch.default
1128 tar.umask
1129 transfer.unpackLimit
1130 receive.unpackLimit
1131 receive.denyNonFastForwards
1132 user.name
1133 user.email
1134 user.signingkey
1135 branch. remote.
1136 "
1137}
1138
1139_git_remote ()
1140{
1141 local subcommands="add rm show prune update"
1142 local subcommand="$(__git_find_subcommand "$subcommands")"
1143 if [ -z "$subcommand" ]; then
1144 __gitcomp "$subcommands"
1145 return
1146 fi
1147
1148 case "$subcommand" in
1149 rm|show|prune)
1150 __gitcomp "$(__git_remotes)"
1151 ;;
1152 update)
1153 local i c='' IFS=$'\n'
1154 for i in $(git --git-dir="$(__gitdir)" config --list); do
1155 case "$i" in
1156 remotes.*)
1157 i="${i#remotes.}"
1158 c="$c ${i/=*/}"
1159 ;;
1160 esac
1161 done
1162 __gitcomp "$c"
1163 ;;
1164 *)
1165 COMPREPLY=()
1166 ;;
1167 esac
1168}
1169
1170_git_reset ()
1171{
1172 __git_has_doubledash && return
1173
1174 local cur="${COMP_WORDS[COMP_CWORD]}"
1175 case "$cur" in
1176 --*)
1177 __gitcomp "--mixed --hard --soft"
1178 return
1179 ;;
1180 esac
1181 __gitcomp "$(__git_refs)"
1182}
1183
1184_git_rm ()
1185{
1186 __git_has_doubledash && return
1187
1188 local cur="${COMP_WORDS[COMP_CWORD]}"
1189 case "$cur" in
1190 --*)
1191 __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
1192 return
1193 ;;
1194 esac
1195 COMPREPLY=()
1196}
1197
1198_git_shortlog ()
1199{
1200 __git_has_doubledash && return
1201
1202 local cur="${COMP_WORDS[COMP_CWORD]}"
1203 case "$cur" in
1204 --*)
1205 __gitcomp "
1206 --max-count= --max-age= --since= --after=
1207 --min-age= --before= --until=
1208 --no-merges
1209 --author= --committer= --grep=
1210 --all-match
1211 --not --all
1212 --numbered --summary
1213 "
1214 return
1215 ;;
1216 esac
1217 __git_complete_revlist
1218}
1219
1220_git_show ()
1221{
1222 local cur="${COMP_WORDS[COMP_CWORD]}"
1223 case "$cur" in
1224 --pretty=*)
1225 __gitcomp "
1226 oneline short medium full fuller email raw
1227 " "" "${cur##--pretty=}"
1228 return
1229 ;;
1230 --*)
1231 __gitcomp "--pretty="
1232 return
1233 ;;
1234 esac
1235 __git_complete_file
1236}
1237
1238_git_show_branch ()
1239{
1240 local cur="${COMP_WORDS[COMP_CWORD]}"
1241 case "$cur" in
1242 --*)
1243 __gitcomp "
1244 --all --remotes --topo-order --current --more=
1245 --list --independent --merge-base --no-name
1246 --sha1-name --topics --reflog
1247 "
1248 return
1249 ;;
1250 esac
1251 __git_complete_revlist
1252}
1253
1254_git_stash ()
1255{
1256 local subcommands='save list show apply clear drop pop create'
1257 local subcommand="$(__git_find_subcommand "$subcommands")"
1258 if [ -z "$subcommand" ]; then
1259 __gitcomp "$subcommands"
1260 else
1261 local cur="${COMP_WORDS[COMP_CWORD]}"
1262 case "$subcommand,$cur" in
1263 save,--*)
1264 __gitcomp "--keep-index"
1265 ;;
1266 *)
1267 COMPREPLY=()
1268 ;;
1269 esac
1270 fi
1271}
1272
1273_git_submodule ()
1274{
1275 __git_has_doubledash && return
1276
1277 local subcommands="add status init update"
1278 if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1279 local cur="${COMP_WORDS[COMP_CWORD]}"
1280 case "$cur" in
1281 --*)
1282 __gitcomp "--quiet --cached"
1283 ;;
1284 *)
1285 __gitcomp "$subcommands"
1286 ;;
1287 esac
1288 return
1289 fi
1290}
1291
1292_git_svn ()
1293{
1294 local subcommands="
1295 init fetch clone rebase dcommit log find-rev
1296 set-tree commit-diff info create-ignore propget
1297 proplist show-ignore show-externals
1298 "
1299 local subcommand="$(__git_find_subcommand "$subcommands")"
1300 if [ -z "$subcommand" ]; then
1301 __gitcomp "$subcommands"
1302 else
1303 local remote_opts="--username= --config-dir= --no-auth-cache"
1304 local fc_opts="
1305 --follow-parent --authors-file= --repack=
1306 --no-metadata --use-svm-props --use-svnsync-props
1307 --log-window-size= --no-checkout --quiet
1308 --repack-flags --user-log-author $remote_opts
1309 "
1310 local init_opts="
1311 --template= --shared= --trunk= --tags=
1312 --branches= --stdlayout --minimize-url
1313 --no-metadata --use-svm-props --use-svnsync-props
1314 --rewrite-root= $remote_opts
1315 "
1316 local cmt_opts="
1317 --edit --rmdir --find-copies-harder --copy-similarity=
1318 "
1319
1320 local cur="${COMP_WORDS[COMP_CWORD]}"
1321 case "$subcommand,$cur" in
1322 fetch,--*)
1323 __gitcomp "--revision= --fetch-all $fc_opts"
1324 ;;
1325 clone,--*)
1326 __gitcomp "--revision= $fc_opts $init_opts"
1327 ;;
1328 init,--*)
1329 __gitcomp "$init_opts"
1330 ;;
1331 dcommit,--*)
1332 __gitcomp "
1333 --merge --strategy= --verbose --dry-run
1334 --fetch-all --no-rebase $cmt_opts $fc_opts
1335 "
1336 ;;
1337 set-tree,--*)
1338 __gitcomp "--stdin $cmt_opts $fc_opts"
1339 ;;
1340 create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
1341 show-externals,--*)
1342 __gitcomp "--revision="
1343 ;;
1344 log,--*)
1345 __gitcomp "
1346 --limit= --revision= --verbose --incremental
1347 --oneline --show-commit --non-recursive
1348 --authors-file=
1349 "
1350 ;;
1351 rebase,--*)
1352 __gitcomp "
1353 --merge --verbose --strategy= --local
1354 --fetch-all $fc_opts
1355 "
1356 ;;
1357 commit-diff,--*)
1358 __gitcomp "--message= --file= --revision= $cmt_opts"
1359 ;;
1360 info,--*)
1361 __gitcomp "--url"
1362 ;;
1363 *)
1364 COMPREPLY=()
1365 ;;
1366 esac
1367 fi
1368}
1369
1370_git_tag ()
1371{
1372 local i c=1 f=0
1373 while [ $c -lt $COMP_CWORD ]; do
1374 i="${COMP_WORDS[c]}"
1375 case "$i" in
1376 -d|-v)
1377 __gitcomp "$(__git_tags)"
1378 return
1379 ;;
1380 -f)
1381 f=1
1382 ;;
1383 esac
1384 c=$((++c))
1385 done
1386
1387 case "${COMP_WORDS[COMP_CWORD-1]}" in
1388 -m|-F)
1389 COMPREPLY=()
1390 ;;
1391 -*|tag|git-tag)
1392 if [ $f = 1 ]; then
1393 __gitcomp "$(__git_tags)"
1394 else
1395 COMPREPLY=()
1396 fi
1397 ;;
1398 *)
1399 __gitcomp "$(__git_refs)"
1400 ;;
1401 esac
1402}
1403
1404_git ()
1405{
1406 local i c=1 command __git_dir
1407
1408 while [ $c -lt $COMP_CWORD ]; do
1409 i="${COMP_WORDS[c]}"
1410 case "$i" in
1411 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
1412 --bare) __git_dir="." ;;
1413 --version|--help|-p|--paginate) ;;
1414 *) command="$i"; break ;;
1415 esac
1416 c=$((++c))
1417 done
1418
1419 if [ -z "$command" ]; then
1420 case "${COMP_WORDS[COMP_CWORD]}" in
1421 --*=*) COMPREPLY=() ;;
1422 --*) __gitcomp "
1423 --paginate
1424 --no-pager
1425 --git-dir=
1426 --bare
1427 --version
1428 --exec-path
1429 --work-tree=
1430 --help
1431 "
1432 ;;
1433 *) __gitcomp "$(__git_commands) $(__git_aliases)" ;;
1434 esac
1435 return
1436 fi
1437
1438 local expansion=$(__git_aliased_command "$command")
1439 [ "$expansion" ] && command="$expansion"
1440
1441 case "$command" in
1442 am) _git_am ;;
1443 add) _git_add ;;
1444 apply) _git_apply ;;
1445 bisect) _git_bisect ;;
1446 bundle) _git_bundle ;;
1447 branch) _git_branch ;;
1448 checkout) _git_checkout ;;
1449 cherry) _git_cherry ;;
1450 cherry-pick) _git_cherry_pick ;;
1451 commit) _git_commit ;;
1452 config) _git_config ;;
1453 describe) _git_describe ;;
1454 diff) _git_diff ;;
1455 fetch) _git_fetch ;;
1456 format-patch) _git_format_patch ;;
1457 gc) _git_gc ;;
1458 log) _git_log ;;
1459 ls-remote) _git_ls_remote ;;
1460 ls-tree) _git_ls_tree ;;
1461 merge) _git_merge;;
1462 merge-base) _git_merge_base ;;
1463 name-rev) _git_name_rev ;;
1464 pull) _git_pull ;;
1465 push) _git_push ;;
1466 rebase) _git_rebase ;;
1467 remote) _git_remote ;;
1468 reset) _git_reset ;;
1469 rm) _git_rm ;;
1470 send-email) _git_send_email ;;
1471 shortlog) _git_shortlog ;;
1472 show) _git_show ;;
1473 show-branch) _git_show_branch ;;
1474 stash) _git_stash ;;
1475 submodule) _git_submodule ;;
1476 svn) _git_svn ;;
1477 tag) _git_tag ;;
1478 whatchanged) _git_log ;;
1479 *) COMPREPLY=() ;;
1480 esac
1481}
1482
1483_gitk ()
1484{
1485 __git_has_doubledash && return
1486
1487 local cur="${COMP_WORDS[COMP_CWORD]}"
1488 local g="$(git rev-parse --git-dir 2>/dev/null)"
1489 local merge=""
1490 if [ -f $g/MERGE_HEAD ]; then
1491 merge="--merge"
1492 fi
1493 case "$cur" in
1494 --*)
1495 __gitcomp "--not --all $merge"
1496 return
1497 ;;
1498 esac
1499 __git_complete_revlist
1500}
1501
1502complete -o default -o nospace -F _git git
1503complete -o default -o nospace -F _gitk gitk
1504
1505# The following are necessary only for Cygwin, and only are needed
1506# when the user has tab-completed the executable name and consequently
1507# included the '.exe' suffix.
1508#
1509if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1510complete -o default -o nospace -F _git git.exe
1511fi