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 git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
158 refs/heads
159 return
160 fi
161 for i in $(git ls-remote "$1" 2>/dev/null); do
162 case "$is_hash,$i" in
163 y,*) is_hash=n ;;
164 n,*^{}) is_hash=y ;;
165 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
166 n,*) is_hash=y; echo "$i" ;;
167 esac
168 done
169}
170
171__git_tags ()
172{
173 local cmd i is_hash=y dir="$(__gitdir "$1")"
174 if [ -d "$dir" ]; then
175 git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
176 refs/tags
177 return
178 fi
179 for i in $(git ls-remote "$1" 2>/dev/null); do
180 case "$is_hash,$i" in
181 y,*) is_hash=n ;;
182 n,*^{}) is_hash=y ;;
183 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
184 n,*) is_hash=y; echo "$i" ;;
185 esac
186 done
187}
188
189__git_refs ()
190{
191 local cmd i is_hash=y dir="$(__gitdir "$1")"
192 if [ -d "$dir" ]; then
193 if [ -e "$dir/HEAD" ]; then echo HEAD; fi
194 git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
195 refs/tags refs/heads refs/remotes
196 return
197 fi
198 for i in $(git ls-remote "$dir" 2>/dev/null); do
199 case "$is_hash,$i" in
200 y,*) is_hash=n ;;
201 n,*^{}) is_hash=y ;;
202 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
203 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
204 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
205 n,*) is_hash=y; echo "$i" ;;
206 esac
207 done
208}
209
210__git_refs2 ()
211{
212 local i
213 for i in $(__git_refs "$1"); do
214 echo "$i:$i"
215 done
216}
217
218__git_refs_remotes ()
219{
220 local cmd i is_hash=y
221 for i in $(git ls-remote "$1" 2>/dev/null); do
222 case "$is_hash,$i" in
223 n,refs/heads/*)
224 is_hash=y
225 echo "$i:refs/remotes/$1/${i#refs/heads/}"
226 ;;
227 y,*) is_hash=n ;;
228 n,*^{}) is_hash=y ;;
229 n,refs/tags/*) is_hash=y;;
230 n,*) is_hash=y; ;;
231 esac
232 done
233}
234
235__git_remotes ()
236{
237 local i ngoff IFS=$'\n' d="$(__gitdir)"
238 shopt -q nullglob || ngoff=1
239 shopt -s nullglob
240 for i in "$d/remotes"/*; do
241 echo ${i#$d/remotes/}
242 done
243 [ "$ngoff" ] && shopt -u nullglob
244 for i in $(git --git-dir="$d" config --list); do
245 case "$i" in
246 remote.*.url=*)
247 i="${i#remote.}"
248 echo "${i/.url=*/}"
249 ;;
250 esac
251 done
252}
253
254__git_merge_strategies ()
255{
256 if [ -n "$__git_merge_strategylist" ]; then
257 echo "$__git_merge_strategylist"
258 return
259 fi
260 git merge -s help 2>&1 |
261 sed -n -e '/[Aa]vailable strategies are: /,/^$/{
262 s/\.$//
263 s/.*://
264 s/^[ ]*//
265 s/[ ]*$//
266 p
267 }'
268}
269__git_merge_strategylist=
270__git_merge_strategylist=$(__git_merge_strategies 2>/dev/null)
271
272__git_complete_file ()
273{
274 local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
275 case "$cur" in
276 ?*:*)
277 ref="${cur%%:*}"
278 cur="${cur#*:}"
279 case "$cur" in
280 ?*/*)
281 pfx="${cur%/*}"
282 cur="${cur##*/}"
283 ls="$ref:$pfx"
284 pfx="$pfx/"
285 ;;
286 *)
287 ls="$ref"
288 ;;
289 esac
290
291 case "$COMP_WORDBREAKS" in
292 *:*) : great ;;
293 *) pfx="$ref:$pfx" ;;
294 esac
295
296 local IFS=$'\n'
297 COMPREPLY=($(compgen -P "$pfx" \
298 -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
299 | sed '/^100... blob /{
300 s,^.* ,,
301 s,$, ,
302 }
303 /^120000 blob /{
304 s,^.* ,,
305 s,$, ,
306 }
307 /^040000 tree /{
308 s,^.* ,,
309 s,$,/,
310 }
311 s/^.* //')" \
312 -- "$cur"))
313 ;;
314 *)
315 __gitcomp "$(__git_refs)"
316 ;;
317 esac
318}
319
320__git_complete_revlist ()
321{
322 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
323 case "$cur" in
324 *...*)
325 pfx="${cur%...*}..."
326 cur="${cur#*...}"
327 __gitcomp "$(__git_refs)" "$pfx" "$cur"
328 ;;
329 *..*)
330 pfx="${cur%..*}.."
331 cur="${cur#*..}"
332 __gitcomp "$(__git_refs)" "$pfx" "$cur"
333 ;;
334 *)
335 __gitcomp "$(__git_refs)"
336 ;;
337 esac
338}
339
340__git_all_commands ()
341{
342 if [ -n "$__git_all_commandlist" ]; then
343 echo "$__git_all_commandlist"
344 return
345 fi
346 local i IFS=" "$'\n'
347 for i in $(git help -a|egrep '^ ')
348 do
349 case $i in
350 *--*) : helper pattern;;
351 *) echo $i;;
352 esac
353 done
354}
355__git_all_commandlist=
356__git_all_commandlist="$(__git_all_commands 2>/dev/null)"
357
358__git_porcelain_commands ()
359{
360 if [ -n "$__git_porcelain_commandlist" ]; then
361 echo "$__git_porcelain_commandlist"
362 return
363 fi
364 local i IFS=" "$'\n'
365 for i in "help" $(__git_all_commands)
366 do
367 case $i in
368 *--*) : helper pattern;;
369 applymbox) : ask gittus;;
370 applypatch) : ask gittus;;
371 archimport) : import;;
372 cat-file) : plumbing;;
373 check-attr) : plumbing;;
374 check-ref-format) : plumbing;;
375 checkout-index) : plumbing;;
376 commit-tree) : plumbing;;
377 count-objects) : infrequent;;
378 cvsexportcommit) : export;;
379 cvsimport) : import;;
380 cvsserver) : daemon;;
381 daemon) : daemon;;
382 diff-files) : plumbing;;
383 diff-index) : plumbing;;
384 diff-tree) : plumbing;;
385 fast-import) : import;;
386 fast-export) : export;;
387 fsck-objects) : plumbing;;
388 fetch-pack) : plumbing;;
389 fmt-merge-msg) : plumbing;;
390 for-each-ref) : plumbing;;
391 hash-object) : plumbing;;
392 http-*) : transport;;
393 index-pack) : plumbing;;
394 init-db) : deprecated;;
395 local-fetch) : plumbing;;
396 lost-found) : infrequent;;
397 ls-files) : plumbing;;
398 ls-remote) : plumbing;;
399 ls-tree) : plumbing;;
400 mailinfo) : plumbing;;
401 mailsplit) : plumbing;;
402 merge-*) : plumbing;;
403 mktree) : plumbing;;
404 mktag) : plumbing;;
405 pack-objects) : plumbing;;
406 pack-redundant) : plumbing;;
407 pack-refs) : plumbing;;
408 parse-remote) : plumbing;;
409 patch-id) : plumbing;;
410 peek-remote) : plumbing;;
411 prune) : plumbing;;
412 prune-packed) : plumbing;;
413 quiltimport) : import;;
414 read-tree) : plumbing;;
415 receive-pack) : plumbing;;
416 reflog) : plumbing;;
417 repo-config) : deprecated;;
418 rerere) : plumbing;;
419 rev-list) : plumbing;;
420 rev-parse) : plumbing;;
421 runstatus) : plumbing;;
422 sh-setup) : internal;;
423 shell) : daemon;;
424 show-ref) : plumbing;;
425 send-pack) : plumbing;;
426 show-index) : plumbing;;
427 ssh-*) : transport;;
428 stripspace) : plumbing;;
429 symbolic-ref) : plumbing;;
430 tar-tree) : deprecated;;
431 unpack-file) : plumbing;;
432 unpack-objects) : plumbing;;
433 update-index) : plumbing;;
434 update-ref) : plumbing;;
435 update-server-info) : daemon;;
436 upload-archive) : plumbing;;
437 upload-pack) : plumbing;;
438 write-tree) : plumbing;;
439 var) : infrequent;;
440 verify-pack) : infrequent;;
441 verify-tag) : plumbing;;
442 *) echo $i;;
443 esac
444 done
445}
446__git_porcelain_commandlist=
447__git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)"
448
449__git_aliases ()
450{
451 local i IFS=$'\n'
452 for i in $(git --git-dir="$(__gitdir)" config --list); do
453 case "$i" in
454 alias.*)
455 i="${i#alias.}"
456 echo "${i/=*/}"
457 ;;
458 esac
459 done
460}
461
462__git_aliased_command ()
463{
464 local word cmdline=$(git --git-dir="$(__gitdir)" \
465 config --get "alias.$1")
466 for word in $cmdline; do
467 if [ "${word##-*}" ]; then
468 echo $word
469 return
470 fi
471 done
472}
473
474__git_find_subcommand ()
475{
476 local word subcommand c=1
477
478 while [ $c -lt $COMP_CWORD ]; do
479 word="${COMP_WORDS[c]}"
480 for subcommand in $1; do
481 if [ "$subcommand" = "$word" ]; then
482 echo "$subcommand"
483 return
484 fi
485 done
486 c=$((++c))
487 done
488}
489
490__git_has_doubledash ()
491{
492 local c=1
493 while [ $c -lt $COMP_CWORD ]; do
494 if [ "--" = "${COMP_WORDS[c]}" ]; then
495 return 0
496 fi
497 c=$((++c))
498 done
499 return 1
500}
501
502__git_whitespacelist="nowarn warn error error-all fix"
503
504_git_am ()
505{
506 local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
507 if [ -d "$dir"/rebase-apply ]; then
508 __gitcomp "--skip --resolved --abort"
509 return
510 fi
511 case "$cur" in
512 --whitespace=*)
513 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
514 return
515 ;;
516 --*)
517 __gitcomp "
518 --signoff --utf8 --binary --3way --interactive
519 --whitespace=
520 "
521 return
522 esac
523 COMPREPLY=()
524}
525
526_git_apply ()
527{
528 local cur="${COMP_WORDS[COMP_CWORD]}"
529 case "$cur" in
530 --whitespace=*)
531 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
532 return
533 ;;
534 --*)
535 __gitcomp "
536 --stat --numstat --summary --check --index
537 --cached --index-info --reverse --reject --unidiff-zero
538 --apply --no-add --exclude=
539 --whitespace= --inaccurate-eof --verbose
540 "
541 return
542 esac
543 COMPREPLY=()
544}
545
546_git_add ()
547{
548 __git_has_doubledash && return
549
550 local cur="${COMP_WORDS[COMP_CWORD]}"
551 case "$cur" in
552 --*)
553 __gitcomp "
554 --interactive --refresh --patch --update --dry-run
555 --ignore-errors
556 "
557 return
558 esac
559 COMPREPLY=()
560}
561
562_git_archive ()
563{
564 local cur="${COMP_WORDS[COMP_CWORD]}"
565 case "$cur" in
566 --format=*)
567 __gitcomp "$(git archive --list)" "" "${cur##--format=}"
568 return
569 ;;
570 --remote=*)
571 __gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
572 return
573 ;;
574 --*)
575 __gitcomp "
576 --format= --list --verbose
577 --prefix= --remote= --exec=
578 "
579 return
580 ;;
581 esac
582 __git_complete_file
583}
584
585_git_bisect ()
586{
587 __git_has_doubledash && return
588
589 local subcommands="start bad good skip reset visualize replay log run"
590 local subcommand="$(__git_find_subcommand "$subcommands")"
591 if [ -z "$subcommand" ]; then
592 __gitcomp "$subcommands"
593 return
594 fi
595
596 case "$subcommand" in
597 bad|good|reset|skip)
598 __gitcomp "$(__git_refs)"
599 ;;
600 *)
601 COMPREPLY=()
602 ;;
603 esac
604}
605
606_git_branch ()
607{
608 local i c=1 only_local_ref="n" has_r="n"
609
610 while [ $c -lt $COMP_CWORD ]; do
611 i="${COMP_WORDS[c]}"
612 case "$i" in
613 -d|-m) only_local_ref="y" ;;
614 -r) has_r="y" ;;
615 esac
616 c=$((++c))
617 done
618
619 case "${COMP_WORDS[COMP_CWORD]}" in
620 --*=*) COMPREPLY=() ;;
621 --*)
622 __gitcomp "
623 --color --no-color --verbose --abbrev= --no-abbrev
624 --track --no-track --contains --merged --no-merged
625 "
626 ;;
627 *)
628 if [ $only_local_ref = "y" -a $has_r = "n" ]; then
629 __gitcomp "$(__git_heads)"
630 else
631 __gitcomp "$(__git_refs)"
632 fi
633 ;;
634 esac
635}
636
637_git_bundle ()
638{
639 local mycword="$COMP_CWORD"
640 case "${COMP_WORDS[0]}" in
641 git)
642 local cmd="${COMP_WORDS[2]}"
643 mycword="$((mycword-1))"
644 ;;
645 git-bundle*)
646 local cmd="${COMP_WORDS[1]}"
647 ;;
648 esac
649 case "$mycword" in
650 1)
651 __gitcomp "create list-heads verify unbundle"
652 ;;
653 2)
654 # looking for a file
655 ;;
656 *)
657 case "$cmd" in
658 create)
659 __git_complete_revlist
660 ;;
661 esac
662 ;;
663 esac
664}
665
666_git_checkout ()
667{
668 __git_has_doubledash && return
669
670 __gitcomp "$(__git_refs)"
671}
672
673_git_cherry ()
674{
675 __gitcomp "$(__git_refs)"
676}
677
678_git_cherry_pick ()
679{
680 local cur="${COMP_WORDS[COMP_CWORD]}"
681 case "$cur" in
682 --*)
683 __gitcomp "--edit --no-commit"
684 ;;
685 *)
686 __gitcomp "$(__git_refs)"
687 ;;
688 esac
689}
690
691_git_clean ()
692{
693 __git_has_doubledash && return
694
695 local cur="${COMP_WORDS[COMP_CWORD]}"
696 case "$cur" in
697 --*)
698 __gitcomp "--dry-run --quiet"
699 return
700 ;;
701 esac
702 COMPREPLY=()
703}
704
705_git_clone ()
706{
707 local cur="${COMP_WORDS[COMP_CWORD]}"
708 case "$cur" in
709 --*)
710 __gitcomp "
711 --local
712 --no-hardlinks
713 --shared
714 --reference
715 --quiet
716 --no-checkout
717 --bare
718 --mirror
719 --origin
720 --upload-pack
721 --template=
722 --depth
723 "
724 return
725 ;;
726 esac
727 COMPREPLY=()
728}
729
730_git_commit ()
731{
732 __git_has_doubledash && return
733
734 local cur="${COMP_WORDS[COMP_CWORD]}"
735 case "$cur" in
736 --*)
737 __gitcomp "
738 --all --author= --signoff --verify --no-verify
739 --edit --amend --include --only --interactive
740 "
741 return
742 esac
743 COMPREPLY=()
744}
745
746_git_describe ()
747{
748 local cur="${COMP_WORDS[COMP_CWORD]}"
749 case "$cur" in
750 --*)
751 __gitcomp "
752 --all --tags --contains --abbrev= --candidates=
753 --exact-match --debug --long --match --always
754 "
755 return
756 esac
757 __gitcomp "$(__git_refs)"
758}
759
760_git_diff ()
761{
762 __git_has_doubledash && return
763
764 local cur="${COMP_WORDS[COMP_CWORD]}"
765 case "$cur" in
766 --*)
767 __gitcomp "--cached --stat --numstat --shortstat --summary
768 --patch-with-stat --name-only --name-status --color
769 --no-color --color-words --no-renames --check
770 --full-index --binary --abbrev --diff-filter=
771 --find-copies-harder --pickaxe-all --pickaxe-regex
772 --text --ignore-space-at-eol --ignore-space-change
773 --ignore-all-space --exit-code --quiet --ext-diff
774 --no-ext-diff
775 --no-prefix --src-prefix= --dst-prefix=
776 --base --ours --theirs
777 "
778 return
779 ;;
780 esac
781 __git_complete_file
782}
783
784_git_fetch ()
785{
786 local cur="${COMP_WORDS[COMP_CWORD]}"
787
788 case "${COMP_WORDS[0]},$COMP_CWORD" in
789 git-fetch*,1)
790 __gitcomp "$(__git_remotes)"
791 ;;
792 git,2)
793 __gitcomp "$(__git_remotes)"
794 ;;
795 *)
796 case "$cur" in
797 *:*)
798 local pfx=""
799 case "$COMP_WORDBREAKS" in
800 *:*) : great ;;
801 *) pfx="${cur%%:*}:" ;;
802 esac
803 __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
804 ;;
805 *)
806 local remote
807 case "${COMP_WORDS[0]}" in
808 git-fetch) remote="${COMP_WORDS[1]}" ;;
809 git) remote="${COMP_WORDS[2]}" ;;
810 esac
811 __gitcomp "$(__git_refs2 "$remote")"
812 ;;
813 esac
814 ;;
815 esac
816}
817
818_git_format_patch ()
819{
820 local cur="${COMP_WORDS[COMP_CWORD]}"
821 case "$cur" in
822 --*)
823 __gitcomp "
824 --stdout --attach --thread
825 --output-directory
826 --numbered --start-number
827 --numbered-files
828 --keep-subject
829 --signoff
830 --in-reply-to=
831 --full-index --binary
832 --not --all
833 --cover-letter
834 --no-prefix --src-prefix= --dst-prefix=
835 "
836 return
837 ;;
838 esac
839 __git_complete_revlist
840}
841
842_git_gc ()
843{
844 local cur="${COMP_WORDS[COMP_CWORD]}"
845 case "$cur" in
846 --*)
847 __gitcomp "--prune --aggressive"
848 return
849 ;;
850 esac
851 COMPREPLY=()
852}
853
854_git_grep ()
855{
856 __git_has_doubledash && return
857
858 local cur="${COMP_WORDS[COMP_CWORD]}"
859 case "$cur" in
860 --*)
861 __gitcomp "
862 --cached
863 --text --ignore-case --word-regexp --invert-match
864 --full-name
865 --extended-regexp --basic-regexp --fixed-strings
866 --files-with-matches --name-only
867 --files-without-match
868 --count
869 --and --or --not --all-match
870 "
871 return
872 ;;
873 esac
874 COMPREPLY=()
875}
876
877_git_help ()
878{
879 local cur="${COMP_WORDS[COMP_CWORD]}"
880 case "$cur" in
881 --*)
882 __gitcomp "--all --info --man --web"
883 return
884 ;;
885 esac
886 __gitcomp "$(__git_all_commands)
887 attributes cli core-tutorial cvs-migration
888 diffcore gitk glossary hooks ignore modules
889 repository-layout tutorial tutorial-2
890 "
891}
892
893_git_init ()
894{
895 local cur="${COMP_WORDS[COMP_CWORD]}"
896 case "$cur" in
897 --shared=*)
898 __gitcomp "
899 false true umask group all world everybody
900 " "" "${cur##--shared=}"
901 return
902 ;;
903 --*)
904 __gitcomp "--quiet --bare --template= --shared --shared="
905 return
906 ;;
907 esac
908 COMPREPLY=()
909}
910
911_git_ls_files ()
912{
913 __git_has_doubledash && return
914
915 local cur="${COMP_WORDS[COMP_CWORD]}"
916 case "$cur" in
917 --*)
918 __gitcomp "--cached --deleted --modified --others --ignored
919 --stage --directory --no-empty-directory --unmerged
920 --killed --exclude= --exclude-from=
921 --exclude-per-directory= --exclude-standard
922 --error-unmatch --with-tree= --full-name
923 --abbrev --ignored --exclude-per-directory
924 "
925 return
926 ;;
927 esac
928 COMPREPLY=()
929}
930
931_git_ls_remote ()
932{
933 __gitcomp "$(__git_remotes)"
934}
935
936_git_ls_tree ()
937{
938 __git_complete_file
939}
940
941_git_log ()
942{
943 __git_has_doubledash && return
944
945 local cur="${COMP_WORDS[COMP_CWORD]}"
946 case "$cur" in
947 --pretty=*)
948 __gitcomp "
949 oneline short medium full fuller email raw
950 " "" "${cur##--pretty=}"
951 return
952 ;;
953 --date=*)
954 __gitcomp "
955 relative iso8601 rfc2822 short local default
956 " "" "${cur##--date=}"
957 return
958 ;;
959 --*)
960 __gitcomp "
961 --max-count= --max-age= --since= --after=
962 --min-age= --before= --until=
963 --root --topo-order --date-order --reverse
964 --no-merges --follow
965 --abbrev-commit --abbrev=
966 --relative-date --date=
967 --author= --committer= --grep=
968 --all-match
969 --pretty= --name-status --name-only --raw
970 --not --all
971 --left-right --cherry-pick
972 --graph
973 --stat --numstat --shortstat
974 --decorate --diff-filter=
975 --color-words --walk-reflogs
976 --parents --children --full-history
977 --merge
978 "
979 return
980 ;;
981 esac
982 __git_complete_revlist
983}
984
985_git_merge ()
986{
987 local cur="${COMP_WORDS[COMP_CWORD]}"
988 case "${COMP_WORDS[COMP_CWORD-1]}" in
989 -s|--strategy)
990 __gitcomp "$(__git_merge_strategies)"
991 return
992 esac
993 case "$cur" in
994 --strategy=*)
995 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
996 return
997 ;;
998 --*)
999 __gitcomp "
1000 --no-commit --no-stat --log --no-log --squash --strategy
1001 "
1002 return
1003 esac
1004 __gitcomp "$(__git_refs)"
1005}
1006
1007_git_mergetool ()
1008{
1009 local cur="${COMP_WORDS[COMP_CWORD]}"
1010 case "$cur" in
1011 --tool=*)
1012 __gitcomp "
1013 kdiff3 tkdiff meld xxdiff emerge
1014 vimdiff gvimdiff ecmerge opendiff
1015 " "" "${cur##--tool=}"
1016 return
1017 ;;
1018 --*)
1019 __gitcomp "--tool="
1020 return
1021 ;;
1022 esac
1023 COMPREPLY=()
1024}
1025
1026_git_merge_base ()
1027{
1028 __gitcomp "$(__git_refs)"
1029}
1030
1031_git_mv ()
1032{
1033 local cur="${COMP_WORDS[COMP_CWORD]}"
1034 case "$cur" in
1035 --*)
1036 __gitcomp "--dry-run"
1037 return
1038 ;;
1039 esac
1040 COMPREPLY=()
1041}
1042
1043_git_name_rev ()
1044{
1045 __gitcomp "--tags --all --stdin"
1046}
1047
1048_git_pull ()
1049{
1050 local cur="${COMP_WORDS[COMP_CWORD]}"
1051
1052 case "${COMP_WORDS[0]},$COMP_CWORD" in
1053 git-pull*,1)
1054 __gitcomp "$(__git_remotes)"
1055 ;;
1056 git,2)
1057 __gitcomp "$(__git_remotes)"
1058 ;;
1059 *)
1060 local remote
1061 case "${COMP_WORDS[0]}" in
1062 git-pull) remote="${COMP_WORDS[1]}" ;;
1063 git) remote="${COMP_WORDS[2]}" ;;
1064 esac
1065 __gitcomp "$(__git_refs "$remote")"
1066 ;;
1067 esac
1068}
1069
1070_git_push ()
1071{
1072 local cur="${COMP_WORDS[COMP_CWORD]}"
1073
1074 case "${COMP_WORDS[0]},$COMP_CWORD" in
1075 git-push*,1)
1076 __gitcomp "$(__git_remotes)"
1077 ;;
1078 git,2)
1079 __gitcomp "$(__git_remotes)"
1080 ;;
1081 *)
1082 case "$cur" in
1083 *:*)
1084 local remote
1085 case "${COMP_WORDS[0]}" in
1086 git-push) remote="${COMP_WORDS[1]}" ;;
1087 git) remote="${COMP_WORDS[2]}" ;;
1088 esac
1089
1090 local pfx=""
1091 case "$COMP_WORDBREAKS" in
1092 *:*) : great ;;
1093 *) pfx="${cur%%:*}:" ;;
1094 esac
1095
1096 __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
1097 ;;
1098 +*)
1099 __gitcomp "$(__git_refs)" + "${cur#+}"
1100 ;;
1101 *)
1102 __gitcomp "$(__git_refs)"
1103 ;;
1104 esac
1105 ;;
1106 esac
1107}
1108
1109_git_rebase ()
1110{
1111 local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
1112 if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1113 __gitcomp "--continue --skip --abort"
1114 return
1115 fi
1116 case "${COMP_WORDS[COMP_CWORD-1]}" in
1117 -s|--strategy)
1118 __gitcomp "$(__git_merge_strategies)"
1119 return
1120 esac
1121 case "$cur" in
1122 --strategy=*)
1123 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
1124 return
1125 ;;
1126 --*)
1127 __gitcomp "--onto --merge --strategy --interactive"
1128 return
1129 esac
1130 __gitcomp "$(__git_refs)"
1131}
1132
1133_git_send_email ()
1134{
1135 local cur="${COMP_WORDS[COMP_CWORD]}"
1136 case "$cur" in
1137 --*)
1138 __gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
1139 --dry-run --envelope-sender --from --identity
1140 --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1141 --no-suppress-from --no-thread --quiet
1142 --signed-off-by-cc --smtp-pass --smtp-server
1143 --smtp-server-port --smtp-ssl --smtp-user --subject
1144 --suppress-cc --suppress-from --thread --to"
1145 return
1146 ;;
1147 esac
1148 COMPREPLY=()
1149}
1150
1151_git_config ()
1152{
1153 local cur="${COMP_WORDS[COMP_CWORD]}"
1154 local prv="${COMP_WORDS[COMP_CWORD-1]}"
1155 case "$prv" in
1156 branch.*.remote)
1157 __gitcomp "$(__git_remotes)"
1158 return
1159 ;;
1160 branch.*.merge)
1161 __gitcomp "$(__git_refs)"
1162 return
1163 ;;
1164 remote.*.fetch)
1165 local remote="${prv#remote.}"
1166 remote="${remote%.fetch}"
1167 __gitcomp "$(__git_refs_remotes "$remote")"
1168 return
1169 ;;
1170 remote.*.push)
1171 local remote="${prv#remote.}"
1172 remote="${remote%.push}"
1173 __gitcomp "$(git --git-dir="$(__gitdir)" \
1174 for-each-ref --format='%(refname):%(refname)' \
1175 refs/heads)"
1176 return
1177 ;;
1178 pull.twohead|pull.octopus)
1179 __gitcomp "$(__git_merge_strategies)"
1180 return
1181 ;;
1182 color.branch|color.diff|color.status)
1183 __gitcomp "always never auto"
1184 return
1185 ;;
1186 color.*.*)
1187 __gitcomp "
1188 black red green yellow blue magenta cyan white
1189 bold dim ul blink reverse
1190 "
1191 return
1192 ;;
1193 *.*)
1194 COMPREPLY=()
1195 return
1196 ;;
1197 esac
1198 case "$cur" in
1199 --*)
1200 __gitcomp "
1201 --global --system --file=
1202 --list --replace-all
1203 --get --get-all --get-regexp
1204 --add --unset --unset-all
1205 --remove-section --rename-section
1206 "
1207 return
1208 ;;
1209 branch.*.*)
1210 local pfx="${cur%.*}."
1211 cur="${cur##*.}"
1212 __gitcomp "remote merge" "$pfx" "$cur"
1213 return
1214 ;;
1215 branch.*)
1216 local pfx="${cur%.*}."
1217 cur="${cur#*.}"
1218 __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1219 return
1220 ;;
1221 remote.*.*)
1222 local pfx="${cur%.*}."
1223 cur="${cur##*.}"
1224 __gitcomp "
1225 url fetch push skipDefaultUpdate
1226 receivepack uploadpack tagopt
1227 " "$pfx" "$cur"
1228 return
1229 ;;
1230 remote.*)
1231 local pfx="${cur%.*}."
1232 cur="${cur#*.}"
1233 __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1234 return
1235 ;;
1236 esac
1237 __gitcomp "
1238 apply.whitespace
1239 core.fileMode
1240 core.gitProxy
1241 core.ignoreStat
1242 core.preferSymlinkRefs
1243 core.logAllRefUpdates
1244 core.loosecompression
1245 core.repositoryFormatVersion
1246 core.sharedRepository
1247 core.warnAmbiguousRefs
1248 core.compression
1249 core.packedGitWindowSize
1250 core.packedGitLimit
1251 clean.requireForce
1252 color.branch
1253 color.branch.current
1254 color.branch.local
1255 color.branch.remote
1256 color.branch.plain
1257 color.diff
1258 color.diff.plain
1259 color.diff.meta
1260 color.diff.frag
1261 color.diff.old
1262 color.diff.new
1263 color.diff.commit
1264 color.diff.whitespace
1265 color.pager
1266 color.status
1267 color.status.header
1268 color.status.added
1269 color.status.changed
1270 color.status.untracked
1271 diff.renameLimit
1272 diff.renames
1273 fetch.unpackLimit
1274 format.headers
1275 format.subjectprefix
1276 gitcvs.enabled
1277 gitcvs.logfile
1278 gitcvs.allbinary
1279 gitcvs.dbname gitcvs.dbdriver gitcvs.dbuser gitcvs.dbpass
1280 gitcvs.dbtablenameprefix
1281 gc.packrefs
1282 gc.reflogexpire
1283 gc.reflogexpireunreachable
1284 gc.rerereresolved
1285 gc.rerereunresolved
1286 http.sslVerify
1287 http.sslCert
1288 http.sslKey
1289 http.sslCAInfo
1290 http.sslCAPath
1291 http.maxRequests
1292 http.lowSpeedLimit
1293 http.lowSpeedTime
1294 http.noEPSV
1295 i18n.commitEncoding
1296 i18n.logOutputEncoding
1297 log.showroot
1298 merge.tool
1299 merge.summary
1300 merge.verbosity
1301 pack.window
1302 pack.depth
1303 pack.windowMemory
1304 pack.compression
1305 pack.deltaCacheSize
1306 pack.deltaCacheLimit
1307 pull.octopus
1308 pull.twohead
1309 repack.useDeltaBaseOffset
1310 showbranch.default
1311 tar.umask
1312 transfer.unpackLimit
1313 receive.unpackLimit
1314 receive.denyNonFastForwards
1315 user.name
1316 user.email
1317 user.signingkey
1318 branch. remote.
1319 "
1320}
1321
1322_git_remote ()
1323{
1324 local subcommands="add rm show prune update"
1325 local subcommand="$(__git_find_subcommand "$subcommands")"
1326 if [ -z "$subcommand" ]; then
1327 __gitcomp "$subcommands"
1328 return
1329 fi
1330
1331 case "$subcommand" in
1332 rm|show|prune)
1333 __gitcomp "$(__git_remotes)"
1334 ;;
1335 update)
1336 local i c='' IFS=$'\n'
1337 for i in $(git --git-dir="$(__gitdir)" config --list); do
1338 case "$i" in
1339 remotes.*)
1340 i="${i#remotes.}"
1341 c="$c ${i/=*/}"
1342 ;;
1343 esac
1344 done
1345 __gitcomp "$c"
1346 ;;
1347 *)
1348 COMPREPLY=()
1349 ;;
1350 esac
1351}
1352
1353_git_reset ()
1354{
1355 __git_has_doubledash && return
1356
1357 local cur="${COMP_WORDS[COMP_CWORD]}"
1358 case "$cur" in
1359 --*)
1360 __gitcomp "--mixed --hard --soft"
1361 return
1362 ;;
1363 esac
1364 __gitcomp "$(__git_refs)"
1365}
1366
1367_git_revert ()
1368{
1369 local cur="${COMP_WORDS[COMP_CWORD]}"
1370 case "$cur" in
1371 --*)
1372 __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
1373 return
1374 ;;
1375 esac
1376 COMPREPLY=()
1377}
1378
1379_git_rm ()
1380{
1381 __git_has_doubledash && return
1382
1383 local cur="${COMP_WORDS[COMP_CWORD]}"
1384 case "$cur" in
1385 --*)
1386 __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
1387 return
1388 ;;
1389 esac
1390 COMPREPLY=()
1391}
1392
1393_git_shortlog ()
1394{
1395 __git_has_doubledash && return
1396
1397 local cur="${COMP_WORDS[COMP_CWORD]}"
1398 case "$cur" in
1399 --*)
1400 __gitcomp "
1401 --max-count= --max-age= --since= --after=
1402 --min-age= --before= --until=
1403 --no-merges
1404 --author= --committer= --grep=
1405 --all-match
1406 --not --all
1407 --numbered --summary
1408 "
1409 return
1410 ;;
1411 esac
1412 __git_complete_revlist
1413}
1414
1415_git_show ()
1416{
1417 local cur="${COMP_WORDS[COMP_CWORD]}"
1418 case "$cur" in
1419 --pretty=*)
1420 __gitcomp "
1421 oneline short medium full fuller email raw
1422 " "" "${cur##--pretty=}"
1423 return
1424 ;;
1425 --*)
1426 __gitcomp "--pretty="
1427 return
1428 ;;
1429 esac
1430 __git_complete_file
1431}
1432
1433_git_show_branch ()
1434{
1435 local cur="${COMP_WORDS[COMP_CWORD]}"
1436 case "$cur" in
1437 --*)
1438 __gitcomp "
1439 --all --remotes --topo-order --current --more=
1440 --list --independent --merge-base --no-name
1441 --sha1-name --topics --reflog
1442 "
1443 return
1444 ;;
1445 esac
1446 __git_complete_revlist
1447}
1448
1449_git_stash ()
1450{
1451 local subcommands='save list show apply clear drop pop create branch'
1452 local subcommand="$(__git_find_subcommand "$subcommands")"
1453 if [ -z "$subcommand" ]; then
1454 __gitcomp "$subcommands"
1455 else
1456 local cur="${COMP_WORDS[COMP_CWORD]}"
1457 case "$subcommand,$cur" in
1458 save,--*)
1459 __gitcomp "--keep-index"
1460 ;;
1461 apply,--*)
1462 __gitcomp "--index"
1463 ;;
1464 show,--*|drop,--*|pop,--*|branch,--*)
1465 COMPREPLY=()
1466 ;;
1467 show,*|apply,*|drop,*|pop,*|branch,*)
1468 __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
1469 | sed -n -e 's/:.*//p')"
1470 ;;
1471 *)
1472 COMPREPLY=()
1473 ;;
1474 esac
1475 fi
1476}
1477
1478_git_submodule ()
1479{
1480 __git_has_doubledash && return
1481
1482 local subcommands="add status init update summary foreach sync"
1483 if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1484 local cur="${COMP_WORDS[COMP_CWORD]}"
1485 case "$cur" in
1486 --*)
1487 __gitcomp "--quiet --cached"
1488 ;;
1489 *)
1490 __gitcomp "$subcommands"
1491 ;;
1492 esac
1493 return
1494 fi
1495}
1496
1497_git_svn ()
1498{
1499 local subcommands="
1500 init fetch clone rebase dcommit log find-rev
1501 set-tree commit-diff info create-ignore propget
1502 proplist show-ignore show-externals
1503 "
1504 local subcommand="$(__git_find_subcommand "$subcommands")"
1505 if [ -z "$subcommand" ]; then
1506 __gitcomp "$subcommands"
1507 else
1508 local remote_opts="--username= --config-dir= --no-auth-cache"
1509 local fc_opts="
1510 --follow-parent --authors-file= --repack=
1511 --no-metadata --use-svm-props --use-svnsync-props
1512 --log-window-size= --no-checkout --quiet
1513 --repack-flags --user-log-author $remote_opts
1514 "
1515 local init_opts="
1516 --template= --shared= --trunk= --tags=
1517 --branches= --stdlayout --minimize-url
1518 --no-metadata --use-svm-props --use-svnsync-props
1519 --rewrite-root= $remote_opts
1520 "
1521 local cmt_opts="
1522 --edit --rmdir --find-copies-harder --copy-similarity=
1523 "
1524
1525 local cur="${COMP_WORDS[COMP_CWORD]}"
1526 case "$subcommand,$cur" in
1527 fetch,--*)
1528 __gitcomp "--revision= --fetch-all $fc_opts"
1529 ;;
1530 clone,--*)
1531 __gitcomp "--revision= $fc_opts $init_opts"
1532 ;;
1533 init,--*)
1534 __gitcomp "$init_opts"
1535 ;;
1536 dcommit,--*)
1537 __gitcomp "
1538 --merge --strategy= --verbose --dry-run
1539 --fetch-all --no-rebase $cmt_opts $fc_opts
1540 "
1541 ;;
1542 set-tree,--*)
1543 __gitcomp "--stdin $cmt_opts $fc_opts"
1544 ;;
1545 create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
1546 show-externals,--*)
1547 __gitcomp "--revision="
1548 ;;
1549 log,--*)
1550 __gitcomp "
1551 --limit= --revision= --verbose --incremental
1552 --oneline --show-commit --non-recursive
1553 --authors-file=
1554 "
1555 ;;
1556 rebase,--*)
1557 __gitcomp "
1558 --merge --verbose --strategy= --local
1559 --fetch-all $fc_opts
1560 "
1561 ;;
1562 commit-diff,--*)
1563 __gitcomp "--message= --file= --revision= $cmt_opts"
1564 ;;
1565 info,--*)
1566 __gitcomp "--url"
1567 ;;
1568 *)
1569 COMPREPLY=()
1570 ;;
1571 esac
1572 fi
1573}
1574
1575_git_tag ()
1576{
1577 local i c=1 f=0
1578 while [ $c -lt $COMP_CWORD ]; do
1579 i="${COMP_WORDS[c]}"
1580 case "$i" in
1581 -d|-v)
1582 __gitcomp "$(__git_tags)"
1583 return
1584 ;;
1585 -f)
1586 f=1
1587 ;;
1588 esac
1589 c=$((++c))
1590 done
1591
1592 case "${COMP_WORDS[COMP_CWORD-1]}" in
1593 -m|-F)
1594 COMPREPLY=()
1595 ;;
1596 -*|tag|git-tag)
1597 if [ $f = 1 ]; then
1598 __gitcomp "$(__git_tags)"
1599 else
1600 COMPREPLY=()
1601 fi
1602 ;;
1603 *)
1604 __gitcomp "$(__git_refs)"
1605 ;;
1606 esac
1607}
1608
1609_git ()
1610{
1611 local i c=1 command __git_dir
1612
1613 while [ $c -lt $COMP_CWORD ]; do
1614 i="${COMP_WORDS[c]}"
1615 case "$i" in
1616 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
1617 --bare) __git_dir="." ;;
1618 --version|-p|--paginate) ;;
1619 --help) command="help"; break ;;
1620 *) command="$i"; break ;;
1621 esac
1622 c=$((++c))
1623 done
1624
1625 if [ -z "$command" ]; then
1626 case "${COMP_WORDS[COMP_CWORD]}" in
1627 --*=*) COMPREPLY=() ;;
1628 --*) __gitcomp "
1629 --paginate
1630 --no-pager
1631 --git-dir=
1632 --bare
1633 --version
1634 --exec-path
1635 --work-tree=
1636 --help
1637 "
1638 ;;
1639 *) __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
1640 esac
1641 return
1642 fi
1643
1644 local expansion=$(__git_aliased_command "$command")
1645 [ "$expansion" ] && command="$expansion"
1646
1647 case "$command" in
1648 am) _git_am ;;
1649 add) _git_add ;;
1650 apply) _git_apply ;;
1651 archive) _git_archive ;;
1652 bisect) _git_bisect ;;
1653 bundle) _git_bundle ;;
1654 branch) _git_branch ;;
1655 checkout) _git_checkout ;;
1656 cherry) _git_cherry ;;
1657 cherry-pick) _git_cherry_pick ;;
1658 clean) _git_clean ;;
1659 clone) _git_clone ;;
1660 commit) _git_commit ;;
1661 config) _git_config ;;
1662 describe) _git_describe ;;
1663 diff) _git_diff ;;
1664 fetch) _git_fetch ;;
1665 format-patch) _git_format_patch ;;
1666 gc) _git_gc ;;
1667 grep) _git_grep ;;
1668 help) _git_help ;;
1669 init) _git_init ;;
1670 log) _git_log ;;
1671 ls-files) _git_ls_files ;;
1672 ls-remote) _git_ls_remote ;;
1673 ls-tree) _git_ls_tree ;;
1674 merge) _git_merge;;
1675 mergetool) _git_mergetool;;
1676 merge-base) _git_merge_base ;;
1677 mv) _git_mv ;;
1678 name-rev) _git_name_rev ;;
1679 pull) _git_pull ;;
1680 push) _git_push ;;
1681 rebase) _git_rebase ;;
1682 remote) _git_remote ;;
1683 reset) _git_reset ;;
1684 revert) _git_revert ;;
1685 rm) _git_rm ;;
1686 send-email) _git_send_email ;;
1687 shortlog) _git_shortlog ;;
1688 show) _git_show ;;
1689 show-branch) _git_show_branch ;;
1690 stash) _git_stash ;;
1691 submodule) _git_submodule ;;
1692 svn) _git_svn ;;
1693 tag) _git_tag ;;
1694 whatchanged) _git_log ;;
1695 *) COMPREPLY=() ;;
1696 esac
1697}
1698
1699_gitk ()
1700{
1701 __git_has_doubledash && return
1702
1703 local cur="${COMP_WORDS[COMP_CWORD]}"
1704 local g="$(git rev-parse --git-dir 2>/dev/null)"
1705 local merge=""
1706 if [ -f $g/MERGE_HEAD ]; then
1707 merge="--merge"
1708 fi
1709 case "$cur" in
1710 --*)
1711 __gitcomp "--not --all $merge"
1712 return
1713 ;;
1714 esac
1715 __git_complete_revlist
1716}
1717
1718complete -o default -o nospace -F _git git
1719complete -o default -o nospace -F _gitk gitk
1720
1721# The following are necessary only for Cygwin, and only are needed
1722# when the user has tab-completed the executable name and consequently
1723# included the '.exe' suffix.
1724#
1725if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1726complete -o default -o nospace -F _git git.exe
1727fi