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) You may want to make sure the git executable is available
22 # in your PATH before this script is sourced, as some caching
23 # is performed while the script loads. If git isn't found
24 # at source time then all lookups will be done on demand,
25 # which may be slightly slower.
27 # 4) Consider changing your PS1 to also show the current branch:
28 # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
30 # The argument to __git_ps1 will be displayed only if you
31 # are currently in a git repository. The %s token will be
32 # the name of the current branch.
37 echo "${__git_dir:-$(git rev-parse --git-dir 2>/dev/null)}"
42 local b="$(git symbolic-ref HEAD 2>/dev/null)"
45 printf "$1" "${b##refs/heads/}"
47 printf " (%s)" "${b##refs/heads/}"
54 local cmd i is_hash=y dir="${1:-$(__gitdir)}"
55 if [ -d "$dir" ]; then
56 for i in $(git --git-dir="$dir" \
57 for-each-ref --format='%(refname)' \
59 echo "${i#refs/heads/}"
63 for i in $(git-ls-remote "$dir" 2>/dev/null); do
67 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
68 n,*) is_hash=y; echo "$i" ;;
75 local cmd i is_hash=y dir="${1:-$(__gitdir)}"
76 if [ -d "$dir" ]; then
77 if [ -e "$dir/HEAD" ]; then echo HEAD; fi
78 for i in $(git --git-dir="$dir" \
79 for-each-ref --format='%(refname)' \
80 refs/tags refs/heads refs/remotes); do
82 refs/tags/*) echo "${i#refs/tags/}" ;;
83 refs/heads/*) echo "${i#refs/heads/}" ;;
84 refs/remotes/*) echo "${i#refs/remotes/}" ;;
90 for i in $(git-ls-remote "$dir" 2>/dev/null); do
94 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
95 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
96 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
97 n,*) is_hash=y; echo "$i" ;;
104 local cmd i is_hash=y dir="${1:-$(__gitdir)}"
105 if [ -d "$dir" ]; then
110 for i in $($cmd "$dir" 2>/dev/null); do
111 case "$is_hash,$i" in
114 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}:${i#refs/tags/}" ;;
115 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}:${i#refs/heads/}" ;;
116 n,*) is_hash=y; echo "$i:$i" ;;
121 __git_refs_remotes ()
123 local cmd i is_hash=y
124 for i in $(git-ls-remote "$1" 2>/dev/null); do
125 case "$is_hash,$i" in
128 echo "$i:refs/remotes/$1/${i#refs/heads/}"
132 n,refs/tags/*) is_hash=y;;
140 local i ngoff IFS=$'\n' d="$(__gitdir)"
141 shopt -q nullglob || ngoff=1
143 for i in "$d/remotes"/*; do
144 echo ${i#$d/remotes/}
146 [ "$ngoff" ] && shopt -u nullglob
147 for i in $(git --git-dir="$d" repo-config --list); do
157 __git_merge_strategies ()
159 if [ -n "$__git_merge_strategylist" ]; then
160 echo "$__git_merge_strategylist"
163 sed -n "/^all_strategies='/{
164 s/^all_strategies='//
168 }" "$(git --exec-path)/git-merge"
170 __git_merge_strategylist=
171 __git_merge_strategylist="$(__git_merge_strategies 2>/dev/null)"
173 __git_complete_file ()
175 local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
191 COMPREPLY=($(compgen -P "$pfx" \
192 -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
193 | sed '/^100... blob /s,^.* ,,
202 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
207 __git_complete_revlist ()
209 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
214 COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur"))
219 COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur"))
222 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
229 if [ -n "$__git_commandlist" ]; then
230 echo "$__git_commandlist"
234 for i in $(git help -a|egrep '^ ')
237 check-ref-format) : plumbing;;
238 commit-tree) : plumbing;;
239 convert-objects) : plumbing;;
240 cvsserver) : daemon;;
242 fetch-pack) : plumbing;;
243 hash-object) : plumbing;;
244 http-*) : transport;;
245 index-pack) : plumbing;;
246 local-fetch) : plumbing;;
247 mailinfo) : plumbing;;
248 mailsplit) : plumbing;;
249 merge-*) : plumbing;;
252 pack-objects) : plumbing;;
253 pack-redundant) : plumbing;;
254 pack-refs) : plumbing;;
255 parse-remote) : plumbing;;
256 patch-id) : plumbing;;
257 peek-remote) : plumbing;;
258 read-tree) : plumbing;;
259 receive-pack) : plumbing;;
261 rev-list) : plumbing;;
262 rev-parse) : plumbing;;
263 runstatus) : plumbing;;
264 sh-setup) : internal;;
266 send-pack) : plumbing;;
267 show-index) : plumbing;;
269 stripspace) : plumbing;;
270 symbolic-ref) : plumbing;;
271 unpack-file) : plumbing;;
272 unpack-objects) : plumbing;;
273 update-ref) : plumbing;;
274 update-server-info) : daemon;;
275 upload-archive) : plumbing;;
276 upload-pack) : plumbing;;
277 write-tree) : plumbing;;
283 __git_commandlist="$(__git_commands 2>/dev/null)"
288 for i in $(git --git-dir="$(__gitdir)" repo-config --list); do
298 __git_aliased_command ()
300 local word cmdline=$(git --git-dir="$(__gitdir)" \
301 repo-config --get "alias.$1")
302 for word in $cmdline; do
303 if [ "${word##-*}" ]; then
312 local cur="${COMP_WORDS[COMP_CWORD]}"
313 COMPREPLY=($(compgen -W "-l -f -d -D $(__git_refs)" -- "$cur"))
318 local cur="${COMP_WORDS[COMP_CWORD]}"
319 case "${COMP_WORDS[0]},$COMP_CWORD" in
321 COMPREPLY=($(compgen -W "-p -t blob tree commit tag" -- "$cur"))
324 COMPREPLY=($(compgen -W "-p -t blob tree commit tag" -- "$cur"))
334 local cur="${COMP_WORDS[COMP_CWORD]}"
335 COMPREPLY=($(compgen -W "-l -b $(__git_refs)" -- "$cur"))
340 local cur="${COMP_WORDS[COMP_CWORD]}"
343 COMPREPLY=($(compgen -W "
348 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
360 local cur="${COMP_WORDS[COMP_CWORD]}"
361 COMPREPLY=($(compgen -W "-r -p -M $(__git_refs)" -- "$cur"))
366 local cur="${COMP_WORDS[COMP_CWORD]}"
368 case "${COMP_WORDS[0]},$COMP_CWORD" in
370 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
373 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
379 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
383 case "${COMP_WORDS[0]}" in
384 git-fetch) remote="${COMP_WORDS[1]}" ;;
385 git) remote="${COMP_WORDS[2]}" ;;
387 COMPREPLY=($(compgen -W "$(__git_refs2 "$remote")" -- "$cur"))
396 local cur="${COMP_WORDS[COMP_CWORD]}"
399 COMPREPLY=($(compgen -W "
400 --stdout --attach --thread
402 --numbered --start-number
406 --full-index --binary
411 __git_complete_revlist
416 local cur="${COMP_WORDS[COMP_CWORD]}"
417 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
427 local cur="${COMP_WORDS[COMP_CWORD]}"
430 COMPREPLY=($(compgen -W "
431 oneline short medium full fuller email raw
432 " -- "${cur##--pretty=}"))
436 COMPREPLY=($(compgen -W "
437 --max-count= --max-age= --since= --after=
438 --min-age= --before= --until=
439 --root --not --topo-order --date-order
441 --abbrev-commit --abbrev=
443 --author= --committer= --grep=
445 --pretty= --name-status --name-only
450 __git_complete_revlist
455 local cur="${COMP_WORDS[COMP_CWORD]}"
456 case "${COMP_WORDS[COMP_CWORD-1]}" in
458 COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur"))
463 COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \
464 -- "${cur##--strategy=}"))
468 COMPREPLY=($(compgen -W "
469 --no-commit --no-summary --squash --strategy
473 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
478 local cur="${COMP_WORDS[COMP_CWORD]}"
479 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
484 local cur="${COMP_WORDS[COMP_CWORD]}"
485 COMPREPLY=($(compgen -W "--tags --all --stdin" -- "$cur"))
490 local cur="${COMP_WORDS[COMP_CWORD]}"
492 case "${COMP_WORDS[0]},$COMP_CWORD" in
494 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
497 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
501 case "${COMP_WORDS[0]}" in
502 git-pull) remote="${COMP_WORDS[1]}" ;;
503 git) remote="${COMP_WORDS[2]}" ;;
505 COMPREPLY=($(compgen -W "$(__git_refs "$remote")" -- "$cur"))
512 local cur="${COMP_WORDS[COMP_CWORD]}"
514 case "${COMP_WORDS[0]},$COMP_CWORD" in
516 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
519 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
525 case "${COMP_WORDS[0]}" in
526 git-push) remote="${COMP_WORDS[1]}" ;;
527 git) remote="${COMP_WORDS[2]}" ;;
530 COMPREPLY=($(compgen -W "$(__git_refs "$remote")" -- "$cur"))
533 COMPREPLY=($(compgen -W "$(__git_refs2)" -- "$cur"))
542 local cur="${COMP_WORDS[COMP_CWORD]}"
543 if [ -d .dotest ]; then
544 COMPREPLY=($(compgen -W "
545 --continue --skip --abort
549 case "${COMP_WORDS[COMP_CWORD-1]}" in
551 COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur"))
556 COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \
557 -- "${cur##--strategy=}"))
561 COMPREPLY=($(compgen -W "
562 --onto --merge --strategy
566 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
571 local cur="${COMP_WORDS[COMP_CWORD]}"
572 local prv="${COMP_WORDS[COMP_CWORD-1]}"
575 COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
579 COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
583 local remote="${prv#remote.}"
584 remote="${remote%.fetch}"
585 COMPREPLY=($(compgen -W "$(__git_refs_remotes "$remote")" \
590 local remote="${prv#remote.}"
591 remote="${remote%.push}"
592 COMPREPLY=($(compgen -W "$(git --git-dir="$(__gitdir)" \
593 for-each-ref --format='%(refname):%(refname)' \
594 refs/heads)" -- "$cur"))
604 COMPREPLY=($(compgen -W "
605 --global --list --replace-all
606 --get --get-all --get-regexp
612 local pfx="${cur%.*}."
614 COMPREPLY=($(compgen -P "$pfx" -W "remote merge" -- "$cur"))
618 local pfx="${cur%.*}."
620 COMPREPLY=($(compgen -P "$pfx" -S . \
621 -W "$(__git_heads)" -- "$cur"))
625 local pfx="${cur%.*}."
627 COMPREPLY=($(compgen -P "$pfx" -W "url fetch push" -- "$cur"))
631 local pfx="${cur%.*}."
633 COMPREPLY=($(compgen -P "$pfx" -S . \
634 -W "$(__git_remotes)" -- "$cur"))
638 COMPREPLY=($(compgen -W "
643 core.preferSymlinkRefs
644 core.logAllRefUpdates
645 core.repositoryFormatVersion
646 core.sharedRepository
647 core.warnAmbiguousRefs
666 http.lowSpeedLimit http.lowSpeedTime
669 repack.useDeltaBaseOffset
670 pull.octopus pull.twohead
673 receive.denyNonFastForwards
684 local cur="${COMP_WORDS[COMP_CWORD]}"
685 local opt="--mixed --hard --soft"
686 COMPREPLY=($(compgen -W "$opt $(__git_refs)" -- "$cur"))
691 local i c=1 command __git_dir
693 while [ $c -lt $COMP_CWORD ]; do
696 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
697 --bare) __git_dir="." ;;
698 --version|--help|-p|--paginate) ;;
699 *) command="$i"; break ;;
704 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
705 COMPREPLY=($(compgen -W "
706 --git-dir= --version --exec-path
709 " -- "${COMP_WORDS[COMP_CWORD]}"))
713 local expansion=$(__git_aliased_command "$command")
714 [ "$expansion" ] && command="$expansion"
717 branch) _git_branch ;;
718 cat-file) _git_cat_file ;;
719 checkout) _git_checkout ;;
720 cherry-pick) _git_cherry_pick ;;
722 diff-tree) _git_diff_tree ;;
724 format-patch) _git_format_patch ;;
726 ls-remote) _git_ls_remote ;;
727 ls-tree) _git_ls_tree ;;
729 merge-base) _git_merge_base ;;
730 name-rev) _git_name_rev ;;
733 rebase) _git_rebase ;;
734 repo-config) _git_repo_config ;;
737 show-branch) _git_log ;;
738 whatchanged) _git_log ;;
745 local cur="${COMP_WORDS[COMP_CWORD]}"
746 COMPREPLY=($(compgen -W "--all $(__git_refs)" -- "$cur"))
749 complete -o default -o nospace -F _git git
750 complete -o default -F _gitk gitk
751 complete -o default -F _git_branch git-branch
752 complete -o default -o nospace -F _git_cat_file git-cat-file
753 complete -o default -F _git_checkout git-checkout
754 complete -o default -F _git_cherry_pick git-cherry-pick
755 complete -o default -o nospace -F _git_diff git-diff
756 complete -o default -F _git_diff_tree git-diff-tree
757 complete -o default -o nospace -F _git_fetch git-fetch
758 complete -o default -o nospace -F _git_format_patch git-format-patch
759 complete -o default -o nospace -F _git_log git-log
760 complete -o default -F _git_ls_remote git-ls-remote
761 complete -o default -o nospace -F _git_ls_tree git-ls-tree
762 complete -o default -F _git_merge git-merge
763 complete -o default -F _git_merge_base git-merge-base
764 complete -o default -F _git_name_rev git-name-rev
765 complete -o default -o nospace -F _git_pull git-pull
766 complete -o default -o nospace -F _git_push git-push
767 complete -o default -F _git_rebase git-rebase
768 complete -o default -F _git_repo_config git-repo-config
769 complete -o default -F _git_reset git-reset
770 complete -o default -F _git_log git-show
771 complete -o default -o nospace -F _git_log git-show-branch
772 complete -o default -o nospace -F _git_log git-whatchanged
774 # The following are necessary only for Cygwin, and only are needed
775 # when the user has tab-completed the executable name and consequently
776 # included the '.exe' suffix.
778 if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
779 complete -o default -o nospace -F _git git.exe
780 complete -o default -F _git_branch git-branch.exe
781 complete -o default -o nospace -F _git_cat_file git-cat-file.exe
782 complete -o default -o nospace -F _git_diff git-diff.exe
783 complete -o default -o nospace -F _git_diff_tree git-diff-tree.exe
784 complete -o default -o nospace -F _git_format_patch git-format-patch.exe
785 complete -o default -o nospace -F _git_log git-log.exe
786 complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
787 complete -o default -F _git_merge_base git-merge-base.exe
788 complete -o default -F _git_name_rev git-name-rev.exe
789 complete -o default -o nospace -F _git_push git-push.exe
790 complete -o default -F _git_repo_config git-repo-config
791 complete -o default -o nospace -F _git_log git-show.exe
792 complete -o default -o nospace -F _git_log git-show-branch.exe
793 complete -o default -o nospace -F _git_log git-whatchanged.exe