2 # bash completion support for core Git.
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.
8 # The contained completion routines provide support for completing:
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
17 # To use these routines:
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
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.
29 # 4) Consider changing your PS1 to also show the current branch:
30 # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
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.
38 # *) Read Documentation/SubmittingPatches
39 # *) Send all patches to the current maintainer:
41 # "Shawn O. Pearce" <spearce@spearce.org>
43 # *) Always CC the Git mailing list:
51 if [ -n "$__git_dir" ]; then
53 elif [ -d .git ]; then
56 git rev-parse --git-dir 2>/dev/null
58 elif [ -d "$1/.git" ]; then
67 local b="$(git symbolic-ref HEAD 2>/dev/null)"
70 printf "$1" "${b##refs/heads/}"
72 printf " (%s)" "${b##refs/heads/}"
79 local all c s=$'\n' IFS=' '$'\t'$'\n'
80 local cur="${COMP_WORDS[COMP_CWORD]}"
86 --*=*) all="$all$c$4$s" ;;
87 *.) all="$all$c$4$s" ;;
88 *) all="$all$c$4 $s" ;;
92 COMPREPLY=($(compgen -P "$2" -W "$all" -- "$cur"))
98 local cmd i is_hash=y dir="$(__gitdir "$1")"
99 if [ -d "$dir" ]; then
100 for i in $(git --git-dir="$dir" \
101 for-each-ref --format='%(refname)' \
103 echo "${i#refs/heads/}"
107 for i in $(git-ls-remote "$1" 2>/dev/null); do
108 case "$is_hash,$i" in
111 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
112 n,*) is_hash=y; echo "$i" ;;
119 local cmd i is_hash=y dir="$(__gitdir "$1")"
120 if [ -d "$dir" ]; then
121 if [ -e "$dir/HEAD" ]; then echo HEAD; fi
122 for i in $(git --git-dir="$dir" \
123 for-each-ref --format='%(refname)' \
124 refs/tags refs/heads refs/remotes); do
126 refs/tags/*) echo "${i#refs/tags/}" ;;
127 refs/heads/*) echo "${i#refs/heads/}" ;;
128 refs/remotes/*) echo "${i#refs/remotes/}" ;;
134 for i in $(git-ls-remote "$dir" 2>/dev/null); do
135 case "$is_hash,$i" in
138 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
139 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
140 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
141 n,*) is_hash=y; echo "$i" ;;
149 for i in $(__git_refs "$1"); do
154 __git_refs_remotes ()
156 local cmd i is_hash=y
157 for i in $(git-ls-remote "$1" 2>/dev/null); do
158 case "$is_hash,$i" in
161 echo "$i:refs/remotes/$1/${i#refs/heads/}"
165 n,refs/tags/*) is_hash=y;;
173 local i ngoff IFS=$'\n' d="$(__gitdir)"
174 shopt -q nullglob || ngoff=1
176 for i in "$d/remotes"/*; do
177 echo ${i#$d/remotes/}
179 [ "$ngoff" ] && shopt -u nullglob
180 for i in $(git --git-dir="$d" config --list); do
190 __git_merge_strategies ()
192 if [ -n "$__git_merge_strategylist" ]; then
193 echo "$__git_merge_strategylist"
196 sed -n "/^all_strategies='/{
197 s/^all_strategies='//
201 }" "$(git --exec-path)/git-merge"
203 __git_merge_strategylist=
204 __git_merge_strategylist="$(__git_merge_strategies 2>/dev/null)"
206 __git_complete_file ()
208 local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
224 COMPREPLY=($(compgen -P "$pfx" \
225 -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
226 | sed '/^100... blob /s,^.* ,,
235 __gitcomp "$(__git_refs)"
240 __git_complete_revlist ()
242 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
247 __gitcomp "$(__git_refs)" "$pfx" "$cur"
252 __gitcomp "$(__git_refs)" "$pfx" "$cur"
258 __gitcomp "$(__git_refs)"
265 if [ -n "$__git_commandlist" ]; then
266 echo "$__git_commandlist"
270 for i in $(git help -a|egrep '^ ')
273 add--interactive) : plumbing;;
274 applymbox) : ask gittus;;
275 applypatch) : ask gittus;;
276 archimport) : import;;
277 cat-file) : plumbing;;
278 check-attr) : plumbing;;
279 check-ref-format) : plumbing;;
280 commit-tree) : plumbing;;
281 convert-objects) : plumbing;;
282 cvsexportcommit) : export;;
283 cvsimport) : import;;
284 cvsserver) : daemon;;
286 diff-files) : plumbing;;
287 diff-index) : plumbing;;
288 diff-tree) : plumbing;;
289 fast-import) : import;;
290 fsck-objects) : plumbing;;
291 fetch--tool) : plumbing;;
292 fetch-pack) : plumbing;;
293 fmt-merge-msg) : plumbing;;
294 for-each-ref) : plumbing;;
295 hash-object) : plumbing;;
296 http-*) : transport;;
297 index-pack) : plumbing;;
298 init-db) : deprecated;;
299 local-fetch) : plumbing;;
300 mailinfo) : plumbing;;
301 mailsplit) : plumbing;;
302 merge-*) : plumbing;;
305 pack-objects) : plumbing;;
306 pack-redundant) : plumbing;;
307 pack-refs) : plumbing;;
308 parse-remote) : plumbing;;
309 patch-id) : plumbing;;
310 peek-remote) : plumbing;;
312 prune-packed) : plumbing;;
313 quiltimport) : import;;
314 read-tree) : plumbing;;
315 receive-pack) : plumbing;;
317 repo-config) : plumbing;;
319 rev-list) : plumbing;;
320 rev-parse) : plumbing;;
321 runstatus) : plumbing;;
322 sh-setup) : internal;;
324 send-pack) : plumbing;;
325 show-index) : plumbing;;
327 stripspace) : plumbing;;
328 svn) : import export;;
329 svnimport) : import;;
330 symbolic-ref) : plumbing;;
331 tar-tree) : deprecated;;
332 unpack-file) : plumbing;;
333 unpack-objects) : plumbing;;
334 update-index) : plumbing;;
335 update-ref) : plumbing;;
336 update-server-info) : daemon;;
337 upload-archive) : plumbing;;
338 upload-pack) : plumbing;;
339 write-tree) : plumbing;;
340 verify-tag) : plumbing;;
346 __git_commandlist="$(__git_commands 2>/dev/null)"
351 for i in $(git --git-dir="$(__gitdir)" config --list); do
361 __git_aliased_command ()
363 local word cmdline=$(git --git-dir="$(__gitdir)" \
364 config --get "alias.$1")
365 for word in $cmdline; do
366 if [ "${word##-*}" ]; then
373 __git_whitespacelist="nowarn warn error error-all strip"
377 local cur="${COMP_WORDS[COMP_CWORD]}"
378 if [ -d .dotest ]; then
379 __gitcomp "--skip --resolved"
384 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
389 --signoff --utf8 --binary --3way --interactive
399 local cur="${COMP_WORDS[COMP_CWORD]}"
402 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
407 --stat --numstat --summary --check --index
408 --cached --index-info --reverse --reject --unidiff-zero
409 --apply --no-add --exclude=
410 --whitespace= --inaccurate-eof --verbose
419 local cur="${COMP_WORDS[COMP_CWORD]}"
422 __gitcomp "--interactive"
431 while [ $c -lt $COMP_CWORD ]; do
434 start|bad|good|reset|visualize|replay|log)
442 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
443 __gitcomp "start bad good reset visualize replay log"
449 __gitcomp "$(__git_refs)"
459 __gitcomp "$(__git_refs)"
464 __gitcomp "$(__git_refs)"
469 __gitcomp "$(__git_refs)"
474 local cur="${COMP_WORDS[COMP_CWORD]}"
477 __gitcomp "--edit --no-commit"
480 __gitcomp "$(__git_refs)"
487 local cur="${COMP_WORDS[COMP_CWORD]}"
491 --all --author= --signoff --verify --no-verify
492 --edit --amend --include --only
506 __gitcomp "$(__git_refs)"
511 local cur="${COMP_WORDS[COMP_CWORD]}"
513 case "${COMP_WORDS[0]},$COMP_CWORD" in
515 __gitcomp "$(__git_remotes)"
518 __gitcomp "$(__git_remotes)"
523 __gitcomp "$(__git_refs)" "" "${cur#*:}"
527 case "${COMP_WORDS[0]}" in
528 git-fetch) remote="${COMP_WORDS[1]}" ;;
529 git) remote="${COMP_WORDS[2]}" ;;
531 __gitcomp "$(__git_refs2 "$remote")"
540 local cur="${COMP_WORDS[COMP_CWORD]}"
544 --stdout --attach --thread
546 --numbered --start-number
550 --full-index --binary
556 __git_complete_revlist
561 local cur="${COMP_WORDS[COMP_CWORD]}"
573 __gitcomp "$(__git_remotes)"
583 local cur="${COMP_WORDS[COMP_CWORD]}"
587 oneline short medium full fuller email raw
588 " "" "${cur##--pretty=}"
593 --max-count= --max-age= --since= --after=
594 --min-age= --before= --until=
595 --root --topo-order --date-order
597 --abbrev-commit --abbrev=
599 --author= --committer= --grep=
601 --pretty= --name-status --name-only
607 __git_complete_revlist
612 local cur="${COMP_WORDS[COMP_CWORD]}"
613 case "${COMP_WORDS[COMP_CWORD-1]}" in
615 __gitcomp "$(__git_merge_strategies)"
620 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
625 --no-commit --no-summary --squash --strategy
629 __gitcomp "$(__git_refs)"
634 __gitcomp "$(__git_refs)"
639 __gitcomp "--tags --all --stdin"
644 local cur="${COMP_WORDS[COMP_CWORD]}"
646 case "${COMP_WORDS[0]},$COMP_CWORD" in
648 __gitcomp "$(__git_remotes)"
651 __gitcomp "$(__git_remotes)"
655 case "${COMP_WORDS[0]}" in
656 git-pull) remote="${COMP_WORDS[1]}" ;;
657 git) remote="${COMP_WORDS[2]}" ;;
659 __gitcomp "$(__git_refs "$remote")"
666 local cur="${COMP_WORDS[COMP_CWORD]}"
668 case "${COMP_WORDS[0]},$COMP_CWORD" in
670 __gitcomp "$(__git_remotes)"
673 __gitcomp "$(__git_remotes)"
679 case "${COMP_WORDS[0]}" in
680 git-push) remote="${COMP_WORDS[1]}" ;;
681 git) remote="${COMP_WORDS[2]}" ;;
683 __gitcomp "$(__git_refs "$remote")" "" "${cur#*:}"
686 __gitcomp "$(__git_refs2)"
695 local cur="${COMP_WORDS[COMP_CWORD]}"
696 if [ -d .dotest ] || [ -d .git/.dotest-merge ]; then
697 __gitcomp "--continue --skip --abort"
700 case "${COMP_WORDS[COMP_CWORD-1]}" in
702 __gitcomp "$(__git_merge_strategies)"
707 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
711 __gitcomp "--onto --merge --strategy"
714 __gitcomp "$(__git_refs)"
719 local cur="${COMP_WORDS[COMP_CWORD]}"
720 local prv="${COMP_WORDS[COMP_CWORD-1]}"
723 __gitcomp "$(__git_remotes)"
727 __gitcomp "$(__git_refs)"
731 local remote="${prv#remote.}"
732 remote="${remote%.fetch}"
733 __gitcomp "$(__git_refs_remotes "$remote")"
737 local remote="${prv#remote.}"
738 remote="${remote%.push}"
739 __gitcomp "$(git --git-dir="$(__gitdir)" \
740 for-each-ref --format='%(refname):%(refname)' \
744 pull.twohead|pull.octopus)
745 __gitcomp "$(__git_merge_strategies)"
748 color.branch|color.diff|color.status)
749 __gitcomp "always never auto"
754 black red green yellow blue magenta cyan white
755 bold dim ul blink reverse
767 --global --list --replace-all
768 --get --get-all --get-regexp
769 --add --unset --unset-all
774 local pfx="${cur%.*}."
776 __gitcomp "remote merge" "$pfx" "$cur"
780 local pfx="${cur%.*}."
782 __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
786 local pfx="${cur%.*}."
788 __gitcomp "url fetch push" "$pfx" "$cur"
792 local pfx="${cur%.*}."
794 __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
803 core.preferSymlinkRefs
804 core.logAllRefUpdates
805 core.repositoryFormatVersion
806 core.sharedRepository
807 core.warnAmbiguousRefs
810 core.packedGitWindowSize
825 color.diff.whitespace
831 color.status.untracked
839 gc.reflogexpireunreachable
852 i18n.logOutputEncoding
859 repack.useDeltaBaseOffset
865 receive.denyNonFastForwards
877 while [ $c -lt $COMP_CWORD ]; do
880 add|show|prune|update) command="$i"; break ;;
885 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
886 __gitcomp "add show prune update"
892 __gitcomp "$(__git_remotes)"
895 local i c='' IFS=$'\n'
896 for i in $(git --git-dir="$(__gitdir)" config --list); do
914 local cur="${COMP_WORDS[COMP_CWORD]}"
917 __gitcomp "--mixed --hard --soft"
921 __gitcomp "$(__git_refs)"
926 local cur="${COMP_WORDS[COMP_CWORD]}"
930 --max-count= --max-age= --since= --after=
931 --min-age= --before= --until=
933 --author= --committer= --grep=
941 __git_complete_revlist
946 local cur="${COMP_WORDS[COMP_CWORD]}"
950 oneline short medium full fuller email raw
951 " "" "${cur##--pretty=}"
955 __gitcomp "--pretty="
964 local i c=1 command __git_dir
966 while [ $c -lt $COMP_CWORD ]; do
969 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
970 --bare) __git_dir="." ;;
971 --version|--help|-p|--paginate) ;;
972 *) command="$i"; break ;;
977 if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
978 case "${COMP_WORDS[COMP_CWORD]}" in
979 --*=*) COMPREPLY=() ;;
980 --*) __gitcomp "--git-dir= --bare --version --exec-path" ;;
981 *) __gitcomp "$(__git_commands) $(__git_aliases)" ;;
986 local expansion=$(__git_aliased_command "$command")
987 [ "$expansion" ] && command="$expansion"
993 bisect) _git_bisect ;;
994 branch) _git_branch ;;
995 checkout) _git_checkout ;;
996 cherry) _git_cherry ;;
997 cherry-pick) _git_cherry_pick ;;
998 commit) _git_commit ;;
999 config) _git_config ;;
1001 fetch) _git_fetch ;;
1002 format-patch) _git_format_patch ;;
1005 ls-remote) _git_ls_remote ;;
1006 ls-tree) _git_ls_tree ;;
1008 merge-base) _git_merge_base ;;
1009 name-rev) _git_name_rev ;;
1012 rebase) _git_rebase ;;
1013 remote) _git_remote ;;
1014 reset) _git_reset ;;
1015 shortlog) _git_shortlog ;;
1017 show-branch) _git_log ;;
1018 whatchanged) _git_log ;;
1025 local cur="${COMP_WORDS[COMP_CWORD]}"
1028 __gitcomp "--not --all"
1032 __git_complete_revlist
1035 complete -o default -o nospace -F _git git
1036 complete -o default -o nospace -F _gitk gitk
1037 complete -o default -o nospace -F _git_am git-am
1038 complete -o default -o nospace -F _git_apply git-apply
1039 complete -o default -o nospace -F _git_bisect git-bisect
1040 complete -o default -o nospace -F _git_branch git-branch
1041 complete -o default -o nospace -F _git_checkout git-checkout
1042 complete -o default -o nospace -F _git_cherry git-cherry
1043 complete -o default -o nospace -F _git_cherry_pick git-cherry-pick
1044 complete -o default -o nospace -F _git_commit git-commit
1045 complete -o default -o nospace -F _git_diff git-diff
1046 complete -o default -o nospace -F _git_fetch git-fetch
1047 complete -o default -o nospace -F _git_format_patch git-format-patch
1048 complete -o default -o nospace -F _git_gc git-gc
1049 complete -o default -o nospace -F _git_log git-log
1050 complete -o default -o nospace -F _git_ls_remote git-ls-remote
1051 complete -o default -o nospace -F _git_ls_tree git-ls-tree
1052 complete -o default -o nospace -F _git_merge git-merge
1053 complete -o default -o nospace -F _git_merge_base git-merge-base
1054 complete -o default -o nospace -F _git_name_rev git-name-rev
1055 complete -o default -o nospace -F _git_pull git-pull
1056 complete -o default -o nospace -F _git_push git-push
1057 complete -o default -o nospace -F _git_rebase git-rebase
1058 complete -o default -o nospace -F _git_config git-config
1059 complete -o default -o nospace -F _git_remote git-remote
1060 complete -o default -o nospace -F _git_reset git-reset
1061 complete -o default -o nospace -F _git_shortlog git-shortlog
1062 complete -o default -o nospace -F _git_show git-show
1063 complete -o default -o nospace -F _git_log git-show-branch
1064 complete -o default -o nospace -F _git_log git-whatchanged
1066 # The following are necessary only for Cygwin, and only are needed
1067 # when the user has tab-completed the executable name and consequently
1068 # included the '.exe' suffix.
1070 if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1071 complete -o default -o nospace -F _git_add git-add.exe
1072 complete -o default -o nospace -F _git_apply git-apply.exe
1073 complete -o default -o nospace -F _git git.exe
1074 complete -o default -o nospace -F _git_branch git-branch.exe
1075 complete -o default -o nospace -F _git_cherry git-cherry.exe
1076 complete -o default -o nospace -F _git_diff git-diff.exe
1077 complete -o default -o nospace -F _git_format_patch git-format-patch.exe
1078 complete -o default -o nospace -F _git_log git-log.exe
1079 complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
1080 complete -o default -o nospace -F _git_merge_base git-merge-base.exe
1081 complete -o default -o nospace -F _git_name_rev git-name-rev.exe
1082 complete -o default -o nospace -F _git_push git-push.exe
1083 complete -o default -o nospace -F _git_config git-config
1084 complete -o default -o nospace -F _git_shortlog git-shortlog.exe
1085 complete -o default -o nospace -F _git_show git-show.exe
1086 complete -o default -o nospace -F _git_log git-show-branch.exe
1087 complete -o default -o nospace -F _git_log git-whatchanged.exe