Support --strategy=x completion in addition to --strategy x.
[git/jnareb-git.git] / contrib / completion / git-completion.bash
blob16b8dda17dbe1e3c09f3b1377e4a98b9c19900f7
2 # bash completion support for core Git.
4 # Copyright (C) 2006 Shawn Pearce
5 # Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
7 # The contained completion routines provide support for completing:
9 # *) local and remote branch names
10 # *) local and remote tag names
11 # *) .git/remotes file names
12 # *) git 'subcommands'
13 # *) tree paths within 'ref:path/to/file' expressions
15 # To use these routines:
17 # 1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
18 # 2) Added the following line to your .bashrc:
19 # source ~/.git-completion.sh
21 # 3) Consider changing your PS1 to also show the current branch:
22 # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
24 # The argument to __git_ps1 will be displayed only if you
25 # are currently in a git repository. The %s token will be
26 # the name of the current branch.
29 __gitdir ()
31 echo "${__git_dir:-$(git rev-parse --git-dir 2>/dev/null)}"
34 __git_ps1 ()
36 local b="$(git symbolic-ref HEAD 2>/dev/null)"
37 if [ -n "$b" ]; then
38 if [ -n "$1" ]; then
39 printf "$1" "${b##refs/heads/}"
40 else
41 printf " (%s)" "${b##refs/heads/}"
46 __git_heads ()
48 local cmd i is_hash=y dir="${1:-$(__gitdir)}"
49 if [ -d "$dir" ]; then
50 for i in $(git --git-dir="$dir" \
51 for-each-ref --format='%(refname)' \
52 refs/heads ); do
53 echo "${i#refs/heads/}"
54 done
55 return
57 for i in $(git-ls-remote "$dir" 2>/dev/null); do
58 case "$is_hash,$i" in
59 y,*) is_hash=n ;;
60 n,*^{}) is_hash=y ;;
61 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
62 n,*) is_hash=y; echo "$i" ;;
63 esac
64 done
67 __git_refs ()
69 local cmd i is_hash=y dir="${1:-$(__gitdir)}"
70 if [ -d "$dir" ]; then
71 if [ -e "$dir/HEAD" ]; then echo HEAD; fi
72 for i in $(git --git-dir="$dir" \
73 for-each-ref --format='%(refname)' \
74 refs/tags refs/heads refs/remotes); do
75 case "$i" in
76 refs/tags/*) echo "${i#refs/tags/}" ;;
77 refs/heads/*) echo "${i#refs/heads/}" ;;
78 refs/remotes/*) echo "${i#refs/remotes/}" ;;
79 *) echo "$i" ;;
80 esac
81 done
82 return
84 for i in $(git-ls-remote "$dir" 2>/dev/null); do
85 case "$is_hash,$i" in
86 y,*) is_hash=n ;;
87 n,*^{}) is_hash=y ;;
88 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
89 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
90 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
91 n,*) is_hash=y; echo "$i" ;;
92 esac
93 done
96 __git_refs2 ()
98 local cmd i is_hash=y dir="${1:-$(__gitdir)}"
99 if [ -d "$dir" ]; then
100 cmd=git-peek-remote
101 else
102 cmd=git-ls-remote
104 for i in $($cmd "$dir" 2>/dev/null); do
105 case "$is_hash,$i" in
106 y,*) is_hash=n ;;
107 n,*^{}) is_hash=y ;;
108 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}:${i#refs/tags/}" ;;
109 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}:${i#refs/heads/}" ;;
110 n,*) is_hash=y; echo "$i:$i" ;;
111 esac
112 done
115 __git_refs_remotes ()
117 local cmd i is_hash=y
118 for i in $(git-ls-remote "$1" 2>/dev/null); do
119 case "$is_hash,$i" in
120 n,refs/heads/*)
121 is_hash=y
122 echo "$i:refs/remotes/$1/${i#refs/heads/}"
124 y,*) is_hash=n ;;
125 n,*^{}) is_hash=y ;;
126 n,refs/tags/*) is_hash=y;;
127 n,*) is_hash=y; ;;
128 esac
129 done
132 __git_remotes ()
134 local i ngoff IFS=$'\n' d="$(__gitdir)"
135 shopt -q nullglob || ngoff=1
136 shopt -s nullglob
137 for i in "$d/remotes"/*; do
138 echo ${i#$d/remotes/}
139 done
140 [ "$ngoff" ] && shopt -u nullglob
141 for i in $(git --git-dir="$d" repo-config --list); do
142 case "$i" in
143 remote.*.url=*)
144 i="${i#remote.}"
145 echo "${i/.url=*/}"
147 esac
148 done
151 __git_merge_strategies ()
153 sed -n "/^all_strategies='/{
154 s/^all_strategies='//
155 s/'//
158 }" "$(git --exec-path)/git-merge"
161 __git_complete_file ()
163 local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
164 case "$cur" in
165 ?*:*)
166 ref="${cur%%:*}"
167 cur="${cur#*:}"
168 case "$cur" in
169 ?*/*)
170 pfx="${cur%/*}"
171 cur="${cur##*/}"
172 ls="$ref:$pfx"
173 pfx="$pfx/"
176 ls="$ref"
178 esac
179 COMPREPLY=($(compgen -P "$pfx" \
180 -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
181 | sed '/^100... blob /s,^.* ,,
182 /^040000 tree /{
183 s,^.* ,,
184 s,$,/,
186 s/^.* //')" \
187 -- "$cur"))
190 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
192 esac
195 __git_complete_revlist ()
197 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
198 case "$cur" in
199 *...*)
200 pfx="${cur%...*}..."
201 cur="${cur#*...}"
202 COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur"))
204 *..*)
205 pfx="${cur%..*}.."
206 cur="${cur#*..}"
207 COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur"))
210 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
212 esac
215 __git_commands ()
217 local i IFS=" "$'\n'
218 for i in $(git help -a|egrep '^ ')
220 case $i in
221 check-ref-format) : plumbing;;
222 commit-tree) : plumbing;;
223 convert-objects) : plumbing;;
224 cvsserver) : daemon;;
225 daemon) : daemon;;
226 fetch-pack) : plumbing;;
227 hash-object) : plumbing;;
228 http-*) : transport;;
229 index-pack) : plumbing;;
230 local-fetch) : plumbing;;
231 mailinfo) : plumbing;;
232 mailsplit) : plumbing;;
233 merge-*) : plumbing;;
234 mktree) : plumbing;;
235 mktag) : plumbing;;
236 pack-objects) : plumbing;;
237 pack-redundant) : plumbing;;
238 pack-refs) : plumbing;;
239 parse-remote) : plumbing;;
240 patch-id) : plumbing;;
241 peek-remote) : plumbing;;
242 read-tree) : plumbing;;
243 receive-pack) : plumbing;;
244 rerere) : plumbing;;
245 rev-list) : plumbing;;
246 rev-parse) : plumbing;;
247 runstatus) : plumbing;;
248 sh-setup) : internal;;
249 shell) : daemon;;
250 send-pack) : plumbing;;
251 show-index) : plumbing;;
252 ssh-*) : transport;;
253 stripspace) : plumbing;;
254 symbolic-ref) : plumbing;;
255 unpack-file) : plumbing;;
256 unpack-objects) : plumbing;;
257 update-ref) : plumbing;;
258 update-server-info) : daemon;;
259 upload-archive) : plumbing;;
260 upload-pack) : plumbing;;
261 write-tree) : plumbing;;
262 *) echo $i;;
263 esac
264 done
267 __git_aliases ()
269 local i IFS=$'\n'
270 for i in $(git --git-dir="$(__gitdir)" repo-config --list); do
271 case "$i" in
272 alias.*)
273 i="${i#alias.}"
274 echo "${i/=*/}"
276 esac
277 done
280 __git_aliased_command ()
282 local word cmdline=$(git --git-dir="$(__gitdir)" \
283 repo-config --get "alias.$1")
284 for word in $cmdline; do
285 if [ "${word##-*}" ]; then
286 echo $word
287 return
289 done
292 _git_branch ()
294 local cur="${COMP_WORDS[COMP_CWORD]}"
295 COMPREPLY=($(compgen -W "-l -f -d -D $(__git_refs)" -- "$cur"))
298 _git_cat_file ()
300 local cur="${COMP_WORDS[COMP_CWORD]}"
301 case "${COMP_WORDS[0]},$COMP_CWORD" in
302 git-cat-file*,1)
303 COMPREPLY=($(compgen -W "-p -t blob tree commit tag" -- "$cur"))
305 git,2)
306 COMPREPLY=($(compgen -W "-p -t blob tree commit tag" -- "$cur"))
309 __git_complete_file
311 esac
314 _git_checkout ()
316 local cur="${COMP_WORDS[COMP_CWORD]}"
317 COMPREPLY=($(compgen -W "-l -b $(__git_refs)" -- "$cur"))
320 _git_cherry_pick ()
322 local cur="${COMP_WORDS[COMP_CWORD]}"
323 case "$cur" in
324 --*)
325 COMPREPLY=($(compgen -W "
326 --edit --no-commit
327 " -- "$cur"))
330 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
332 esac
335 _git_diff ()
337 __git_complete_file
340 _git_diff_tree ()
342 local cur="${COMP_WORDS[COMP_CWORD]}"
343 COMPREPLY=($(compgen -W "-r -p -M $(__git_refs)" -- "$cur"))
346 _git_fetch ()
348 local cur="${COMP_WORDS[COMP_CWORD]}"
350 case "${COMP_WORDS[0]},$COMP_CWORD" in
351 git-fetch*,1)
352 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
354 git,2)
355 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
358 case "$cur" in
359 *:*)
360 cur="${cur#*:}"
361 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
364 local remote
365 case "${COMP_WORDS[0]}" in
366 git-fetch) remote="${COMP_WORDS[1]}" ;;
367 git) remote="${COMP_WORDS[2]}" ;;
368 esac
369 COMPREPLY=($(compgen -W "$(__git_refs2 "$remote")" -- "$cur"))
371 esac
373 esac
376 _git_format_patch ()
378 local cur="${COMP_WORDS[COMP_CWORD]}"
379 case "$cur" in
380 --*)
381 COMPREPLY=($(compgen -W "
382 --stdout --attach --thread
383 --output-directory
384 --numbered --start-number
385 --keep-subject
386 --signoff
387 --in-reply-to=
388 --full-index --binary
389 " -- "$cur"))
390 return
392 esac
393 __git_complete_revlist
396 _git_ls_remote ()
398 local cur="${COMP_WORDS[COMP_CWORD]}"
399 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
402 _git_ls_tree ()
404 __git_complete_file
407 _git_log ()
409 local cur="${COMP_WORDS[COMP_CWORD]}"
410 case "$cur" in
411 --pretty=*)
412 COMPREPLY=($(compgen -W "
413 oneline short medium full fuller email raw
414 " -- "${cur##--pretty=}"))
415 return
417 --*)
418 COMPREPLY=($(compgen -W "
419 --max-count= --max-age= --since= --after=
420 --min-age= --before= --until=
421 --root --not --topo-order --date-order
422 --no-merges
423 --abbrev-commit --abbrev=
424 --relative-date
425 --author= --committer= --grep=
426 --all-match
427 --pretty= --name-status --name-only
428 " -- "$cur"))
429 return
431 esac
432 __git_complete_revlist
435 _git_merge ()
437 local cur="${COMP_WORDS[COMP_CWORD]}"
438 case "${COMP_WORDS[COMP_CWORD-1]}" in
439 -s|--strategy)
440 COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur"))
441 return
442 esac
443 case "$cur" in
444 --strategy=*)
445 COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \
446 -- "${cur##--strategy=}"))
447 return
449 --*)
450 COMPREPLY=($(compgen -W "
451 --no-commit --no-summary --squash --strategy
452 " -- "$cur"))
453 return
454 esac
455 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
458 _git_merge_base ()
460 local cur="${COMP_WORDS[COMP_CWORD]}"
461 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
464 _git_name_rev ()
466 local cur="${COMP_WORDS[COMP_CWORD]}"
467 COMPREPLY=($(compgen -W "--tags --all --stdin" -- "$cur"))
470 _git_pull ()
472 local cur="${COMP_WORDS[COMP_CWORD]}"
474 case "${COMP_WORDS[0]},$COMP_CWORD" in
475 git-pull*,1)
476 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
478 git,2)
479 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
482 local remote
483 case "${COMP_WORDS[0]}" in
484 git-pull) remote="${COMP_WORDS[1]}" ;;
485 git) remote="${COMP_WORDS[2]}" ;;
486 esac
487 COMPREPLY=($(compgen -W "$(__git_refs "$remote")" -- "$cur"))
489 esac
492 _git_push ()
494 local cur="${COMP_WORDS[COMP_CWORD]}"
496 case "${COMP_WORDS[0]},$COMP_CWORD" in
497 git-push*,1)
498 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
500 git,2)
501 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
504 case "$cur" in
505 *:*)
506 local remote
507 case "${COMP_WORDS[0]}" in
508 git-push) remote="${COMP_WORDS[1]}" ;;
509 git) remote="${COMP_WORDS[2]}" ;;
510 esac
511 cur="${cur#*:}"
512 COMPREPLY=($(compgen -W "$(__git_refs "$remote")" -- "$cur"))
515 COMPREPLY=($(compgen -W "$(__git_refs2)" -- "$cur"))
517 esac
519 esac
522 _git_rebase ()
524 local cur="${COMP_WORDS[COMP_CWORD]}"
525 if [ -d .dotest ]; then
526 COMPREPLY=($(compgen -W "
527 --continue --skip --abort
528 " -- "$cur"))
529 return
531 case "${COMP_WORDS[COMP_CWORD-1]}" in
532 -s|--strategy)
533 COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur"))
534 return
535 esac
536 case "$cur" in
537 --strategy=*)
538 COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \
539 -- "${cur##--strategy=}"))
540 return
542 --*)
543 COMPREPLY=($(compgen -W "
544 --onto --merge --strategy
545 " -- "$cur"))
546 return
547 esac
548 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
551 _git_repo_config ()
553 local cur="${COMP_WORDS[COMP_CWORD]}"
554 local prv="${COMP_WORDS[COMP_CWORD-1]}"
555 case "$prv" in
556 branch.*.remote)
557 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
558 return
560 branch.*.merge)
561 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
562 return
564 remote.*.fetch)
565 local remote="${prv#remote.}"
566 remote="${remote%.fetch}"
567 COMPREPLY=($(compgen -W "$(__git_refs_remotes "$remote")" \
568 -- "$cur"))
569 return
571 remote.*.push)
572 local remote="${prv#remote.}"
573 remote="${remote%.push}"
574 COMPREPLY=($(compgen -W "$(git --git-dir="$(__gitdir)" \
575 for-each-ref --format='%(refname):%(refname)' \
576 refs/heads)" -- "$cur"))
577 return
579 *.*)
580 COMPREPLY=()
581 return
583 esac
584 case "$cur" in
585 --*)
586 COMPREPLY=($(compgen -W "
587 --global --list --replace-all
588 --get --get-all --get-regexp
589 --unset --unset-all
590 " -- "$cur"))
591 return
593 branch.*.*)
594 local pfx="${cur%.*}."
595 cur="${cur##*.}"
596 COMPREPLY=($(compgen -P "$pfx" -W "remote merge" -- "$cur"))
597 return
599 branch.*)
600 local pfx="${cur%.*}."
601 cur="${cur#*.}"
602 COMPREPLY=($(compgen -P "$pfx" -S . \
603 -W "$(__git_heads)" -- "$cur"))
604 return
606 remote.*.*)
607 local pfx="${cur%.*}."
608 cur="${cur##*.}"
609 COMPREPLY=($(compgen -P "$pfx" -W "url fetch push" -- "$cur"))
610 return
612 remote.*)
613 local pfx="${cur%.*}."
614 cur="${cur#*.}"
615 COMPREPLY=($(compgen -P "$pfx" -S . \
616 -W "$(__git_remotes)" -- "$cur"))
617 return
619 esac
620 COMPREPLY=($(compgen -W "
621 apply.whitespace
622 core.fileMode
623 core.gitProxy
624 core.ignoreStat
625 core.preferSymlinkRefs
626 core.logAllRefUpdates
627 core.repositoryFormatVersion
628 core.sharedRepository
629 core.warnAmbiguousRefs
630 core.compression
631 core.legacyHeaders
632 i18n.commitEncoding
633 diff.color
634 diff.renameLimit
635 diff.renames
636 pager.color
637 status.color
638 log.showroot
639 show.difftree
640 showbranch.default
641 whatchanged.difftree
642 http.sslVerify
643 http.sslCert
644 http.sslKey
645 http.sslCAInfo
646 http.sslCAPath
647 http.maxRequests
648 http.lowSpeedLimit http.lowSpeedTime
649 http.noEPSV
650 pack.window
651 repack.useDeltaBaseOffset
652 pull.octopus pull.twohead
653 merge.summary
654 receive.unpackLimit
655 receive.denyNonFastForwards
656 user.name user.email
657 tar.umask
658 gitcvs.enabled
659 gitcvs.logfile
660 branch. remote.
661 " -- "$cur"))
664 _git_reset ()
666 local cur="${COMP_WORDS[COMP_CWORD]}"
667 local opt="--mixed --hard --soft"
668 COMPREPLY=($(compgen -W "$opt $(__git_refs)" -- "$cur"))
671 _git ()
673 local i c=1 command __git_dir
675 while [ $c -lt $COMP_CWORD ]; do
676 i="${COMP_WORDS[c]}"
677 case "$i" in
678 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
679 --bare) __git_dir="." ;;
680 --version|--help|-p|--paginate) ;;
681 *) command="$i"; break ;;
682 esac
683 c=$((++c))
684 done
686 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
687 COMPREPLY=($(compgen -W "
688 --git-dir= --version --exec-path
689 $(__git_commands)
690 $(__git_aliases)
691 " -- "${COMP_WORDS[COMP_CWORD]}"))
692 return;
695 local expansion=$(__git_aliased_command "$command")
696 [ "$expansion" ] && command="$expansion"
698 case "$command" in
699 branch) _git_branch ;;
700 cat-file) _git_cat_file ;;
701 checkout) _git_checkout ;;
702 cherry-pick) _git_cherry_pick ;;
703 diff) _git_diff ;;
704 diff-tree) _git_diff_tree ;;
705 fetch) _git_fetch ;;
706 format-patch) _git_format_patch ;;
707 log) _git_log ;;
708 ls-remote) _git_ls_remote ;;
709 ls-tree) _git_ls_tree ;;
710 merge) _git_merge;;
711 merge-base) _git_merge_base ;;
712 name-rev) _git_name_rev ;;
713 pull) _git_pull ;;
714 push) _git_push ;;
715 rebase) _git_rebase ;;
716 repo-config) _git_repo_config ;;
717 reset) _git_reset ;;
718 show) _git_log ;;
719 show-branch) _git_log ;;
720 whatchanged) _git_log ;;
721 *) COMPREPLY=() ;;
722 esac
725 _gitk ()
727 local cur="${COMP_WORDS[COMP_CWORD]}"
728 COMPREPLY=($(compgen -W "--all $(__git_refs)" -- "$cur"))
731 complete -o default -o nospace -F _git git
732 complete -o default -F _gitk gitk
733 complete -o default -F _git_branch git-branch
734 complete -o default -o nospace -F _git_cat_file git-cat-file
735 complete -o default -F _git_checkout git-checkout
736 complete -o default -F _git_cherry_pick git-cherry-pick
737 complete -o default -o nospace -F _git_diff git-diff
738 complete -o default -F _git_diff_tree git-diff-tree
739 complete -o default -o nospace -F _git_fetch git-fetch
740 complete -o default -o nospace -F _git_format_patch git-format-patch
741 complete -o default -o nospace -F _git_log git-log
742 complete -o default -F _git_ls_remote git-ls-remote
743 complete -o default -o nospace -F _git_ls_tree git-ls-tree
744 complete -o default -F _git_merge git-merge
745 complete -o default -F _git_merge_base git-merge-base
746 complete -o default -F _git_name_rev git-name-rev
747 complete -o default -o nospace -F _git_pull git-pull
748 complete -o default -o nospace -F _git_push git-push
749 complete -o default -F _git_rebase git-rebase
750 complete -o default -F _git_repo_config git-repo-config
751 complete -o default -F _git_reset git-reset
752 complete -o default -F _git_log git-show
753 complete -o default -o nospace -F _git_log git-show-branch
754 complete -o default -o nospace -F _git_log git-whatchanged
756 # The following are necessary only for Cygwin, and only are needed
757 # when the user has tab-completed the executable name and consequently
758 # included the '.exe' suffix.
760 if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
761 complete -o default -o nospace -F _git git.exe
762 complete -o default -F _git_branch git-branch.exe
763 complete -o default -o nospace -F _git_cat_file git-cat-file.exe
764 complete -o default -o nospace -F _git_diff git-diff.exe
765 complete -o default -o nospace -F _git_diff_tree git-diff-tree.exe
766 complete -o default -o nospace -F _git_format_patch git-format-patch.exe
767 complete -o default -o nospace -F _git_log git-log.exe
768 complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
769 complete -o default -F _git_merge_base git-merge-base.exe
770 complete -o default -F _git_name_rev git-name-rev.exe
771 complete -o default -o nospace -F _git_push git-push.exe
772 complete -o default -F _git_repo_config git-repo-config
773 complete -o default -o nospace -F _git_log git-show.exe
774 complete -o default -o nospace -F _git_log git-show-branch.exe
775 complete -o default -o nospace -F _git_log git-whatchanged.exe