68b68d0c78fe2ce7aaa80ff0615573f3bfe04525
1#!bash
2#
3# bash completion support for core Git.
4#
5# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
6# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
7# Distributed under the GNU General Public License, version 2.0.
8#
9# The contained completion routines provide support for completing:
10#
11# *) local and remote branch names
12# *) local and remote tag names
13# *) .git/remotes file names
14# *) git 'subcommands'
15# *) tree paths within 'ref:path/to/file' expressions
16# *) common --long-options
17#
18# To use these routines:
19#
20# 1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
21# 2) Added the following line to your .bashrc:
22# source ~/.git-completion.sh
23#
24# 3) Consider changing your PS1 to also show the current branch:
25# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
26#
27# The argument to __git_ps1 will be displayed only if you
28# are currently in a git repository. The %s token will be
29# the name of the current branch.
30#
31# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty
32# value, unstaged (*) and staged (+) changes will be shown next
33# to the branch name. You can configure this per-repository
34# with the bash.showDirtyState variable, which defaults to true
35# once GIT_PS1_SHOWDIRTYSTATE is enabled.
36#
37# You can also see if currently something is stashed, by setting
38# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
39# then a '$' will be shown next to the branch name.
40#
41# If you would like to see if there're untracked files, then you can
42# set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
43# untracked files, then a '%' will be shown next to the branch name.
44#
45# If you would like to see the difference between HEAD and its
46# upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates
47# you are behind, ">" indicates you are ahead, and "<>"
48# indicates you have diverged. You can further control
49# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated
50# list of values:
51# verbose show number of commits ahead/behind (+/-) upstream
52# legacy don't use the '--count' option available in recent
53# versions of git-rev-list
54# git always compare HEAD to @{upstream}
55# svn always compare HEAD to your SVN upstream
56# By default, __git_ps1 will compare HEAD to your SVN upstream
57# if it can find one, or @{upstream} otherwise. Once you have
58# set GIT_PS1_SHOWUPSTREAM, you can override it on a
59# per-repository basis by setting the bash.showUpstream config
60# variable.
61#
62#
63# To submit patches:
64#
65# *) Read Documentation/SubmittingPatches
66# *) Send all patches to the current maintainer:
67#
68# "Shawn O. Pearce" <spearce@spearce.org>
69#
70# *) Always CC the Git mailing list:
71#
72# git@vger.kernel.org
73#
74
75case "$COMP_WORDBREAKS" in
76*:*) : great ;;
77*) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
78esac
79
80# __gitdir accepts 0 or 1 arguments (i.e., location)
81# returns location of .git repo
82__gitdir ()
83{
84 if [ -z "${1-}" ]; then
85 if [ -n "${__git_dir-}" ]; then
86 echo "$__git_dir"
87 elif [ -d .git ]; then
88 echo .git
89 else
90 git rev-parse --git-dir 2>/dev/null
91 fi
92 elif [ -d "$1/.git" ]; then
93 echo "$1/.git"
94 else
95 echo "$1"
96 fi
97}
98
99# stores the divergence from upstream in $p
100# used by GIT_PS1_SHOWUPSTREAM
101__git_ps1_show_upstream ()
102{
103 local key value
104 local svn_remote=() svn_url_pattern count n
105 local upstream=git legacy="" verbose=""
106
107 # get some config options from git-config
108 while read key value; do
109 case "$key" in
110 bash.showupstream)
111 GIT_PS1_SHOWUPSTREAM="$value"
112 if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
113 p=""
114 return
115 fi
116 ;;
117 svn-remote.*.url)
118 svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
119 svn_url_pattern+="\\|$value"
120 upstream=svn+git # default upstream is SVN if available, else git
121 ;;
122 esac
123 done < <(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')
124
125 # parse configuration values
126 for option in ${GIT_PS1_SHOWUPSTREAM}; do
127 case "$option" in
128 git|svn) upstream="$option" ;;
129 verbose) verbose=1 ;;
130 legacy) legacy=1 ;;
131 esac
132 done
133
134 # Find our upstream
135 case "$upstream" in
136 git) upstream="@{upstream}" ;;
137 svn*)
138 # get the upstream from the "git-svn-id: ..." in a commit message
139 # (git-svn uses essentially the same procedure internally)
140 local svn_upstream=($(git log --first-parent -1 \
141 --grep="^git-svn-id: \(${svn_url_pattern:2}\)" 2>/dev/null))
142 if [[ 0 -ne ${#svn_upstream[@]} ]]; then
143 svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
144 svn_upstream=${svn_upstream%@*}
145 for ((n=1; "$n" <= "${#svn_remote[@]}"; ++n)); do
146 svn_upstream=${svn_upstream#${svn_remote[$n]}}
147 done
148
149 if [[ -z "$svn_upstream" ]]; then
150 # default branch name for checkouts with no layout:
151 upstream=${GIT_SVN_ID:-git-svn}
152 else
153 upstream=${svn_upstream#/}
154 fi
155 elif [[ "svn+git" = "$upstream" ]]; then
156 upstream="@{upstream}"
157 fi
158 ;;
159 esac
160
161 # Find how many commits we are ahead/behind our upstream
162 if [[ -z "$legacy" ]]; then
163 count="$(git rev-list --count --left-right \
164 "$upstream"...HEAD 2>/dev/null)"
165 else
166 # produce equivalent output to --count for older versions of git
167 local commits
168 if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
169 then
170 local commit behind=0 ahead=0
171 for commit in $commits
172 do
173 case "$commit" in
174 "<"*) let ++behind
175 ;;
176 *) let ++ahead
177 ;;
178 esac
179 done
180 count="$behind $ahead"
181 else
182 count=""
183 fi
184 fi
185
186 # calculate the result
187 if [[ -z "$verbose" ]]; then
188 case "$count" in
189 "") # no upstream
190 p="" ;;
191 "0 0") # equal to upstream
192 p="=" ;;
193 "0 "*) # ahead of upstream
194 p=">" ;;
195 *" 0") # behind upstream
196 p="<" ;;
197 *) # diverged from upstream
198 p="<>" ;;
199 esac
200 else
201 case "$count" in
202 "") # no upstream
203 p="" ;;
204 "0 0") # equal to upstream
205 p=" u=" ;;
206 "0 "*) # ahead of upstream
207 p=" u+${count#0 }" ;;
208 *" 0") # behind upstream
209 p=" u-${count% 0}" ;;
210 *) # diverged from upstream
211 p=" u+${count#* }-${count% *}" ;;
212 esac
213 fi
214
215}
216
217
218# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
219# returns text to add to bash PS1 prompt (includes branch name)
220__git_ps1 ()
221{
222 local g="$(__gitdir)"
223 if [ -n "$g" ]; then
224 local r=""
225 local b=""
226 if [ -f "$g/rebase-merge/interactive" ]; then
227 r="|REBASE-i"
228 b="$(cat "$g/rebase-merge/head-name")"
229 elif [ -d "$g/rebase-merge" ]; then
230 r="|REBASE-m"
231 b="$(cat "$g/rebase-merge/head-name")"
232 else
233 if [ -d "$g/rebase-apply" ]; then
234 if [ -f "$g/rebase-apply/rebasing" ]; then
235 r="|REBASE"
236 elif [ -f "$g/rebase-apply/applying" ]; then
237 r="|AM"
238 else
239 r="|AM/REBASE"
240 fi
241 elif [ -f "$g/MERGE_HEAD" ]; then
242 r="|MERGING"
243 elif [ -f "$g/BISECT_LOG" ]; then
244 r="|BISECTING"
245 fi
246
247 b="$(git symbolic-ref HEAD 2>/dev/null)" || {
248
249 b="$(
250 case "${GIT_PS1_DESCRIBE_STYLE-}" in
251 (contains)
252 git describe --contains HEAD ;;
253 (branch)
254 git describe --contains --all HEAD ;;
255 (describe)
256 git describe HEAD ;;
257 (* | default)
258 git describe --tags --exact-match HEAD ;;
259 esac 2>/dev/null)" ||
260
261 b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
262 b="unknown"
263 b="($b)"
264 }
265 fi
266
267 local w=""
268 local i=""
269 local s=""
270 local u=""
271 local c=""
272 local p=""
273
274 if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
275 if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
276 c="BARE:"
277 else
278 b="GIT_DIR!"
279 fi
280 elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
281 if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
282 if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
283 git diff --no-ext-diff --quiet --exit-code || w="*"
284 if git rev-parse --quiet --verify HEAD >/dev/null; then
285 git diff-index --cached --quiet HEAD -- || i="+"
286 else
287 i="#"
288 fi
289 fi
290 fi
291 if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
292 git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
293 fi
294
295 if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
296 if [ -n "$(git ls-files --others --exclude-standard)" ]; then
297 u="%"
298 fi
299 fi
300
301 if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
302 __git_ps1_show_upstream
303 fi
304 fi
305
306 local f="$w$i$s$u"
307 printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
308 fi
309}
310
311# __gitcomp_1 requires 2 arguments
312__gitcomp_1 ()
313{
314 local c IFS=' '$'\t'$'\n'
315 for c in $1; do
316 case "$c$2" in
317 --*=*) printf %s$'\n' "$c$2" ;;
318 *.) printf %s$'\n' "$c$2" ;;
319 *) printf %s$'\n' "$c$2 " ;;
320 esac
321 done
322}
323
324if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
325_get_comp_words_by_ref ()
326{
327 while [ $# -gt 0 ]; do
328 case "$1" in
329 cur)
330 cur=${COMP_WORDS[COMP_CWORD]}
331 ;;
332 prev)
333 prev=${COMP_WORDS[COMP_CWORD-1]}
334 ;;
335 words)
336 words=("${COMP_WORDS[@]}")
337 ;;
338 cword)
339 cword=$COMP_CWORD
340 ;;
341 -n)
342 # assume COMP_WORDBREAKS is already set sanely
343 shift
344 ;;
345 esac
346 shift
347 done
348}
349fi
350
351# __gitcomp accepts 1, 2, 3, or 4 arguments
352# generates completion reply with compgen
353__gitcomp ()
354{
355 local cur
356 _get_comp_words_by_ref -n =: cur
357 if [ $# -gt 2 ]; then
358 cur="$3"
359 fi
360 case "$cur" in
361 --*=)
362 COMPREPLY=()
363 ;;
364 *)
365 local IFS=$'\n'
366 COMPREPLY=($(compgen -P "${2-}" \
367 -W "$(__gitcomp_1 "${1-}" "${4-}")" \
368 -- "$cur"))
369 ;;
370 esac
371}
372
373# __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
374__git_heads ()
375{
376 local cmd i is_hash=y dir="$(__gitdir "${1-}")"
377 if [ -d "$dir" ]; then
378 git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
379 refs/heads
380 return
381 fi
382 for i in $(git ls-remote "${1-}" 2>/dev/null); do
383 case "$is_hash,$i" in
384 y,*) is_hash=n ;;
385 n,*^{}) is_hash=y ;;
386 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
387 n,*) is_hash=y; echo "$i" ;;
388 esac
389 done
390}
391
392# __git_tags accepts 0 or 1 arguments (to pass to __gitdir)
393__git_tags ()
394{
395 local cmd i is_hash=y dir="$(__gitdir "${1-}")"
396 if [ -d "$dir" ]; then
397 git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
398 refs/tags
399 return
400 fi
401 for i in $(git ls-remote "${1-}" 2>/dev/null); do
402 case "$is_hash,$i" in
403 y,*) is_hash=n ;;
404 n,*^{}) is_hash=y ;;
405 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
406 n,*) is_hash=y; echo "$i" ;;
407 esac
408 done
409}
410
411# __git_refs accepts 0 or 1 arguments (to pass to __gitdir)
412__git_refs ()
413{
414 local i is_hash=y dir="$(__gitdir "${1-}")"
415 local cur format refs
416 _get_comp_words_by_ref -n =: cur
417 if [ -d "$dir" ]; then
418 case "$cur" in
419 refs|refs/*)
420 format="refname"
421 refs="${cur%/*}"
422 ;;
423 *)
424 for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
425 if [ -e "$dir/$i" ]; then echo $i; fi
426 done
427 format="refname:short"
428 refs="refs/tags refs/heads refs/remotes"
429 ;;
430 esac
431 git --git-dir="$dir" for-each-ref --format="%($format)" \
432 $refs
433 return
434 fi
435 for i in $(git ls-remote "$dir" 2>/dev/null); do
436 case "$is_hash,$i" in
437 y,*) is_hash=n ;;
438 n,*^{}) is_hash=y ;;
439 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
440 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
441 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
442 n,*) is_hash=y; echo "$i" ;;
443 esac
444 done
445}
446
447# __git_refs2 requires 1 argument (to pass to __git_refs)
448__git_refs2 ()
449{
450 local i
451 for i in $(__git_refs "$1"); do
452 echo "$i:$i"
453 done
454}
455
456# __git_refs_remotes requires 1 argument (to pass to ls-remote)
457__git_refs_remotes ()
458{
459 local cmd i is_hash=y
460 for i in $(git ls-remote "$1" 2>/dev/null); do
461 case "$is_hash,$i" in
462 n,refs/heads/*)
463 is_hash=y
464 echo "$i:refs/remotes/$1/${i#refs/heads/}"
465 ;;
466 y,*) is_hash=n ;;
467 n,*^{}) is_hash=y ;;
468 n,refs/tags/*) is_hash=y;;
469 n,*) is_hash=y; ;;
470 esac
471 done
472}
473
474__git_remotes ()
475{
476 local i ngoff IFS=$'\n' d="$(__gitdir)"
477 shopt -q nullglob || ngoff=1
478 shopt -s nullglob
479 for i in "$d/remotes"/*; do
480 echo ${i#$d/remotes/}
481 done
482 [ "$ngoff" ] && shopt -u nullglob
483 for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
484 i="${i#remote.}"
485 echo "${i/.url*/}"
486 done
487}
488
489__git_list_merge_strategies ()
490{
491 git merge -s help 2>&1 |
492 sed -n -e '/[Aa]vailable strategies are: /,/^$/{
493 s/\.$//
494 s/.*://
495 s/^[ ]*//
496 s/[ ]*$//
497 p
498 }'
499}
500
501__git_merge_strategies=
502# 'git merge -s help' (and thus detection of the merge strategy
503# list) fails, unfortunately, if run outside of any git working
504# tree. __git_merge_strategies is set to the empty string in
505# that case, and the detection will be repeated the next time it
506# is needed.
507__git_compute_merge_strategies ()
508{
509 : ${__git_merge_strategies:=$(__git_list_merge_strategies)}
510}
511
512__git_complete_file ()
513{
514 local pfx ls ref cur
515 _get_comp_words_by_ref -n =: cur
516 case "$cur" in
517 ?*:*)
518 ref="${cur%%:*}"
519 cur="${cur#*:}"
520 case "$cur" in
521 ?*/*)
522 pfx="${cur%/*}"
523 cur="${cur##*/}"
524 ls="$ref:$pfx"
525 pfx="$pfx/"
526 ;;
527 *)
528 ls="$ref"
529 ;;
530 esac
531
532 case "$COMP_WORDBREAKS" in
533 *:*) : great ;;
534 *) pfx="$ref:$pfx" ;;
535 esac
536
537 local IFS=$'\n'
538 COMPREPLY=($(compgen -P "$pfx" \
539 -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
540 | sed '/^100... blob /{
541 s,^.* ,,
542 s,$, ,
543 }
544 /^120000 blob /{
545 s,^.* ,,
546 s,$, ,
547 }
548 /^040000 tree /{
549 s,^.* ,,
550 s,$,/,
551 }
552 s/^.* //')" \
553 -- "$cur"))
554 ;;
555 *)
556 __gitcomp "$(__git_refs)"
557 ;;
558 esac
559}
560
561__git_complete_revlist ()
562{
563 local pfx cur
564 _get_comp_words_by_ref -n =: cur
565 case "$cur" in
566 *...*)
567 pfx="${cur%...*}..."
568 cur="${cur#*...}"
569 __gitcomp "$(__git_refs)" "$pfx" "$cur"
570 ;;
571 *..*)
572 pfx="${cur%..*}.."
573 cur="${cur#*..}"
574 __gitcomp "$(__git_refs)" "$pfx" "$cur"
575 ;;
576 *)
577 __gitcomp "$(__git_refs)"
578 ;;
579 esac
580}
581
582__git_complete_remote_or_refspec ()
583{
584 local cur words cword
585 _get_comp_words_by_ref -n =: cur words cword
586 local cmd="${words[1]}"
587 local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
588 while [ $c -lt $cword ]; do
589 i="${words[c]}"
590 case "$i" in
591 --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
592 --all)
593 case "$cmd" in
594 push) no_complete_refspec=1 ;;
595 fetch)
596 COMPREPLY=()
597 return
598 ;;
599 *) ;;
600 esac
601 ;;
602 -*) ;;
603 *) remote="$i"; break ;;
604 esac
605 c=$((++c))
606 done
607 if [ -z "$remote" ]; then
608 __gitcomp "$(__git_remotes)"
609 return
610 fi
611 if [ $no_complete_refspec = 1 ]; then
612 COMPREPLY=()
613 return
614 fi
615 [ "$remote" = "." ] && remote=
616 case "$cur" in
617 *:*)
618 case "$COMP_WORDBREAKS" in
619 *:*) : great ;;
620 *) pfx="${cur%%:*}:" ;;
621 esac
622 cur="${cur#*:}"
623 lhs=0
624 ;;
625 +*)
626 pfx="+"
627 cur="${cur#+}"
628 ;;
629 esac
630 case "$cmd" in
631 fetch)
632 if [ $lhs = 1 ]; then
633 __gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur"
634 else
635 __gitcomp "$(__git_refs)" "$pfx" "$cur"
636 fi
637 ;;
638 pull)
639 if [ $lhs = 1 ]; then
640 __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
641 else
642 __gitcomp "$(__git_refs)" "$pfx" "$cur"
643 fi
644 ;;
645 push)
646 if [ $lhs = 1 ]; then
647 __gitcomp "$(__git_refs)" "$pfx" "$cur"
648 else
649 __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
650 fi
651 ;;
652 esac
653}
654
655__git_complete_strategy ()
656{
657 local cur prev
658 _get_comp_words_by_ref -n =: cur prev
659 __git_compute_merge_strategies
660 case "$prev" in
661 -s|--strategy)
662 __gitcomp "$__git_merge_strategies"
663 return 0
664 esac
665 case "$cur" in
666 --strategy=*)
667 __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
668 return 0
669 ;;
670 esac
671 return 1
672}
673
674__git_list_all_commands ()
675{
676 local i IFS=" "$'\n'
677 for i in $(git help -a|egrep '^ [a-zA-Z0-9]')
678 do
679 case $i in
680 *--*) : helper pattern;;
681 *) echo $i;;
682 esac
683 done
684}
685
686__git_all_commands=
687__git_compute_all_commands ()
688{
689 : ${__git_all_commands:=$(__git_list_all_commands)}
690}
691
692__git_list_porcelain_commands ()
693{
694 local i IFS=" "$'\n'
695 __git_compute_all_commands
696 for i in "help" $__git_all_commands
697 do
698 case $i in
699 *--*) : helper pattern;;
700 applymbox) : ask gittus;;
701 applypatch) : ask gittus;;
702 archimport) : import;;
703 cat-file) : plumbing;;
704 check-attr) : plumbing;;
705 check-ref-format) : plumbing;;
706 checkout-index) : plumbing;;
707 commit-tree) : plumbing;;
708 count-objects) : infrequent;;
709 cvsexportcommit) : export;;
710 cvsimport) : import;;
711 cvsserver) : daemon;;
712 daemon) : daemon;;
713 diff-files) : plumbing;;
714 diff-index) : plumbing;;
715 diff-tree) : plumbing;;
716 fast-import) : import;;
717 fast-export) : export;;
718 fsck-objects) : plumbing;;
719 fetch-pack) : plumbing;;
720 fmt-merge-msg) : plumbing;;
721 for-each-ref) : plumbing;;
722 hash-object) : plumbing;;
723 http-*) : transport;;
724 index-pack) : plumbing;;
725 init-db) : deprecated;;
726 local-fetch) : plumbing;;
727 lost-found) : infrequent;;
728 ls-files) : plumbing;;
729 ls-remote) : plumbing;;
730 ls-tree) : plumbing;;
731 mailinfo) : plumbing;;
732 mailsplit) : plumbing;;
733 merge-*) : plumbing;;
734 mktree) : plumbing;;
735 mktag) : plumbing;;
736 pack-objects) : plumbing;;
737 pack-redundant) : plumbing;;
738 pack-refs) : plumbing;;
739 parse-remote) : plumbing;;
740 patch-id) : plumbing;;
741 peek-remote) : plumbing;;
742 prune) : plumbing;;
743 prune-packed) : plumbing;;
744 quiltimport) : import;;
745 read-tree) : plumbing;;
746 receive-pack) : plumbing;;
747 reflog) : plumbing;;
748 remote-*) : transport;;
749 repo-config) : deprecated;;
750 rerere) : plumbing;;
751 rev-list) : plumbing;;
752 rev-parse) : plumbing;;
753 runstatus) : plumbing;;
754 sh-setup) : internal;;
755 shell) : daemon;;
756 show-ref) : plumbing;;
757 send-pack) : plumbing;;
758 show-index) : plumbing;;
759 ssh-*) : transport;;
760 stripspace) : plumbing;;
761 symbolic-ref) : plumbing;;
762 tar-tree) : deprecated;;
763 unpack-file) : plumbing;;
764 unpack-objects) : plumbing;;
765 update-index) : plumbing;;
766 update-ref) : plumbing;;
767 update-server-info) : daemon;;
768 upload-archive) : plumbing;;
769 upload-pack) : plumbing;;
770 write-tree) : plumbing;;
771 var) : infrequent;;
772 verify-pack) : infrequent;;
773 verify-tag) : plumbing;;
774 *) echo $i;;
775 esac
776 done
777}
778
779__git_porcelain_commands=
780__git_compute_porcelain_commands ()
781{
782 __git_compute_all_commands
783 : ${__git_porcelain_commands:=$(__git_list_porcelain_commands)}
784}
785
786__git_aliases ()
787{
788 local i IFS=$'\n'
789 for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
790 case "$i" in
791 alias.*)
792 i="${i#alias.}"
793 echo "${i/ */}"
794 ;;
795 esac
796 done
797}
798
799# __git_aliased_command requires 1 argument
800__git_aliased_command ()
801{
802 local word cmdline=$(git --git-dir="$(__gitdir)" \
803 config --get "alias.$1")
804 for word in $cmdline; do
805 case "$word" in
806 \!gitk|gitk)
807 echo "gitk"
808 return
809 ;;
810 \!*) : shell command alias ;;
811 -*) : option ;;
812 *=*) : setting env ;;
813 git) : git itself ;;
814 *)
815 echo "$word"
816 return
817 esac
818 done
819}
820
821# __git_find_on_cmdline requires 1 argument
822__git_find_on_cmdline ()
823{
824 local word subcommand c=1 words cword
825 _get_comp_words_by_ref -n =: words cword
826 while [ $c -lt $cword ]; do
827 word="${words[c]}"
828 for subcommand in $1; do
829 if [ "$subcommand" = "$word" ]; then
830 echo "$subcommand"
831 return
832 fi
833 done
834 c=$((++c))
835 done
836}
837
838__git_has_doubledash ()
839{
840 local c=1 words cword
841 _get_comp_words_by_ref -n =: words cword
842 while [ $c -lt $cword ]; do
843 if [ "--" = "${words[c]}" ]; then
844 return 0
845 fi
846 c=$((++c))
847 done
848 return 1
849}
850
851__git_whitespacelist="nowarn warn error error-all fix"
852
853_git_am ()
854{
855 local cur dir="$(__gitdir)"
856 _get_comp_words_by_ref -n =: cur
857 if [ -d "$dir"/rebase-apply ]; then
858 __gitcomp "--skip --continue --resolved --abort"
859 return
860 fi
861 case "$cur" in
862 --whitespace=*)
863 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
864 return
865 ;;
866 --*)
867 __gitcomp "
868 --3way --committer-date-is-author-date --ignore-date
869 --ignore-whitespace --ignore-space-change
870 --interactive --keep --no-utf8 --signoff --utf8
871 --whitespace= --scissors
872 "
873 return
874 esac
875 COMPREPLY=()
876}
877
878_git_apply ()
879{
880 local cur
881 _get_comp_words_by_ref -n =: cur
882 case "$cur" in
883 --whitespace=*)
884 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
885 return
886 ;;
887 --*)
888 __gitcomp "
889 --stat --numstat --summary --check --index
890 --cached --index-info --reverse --reject --unidiff-zero
891 --apply --no-add --exclude=
892 --ignore-whitespace --ignore-space-change
893 --whitespace= --inaccurate-eof --verbose
894 "
895 return
896 esac
897 COMPREPLY=()
898}
899
900_git_add ()
901{
902 __git_has_doubledash && return
903
904 local cur
905 _get_comp_words_by_ref -n =: cur
906 case "$cur" in
907 --*)
908 __gitcomp "
909 --interactive --refresh --patch --update --dry-run
910 --ignore-errors --intent-to-add
911 "
912 return
913 esac
914 COMPREPLY=()
915}
916
917_git_archive ()
918{
919 local cur
920 _get_comp_words_by_ref -n =: cur
921 case "$cur" in
922 --format=*)
923 __gitcomp "$(git archive --list)" "" "${cur##--format=}"
924 return
925 ;;
926 --remote=*)
927 __gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
928 return
929 ;;
930 --*)
931 __gitcomp "
932 --format= --list --verbose
933 --prefix= --remote= --exec=
934 "
935 return
936 ;;
937 esac
938 __git_complete_file
939}
940
941_git_bisect ()
942{
943 __git_has_doubledash && return
944
945 local subcommands="start bad good skip reset visualize replay log run"
946 local subcommand="$(__git_find_on_cmdline "$subcommands")"
947 if [ -z "$subcommand" ]; then
948 __gitcomp "$subcommands"
949 return
950 fi
951
952 case "$subcommand" in
953 bad|good|reset|skip)
954 __gitcomp "$(__git_refs)"
955 ;;
956 *)
957 COMPREPLY=()
958 ;;
959 esac
960}
961
962_git_branch ()
963{
964 local i c=1 only_local_ref="n" has_r="n" cur words cword
965
966 _get_comp_words_by_ref -n =: cur words cword
967 while [ $c -lt $cword ]; do
968 i="${words[c]}"
969 case "$i" in
970 -d|-m) only_local_ref="y" ;;
971 -r) has_r="y" ;;
972 esac
973 c=$((++c))
974 done
975
976 case "$cur" in
977 --*)
978 __gitcomp "
979 --color --no-color --verbose --abbrev= --no-abbrev
980 --track --no-track --contains --merged --no-merged
981 --set-upstream
982 "
983 ;;
984 *)
985 if [ $only_local_ref = "y" -a $has_r = "n" ]; then
986 __gitcomp "$(__git_heads)"
987 else
988 __gitcomp "$(__git_refs)"
989 fi
990 ;;
991 esac
992}
993
994_git_bundle ()
995{
996 local words cword
997 _get_comp_words_by_ref -n =: words cword
998 local cmd="${words[2]}"
999 case "$cword" in
1000 2)
1001 __gitcomp "create list-heads verify unbundle"
1002 ;;
1003 3)
1004 # looking for a file
1005 ;;
1006 *)
1007 case "$cmd" in
1008 create)
1009 __git_complete_revlist
1010 ;;
1011 esac
1012 ;;
1013 esac
1014}
1015
1016_git_checkout ()
1017{
1018 __git_has_doubledash && return
1019
1020 local cur
1021 _get_comp_words_by_ref -n =: cur
1022 case "$cur" in
1023 --conflict=*)
1024 __gitcomp "diff3 merge" "" "${cur##--conflict=}"
1025 ;;
1026 --*)
1027 __gitcomp "
1028 --quiet --ours --theirs --track --no-track --merge
1029 --conflict= --orphan --patch
1030 "
1031 ;;
1032 *)
1033 __gitcomp "$(__git_refs)"
1034 ;;
1035 esac
1036}
1037
1038_git_cherry ()
1039{
1040 __gitcomp "$(__git_refs)"
1041}
1042
1043_git_cherry_pick ()
1044{
1045 local cur
1046 _get_comp_words_by_ref -n =: cur
1047 case "$cur" in
1048 --*)
1049 __gitcomp "--edit --no-commit"
1050 ;;
1051 *)
1052 __gitcomp "$(__git_refs)"
1053 ;;
1054 esac
1055}
1056
1057_git_clean ()
1058{
1059 __git_has_doubledash && return
1060
1061 local cur
1062 _get_comp_words_by_ref -n =: cur
1063 case "$cur" in
1064 --*)
1065 __gitcomp "--dry-run --quiet"
1066 return
1067 ;;
1068 esac
1069 COMPREPLY=()
1070}
1071
1072_git_clone ()
1073{
1074 local cur
1075 _get_comp_words_by_ref -n =: cur
1076 case "$cur" in
1077 --*)
1078 __gitcomp "
1079 --local
1080 --no-hardlinks
1081 --shared
1082 --reference
1083 --quiet
1084 --no-checkout
1085 --bare
1086 --mirror
1087 --origin
1088 --upload-pack
1089 --template=
1090 --depth
1091 "
1092 return
1093 ;;
1094 esac
1095 COMPREPLY=()
1096}
1097
1098_git_commit ()
1099{
1100 __git_has_doubledash && return
1101
1102 local cur
1103 _get_comp_words_by_ref -n =: cur
1104 case "$cur" in
1105 --cleanup=*)
1106 __gitcomp "default strip verbatim whitespace
1107 " "" "${cur##--cleanup=}"
1108 return
1109 ;;
1110 --reuse-message=*)
1111 __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
1112 return
1113 ;;
1114 --reedit-message=*)
1115 __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
1116 return
1117 ;;
1118 --untracked-files=*)
1119 __gitcomp "all no normal" "" "${cur##--untracked-files=}"
1120 return
1121 ;;
1122 --*)
1123 __gitcomp "
1124 --all --author= --signoff --verify --no-verify
1125 --edit --amend --include --only --interactive
1126 --dry-run --reuse-message= --reedit-message=
1127 --reset-author --file= --message= --template=
1128 --cleanup= --untracked-files --untracked-files=
1129 --verbose --quiet
1130 "
1131 return
1132 esac
1133 COMPREPLY=()
1134}
1135
1136_git_describe ()
1137{
1138 local cur
1139 _get_comp_words_by_ref -n =: cur
1140 case "$cur" in
1141 --*)
1142 __gitcomp "
1143 --all --tags --contains --abbrev= --candidates=
1144 --exact-match --debug --long --match --always
1145 "
1146 return
1147 esac
1148 __gitcomp "$(__git_refs)"
1149}
1150
1151__git_diff_common_options="--stat --numstat --shortstat --summary
1152 --patch-with-stat --name-only --name-status --color
1153 --no-color --color-words --no-renames --check
1154 --full-index --binary --abbrev --diff-filter=
1155 --find-copies-harder
1156 --text --ignore-space-at-eol --ignore-space-change
1157 --ignore-all-space --exit-code --quiet --ext-diff
1158 --no-ext-diff
1159 --no-prefix --src-prefix= --dst-prefix=
1160 --inter-hunk-context=
1161 --patience
1162 --raw
1163 --dirstat --dirstat= --dirstat-by-file
1164 --dirstat-by-file= --cumulative
1165"
1166
1167_git_diff ()
1168{
1169 __git_has_doubledash && return
1170
1171 local cur
1172 _get_comp_words_by_ref -n =: cur
1173 case "$cur" in
1174 --*)
1175 __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1176 --base --ours --theirs
1177 $__git_diff_common_options
1178 "
1179 return
1180 ;;
1181 esac
1182 __git_complete_file
1183}
1184
1185__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
1186 tkdiff vimdiff gvimdiff xxdiff araxis p4merge
1187"
1188
1189_git_difftool ()
1190{
1191 __git_has_doubledash && return
1192
1193 local cur
1194 _get_comp_words_by_ref -n =: cur
1195 case "$cur" in
1196 --tool=*)
1197 __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
1198 return
1199 ;;
1200 --*)
1201 __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1202 --base --ours --theirs
1203 --no-renames --diff-filter= --find-copies-harder
1204 --relative --ignore-submodules
1205 --tool="
1206 return
1207 ;;
1208 esac
1209 __git_complete_file
1210}
1211
1212__git_fetch_options="
1213 --quiet --verbose --append --upload-pack --force --keep --depth=
1214 --tags --no-tags --all --prune --dry-run
1215"
1216
1217_git_fetch ()
1218{
1219 local cur
1220 _get_comp_words_by_ref -n =: cur
1221 case "$cur" in
1222 --*)
1223 __gitcomp "$__git_fetch_options"
1224 return
1225 ;;
1226 esac
1227 __git_complete_remote_or_refspec
1228}
1229
1230_git_format_patch ()
1231{
1232 local cur
1233 _get_comp_words_by_ref -n =: cur
1234 case "$cur" in
1235 --thread=*)
1236 __gitcomp "
1237 deep shallow
1238 " "" "${cur##--thread=}"
1239 return
1240 ;;
1241 --*)
1242 __gitcomp "
1243 --stdout --attach --no-attach --thread --thread=
1244 --output-directory
1245 --numbered --start-number
1246 --numbered-files
1247 --keep-subject
1248 --signoff --signature --no-signature
1249 --in-reply-to= --cc=
1250 --full-index --binary
1251 --not --all
1252 --cover-letter
1253 --no-prefix --src-prefix= --dst-prefix=
1254 --inline --suffix= --ignore-if-in-upstream
1255 --subject-prefix=
1256 "
1257 return
1258 ;;
1259 esac
1260 __git_complete_revlist
1261}
1262
1263_git_fsck ()
1264{
1265 local cur
1266 _get_comp_words_by_ref -n =: cur
1267 case "$cur" in
1268 --*)
1269 __gitcomp "
1270 --tags --root --unreachable --cache --no-reflogs --full
1271 --strict --verbose --lost-found
1272 "
1273 return
1274 ;;
1275 esac
1276 COMPREPLY=()
1277}
1278
1279_git_gc ()
1280{
1281 local cur
1282 _get_comp_words_by_ref -n =: cur
1283 case "$cur" in
1284 --*)
1285 __gitcomp "--prune --aggressive"
1286 return
1287 ;;
1288 esac
1289 COMPREPLY=()
1290}
1291
1292_git_gitk ()
1293{
1294 _gitk
1295}
1296
1297_git_grep ()
1298{
1299 __git_has_doubledash && return
1300
1301 local cur
1302 _get_comp_words_by_ref -n =: cur
1303 case "$cur" in
1304 --*)
1305 __gitcomp "
1306 --cached
1307 --text --ignore-case --word-regexp --invert-match
1308 --full-name
1309 --extended-regexp --basic-regexp --fixed-strings
1310 --files-with-matches --name-only
1311 --files-without-match
1312 --max-depth
1313 --count
1314 --and --or --not --all-match
1315 "
1316 return
1317 ;;
1318 esac
1319
1320 __gitcomp "$(__git_refs)"
1321}
1322
1323_git_help ()
1324{
1325 local cur
1326 _get_comp_words_by_ref -n =: cur
1327 case "$cur" in
1328 --*)
1329 __gitcomp "--all --info --man --web"
1330 return
1331 ;;
1332 esac
1333 __git_compute_all_commands
1334 __gitcomp "$__git_all_commands
1335 attributes cli core-tutorial cvs-migration
1336 diffcore gitk glossary hooks ignore modules
1337 repository-layout tutorial tutorial-2
1338 workflows
1339 "
1340}
1341
1342_git_init ()
1343{
1344 local cur
1345 _get_comp_words_by_ref -n =: cur
1346 case "$cur" in
1347 --shared=*)
1348 __gitcomp "
1349 false true umask group all world everybody
1350 " "" "${cur##--shared=}"
1351 return
1352 ;;
1353 --*)
1354 __gitcomp "--quiet --bare --template= --shared --shared="
1355 return
1356 ;;
1357 esac
1358 COMPREPLY=()
1359}
1360
1361_git_ls_files ()
1362{
1363 __git_has_doubledash && return
1364
1365 local cur
1366 _get_comp_words_by_ref -n =: cur
1367 case "$cur" in
1368 --*)
1369 __gitcomp "--cached --deleted --modified --others --ignored
1370 --stage --directory --no-empty-directory --unmerged
1371 --killed --exclude= --exclude-from=
1372 --exclude-per-directory= --exclude-standard
1373 --error-unmatch --with-tree= --full-name
1374 --abbrev --ignored --exclude-per-directory
1375 "
1376 return
1377 ;;
1378 esac
1379 COMPREPLY=()
1380}
1381
1382_git_ls_remote ()
1383{
1384 __gitcomp "$(__git_remotes)"
1385}
1386
1387_git_ls_tree ()
1388{
1389 __git_complete_file
1390}
1391
1392# Options that go well for log, shortlog and gitk
1393__git_log_common_options="
1394 --not --all
1395 --branches --tags --remotes
1396 --first-parent --merges --no-merges
1397 --max-count=
1398 --max-age= --since= --after=
1399 --min-age= --until= --before=
1400"
1401# Options that go well for log and gitk (not shortlog)
1402__git_log_gitk_options="
1403 --dense --sparse --full-history
1404 --simplify-merges --simplify-by-decoration
1405 --left-right
1406"
1407# Options that go well for log and shortlog (not gitk)
1408__git_log_shortlog_options="
1409 --author= --committer= --grep=
1410 --all-match
1411"
1412
1413__git_log_pretty_formats="oneline short medium full fuller email raw format:"
1414__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1415
1416_git_log ()
1417{
1418 __git_has_doubledash && return
1419
1420 local g="$(git rev-parse --git-dir 2>/dev/null)"
1421 local merge=""
1422 if [ -f "$g/MERGE_HEAD" ]; then
1423 merge="--merge"
1424 fi
1425 local cur
1426 _get_comp_words_by_ref -n =: cur
1427 case "$cur" in
1428 --pretty=*)
1429 __gitcomp "$__git_log_pretty_formats
1430 " "" "${cur##--pretty=}"
1431 return
1432 ;;
1433 --format=*)
1434 __gitcomp "$__git_log_pretty_formats
1435 " "" "${cur##--format=}"
1436 return
1437 ;;
1438 --date=*)
1439 __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1440 return
1441 ;;
1442 --decorate=*)
1443 __gitcomp "long short" "" "${cur##--decorate=}"
1444 return
1445 ;;
1446 --*)
1447 __gitcomp "
1448 $__git_log_common_options
1449 $__git_log_shortlog_options
1450 $__git_log_gitk_options
1451 --root --topo-order --date-order --reverse
1452 --follow --full-diff
1453 --abbrev-commit --abbrev=
1454 --relative-date --date=
1455 --pretty= --format= --oneline
1456 --cherry-pick
1457 --graph
1458 --decorate --decorate=
1459 --walk-reflogs
1460 --parents --children
1461 $merge
1462 $__git_diff_common_options
1463 --pickaxe-all --pickaxe-regex
1464 "
1465 return
1466 ;;
1467 esac
1468 __git_complete_revlist
1469}
1470
1471__git_merge_options="
1472 --no-commit --no-stat --log --no-log --squash --strategy
1473 --commit --stat --no-squash --ff --no-ff --ff-only
1474"
1475
1476_git_merge ()
1477{
1478 __git_complete_strategy && return
1479
1480 local cur
1481 _get_comp_words_by_ref -n =: cur
1482 case "$cur" in
1483 --*)
1484 __gitcomp "$__git_merge_options"
1485 return
1486 esac
1487 __gitcomp "$(__git_refs)"
1488}
1489
1490_git_mergetool ()
1491{
1492 local cur
1493 _get_comp_words_by_ref -n =: cur
1494 case "$cur" in
1495 --tool=*)
1496 __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1497 return
1498 ;;
1499 --*)
1500 __gitcomp "--tool="
1501 return
1502 ;;
1503 esac
1504 COMPREPLY=()
1505}
1506
1507_git_merge_base ()
1508{
1509 __gitcomp "$(__git_refs)"
1510}
1511
1512_git_mv ()
1513{
1514 local cur
1515 _get_comp_words_by_ref -n =: cur
1516 case "$cur" in
1517 --*)
1518 __gitcomp "--dry-run"
1519 return
1520 ;;
1521 esac
1522 COMPREPLY=()
1523}
1524
1525_git_name_rev ()
1526{
1527 __gitcomp "--tags --all --stdin"
1528}
1529
1530_git_notes ()
1531{
1532 local subcommands="edit show"
1533 local words cword
1534 _get_comp_words_by_ref -n =: words cword
1535 if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
1536 __gitcomp "$subcommands"
1537 return
1538 fi
1539
1540 case "${words[cword-1]}" in
1541 -m|-F)
1542 COMPREPLY=()
1543 ;;
1544 *)
1545 __gitcomp "$(__git_refs)"
1546 ;;
1547 esac
1548}
1549
1550_git_pull ()
1551{
1552 __git_complete_strategy && return
1553
1554 local cur
1555 _get_comp_words_by_ref -n =: cur
1556 case "$cur" in
1557 --*)
1558 __gitcomp "
1559 --rebase --no-rebase
1560 $__git_merge_options
1561 $__git_fetch_options
1562 "
1563 return
1564 ;;
1565 esac
1566 __git_complete_remote_or_refspec
1567}
1568
1569_git_push ()
1570{
1571 local cur prev
1572 _get_comp_words_by_ref -n =: cur prev
1573 case "$prev" in
1574 --repo)
1575 __gitcomp "$(__git_remotes)"
1576 return
1577 esac
1578 case "$cur" in
1579 --repo=*)
1580 __gitcomp "$(__git_remotes)" "" "${cur##--repo=}"
1581 return
1582 ;;
1583 --*)
1584 __gitcomp "
1585 --all --mirror --tags --dry-run --force --verbose
1586 --receive-pack= --repo=
1587 "
1588 return
1589 ;;
1590 esac
1591 __git_complete_remote_or_refspec
1592}
1593
1594_git_rebase ()
1595{
1596 local dir="$(__gitdir)"
1597 local cur
1598 _get_comp_words_by_ref -n =: cur
1599 if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1600 __gitcomp "--continue --skip --abort"
1601 return
1602 fi
1603 __git_complete_strategy && return
1604 case "$cur" in
1605 --whitespace=*)
1606 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1607 return
1608 ;;
1609 --*)
1610 __gitcomp "
1611 --onto --merge --strategy --interactive
1612 --preserve-merges --stat --no-stat
1613 --committer-date-is-author-date --ignore-date
1614 --ignore-whitespace --whitespace=
1615 --autosquash
1616 "
1617
1618 return
1619 esac
1620 __gitcomp "$(__git_refs)"
1621}
1622
1623__git_send_email_confirm_options="always never auto cc compose"
1624__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1625
1626_git_send_email ()
1627{
1628 local cur
1629 _get_comp_words_by_ref -n =: cur
1630 case "$cur" in
1631 --confirm=*)
1632 __gitcomp "
1633 $__git_send_email_confirm_options
1634 " "" "${cur##--confirm=}"
1635 return
1636 ;;
1637 --suppress-cc=*)
1638 __gitcomp "
1639 $__git_send_email_suppresscc_options
1640 " "" "${cur##--suppress-cc=}"
1641
1642 return
1643 ;;
1644 --smtp-encryption=*)
1645 __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
1646 return
1647 ;;
1648 --*)
1649 __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1650 --compose --confirm= --dry-run --envelope-sender
1651 --from --identity
1652 --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1653 --no-suppress-from --no-thread --quiet
1654 --signed-off-by-cc --smtp-pass --smtp-server
1655 --smtp-server-port --smtp-encryption= --smtp-user
1656 --subject --suppress-cc= --suppress-from --thread --to
1657 --validate --no-validate"
1658 return
1659 ;;
1660 esac
1661 COMPREPLY=()
1662}
1663
1664_git_stage ()
1665{
1666 _git_add
1667}
1668
1669__git_config_get_set_variables ()
1670{
1671 local words cword
1672 _get_comp_words_by_ref -n =: words cword
1673 local prevword word config_file= c=$cword
1674 while [ $c -gt 1 ]; do
1675 word="${words[c]}"
1676 case "$word" in
1677 --global|--system|--file=*)
1678 config_file="$word"
1679 break
1680 ;;
1681 -f|--file)
1682 config_file="$word $prevword"
1683 break
1684 ;;
1685 esac
1686 prevword=$word
1687 c=$((--c))
1688 done
1689
1690 git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1691 while read line
1692 do
1693 case "$line" in
1694 *.*=*)
1695 echo "${line/=*/}"
1696 ;;
1697 esac
1698 done
1699}
1700
1701_git_config ()
1702{
1703 local cur prev
1704 _get_comp_words_by_ref -n =: cur prev
1705 case "$prev" in
1706 branch.*.remote)
1707 __gitcomp "$(__git_remotes)"
1708 return
1709 ;;
1710 branch.*.merge)
1711 __gitcomp "$(__git_refs)"
1712 return
1713 ;;
1714 remote.*.fetch)
1715 local remote="${prev#remote.}"
1716 remote="${remote%.fetch}"
1717 __gitcomp "$(__git_refs_remotes "$remote")"
1718 return
1719 ;;
1720 remote.*.push)
1721 local remote="${prev#remote.}"
1722 remote="${remote%.push}"
1723 __gitcomp "$(git --git-dir="$(__gitdir)" \
1724 for-each-ref --format='%(refname):%(refname)' \
1725 refs/heads)"
1726 return
1727 ;;
1728 pull.twohead|pull.octopus)
1729 __git_compute_merge_strategies
1730 __gitcomp "$__git_merge_strategies"
1731 return
1732 ;;
1733 color.branch|color.diff|color.interactive|\
1734 color.showbranch|color.status|color.ui)
1735 __gitcomp "always never auto"
1736 return
1737 ;;
1738 color.pager)
1739 __gitcomp "false true"
1740 return
1741 ;;
1742 color.*.*)
1743 __gitcomp "
1744 normal black red green yellow blue magenta cyan white
1745 bold dim ul blink reverse
1746 "
1747 return
1748 ;;
1749 help.format)
1750 __gitcomp "man info web html"
1751 return
1752 ;;
1753 log.date)
1754 __gitcomp "$__git_log_date_formats"
1755 return
1756 ;;
1757 sendemail.aliasesfiletype)
1758 __gitcomp "mutt mailrc pine elm gnus"
1759 return
1760 ;;
1761 sendemail.confirm)
1762 __gitcomp "$__git_send_email_confirm_options"
1763 return
1764 ;;
1765 sendemail.suppresscc)
1766 __gitcomp "$__git_send_email_suppresscc_options"
1767 return
1768 ;;
1769 --get|--get-all|--unset|--unset-all)
1770 __gitcomp "$(__git_config_get_set_variables)"
1771 return
1772 ;;
1773 *.*)
1774 COMPREPLY=()
1775 return
1776 ;;
1777 esac
1778 case "$cur" in
1779 --*)
1780 __gitcomp "
1781 --global --system --file=
1782 --list --replace-all
1783 --get --get-all --get-regexp
1784 --add --unset --unset-all
1785 --remove-section --rename-section
1786 "
1787 return
1788 ;;
1789 branch.*.*)
1790 local pfx="${cur%.*}."
1791 cur="${cur##*.}"
1792 __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur"
1793 return
1794 ;;
1795 branch.*)
1796 local pfx="${cur%.*}."
1797 cur="${cur#*.}"
1798 __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1799 return
1800 ;;
1801 guitool.*.*)
1802 local pfx="${cur%.*}."
1803 cur="${cur##*.}"
1804 __gitcomp "
1805 argprompt cmd confirm needsfile noconsole norescan
1806 prompt revprompt revunmerged title
1807 " "$pfx" "$cur"
1808 return
1809 ;;
1810 difftool.*.*)
1811 local pfx="${cur%.*}."
1812 cur="${cur##*.}"
1813 __gitcomp "cmd path" "$pfx" "$cur"
1814 return
1815 ;;
1816 man.*.*)
1817 local pfx="${cur%.*}."
1818 cur="${cur##*.}"
1819 __gitcomp "cmd path" "$pfx" "$cur"
1820 return
1821 ;;
1822 mergetool.*.*)
1823 local pfx="${cur%.*}."
1824 cur="${cur##*.}"
1825 __gitcomp "cmd path trustExitCode" "$pfx" "$cur"
1826 return
1827 ;;
1828 pager.*)
1829 local pfx="${cur%.*}."
1830 cur="${cur#*.}"
1831 __git_compute_all_commands
1832 __gitcomp "$__git_all_commands" "$pfx" "$cur"
1833 return
1834 ;;
1835 remote.*.*)
1836 local pfx="${cur%.*}."
1837 cur="${cur##*.}"
1838 __gitcomp "
1839 url proxy fetch push mirror skipDefaultUpdate
1840 receivepack uploadpack tagopt pushurl
1841 " "$pfx" "$cur"
1842 return
1843 ;;
1844 remote.*)
1845 local pfx="${cur%.*}."
1846 cur="${cur#*.}"
1847 __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1848 return
1849 ;;
1850 url.*.*)
1851 local pfx="${cur%.*}."
1852 cur="${cur##*.}"
1853 __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur"
1854 return
1855 ;;
1856 esac
1857 __gitcomp "
1858 add.ignore-errors
1859 alias.
1860 apply.ignorewhitespace
1861 apply.whitespace
1862 branch.autosetupmerge
1863 branch.autosetuprebase
1864 clean.requireForce
1865 color.branch
1866 color.branch.current
1867 color.branch.local
1868 color.branch.plain
1869 color.branch.remote
1870 color.diff
1871 color.diff.commit
1872 color.diff.frag
1873 color.diff.meta
1874 color.diff.new
1875 color.diff.old
1876 color.diff.plain
1877 color.diff.whitespace
1878 color.grep
1879 color.grep.external
1880 color.grep.match
1881 color.interactive
1882 color.interactive.header
1883 color.interactive.help
1884 color.interactive.prompt
1885 color.pager
1886 color.showbranch
1887 color.status
1888 color.status.added
1889 color.status.changed
1890 color.status.header
1891 color.status.nobranch
1892 color.status.untracked
1893 color.status.updated
1894 color.ui
1895 commit.template
1896 core.autocrlf
1897 core.bare
1898 core.compression
1899 core.createObject
1900 core.deltaBaseCacheLimit
1901 core.editor
1902 core.excludesfile
1903 core.fileMode
1904 core.fsyncobjectfiles
1905 core.gitProxy
1906 core.ignoreCygwinFSTricks
1907 core.ignoreStat
1908 core.logAllRefUpdates
1909 core.loosecompression
1910 core.packedGitLimit
1911 core.packedGitWindowSize
1912 core.pager
1913 core.preferSymlinkRefs
1914 core.preloadindex
1915 core.quotepath
1916 core.repositoryFormatVersion
1917 core.safecrlf
1918 core.sharedRepository
1919 core.symlinks
1920 core.trustctime
1921 core.warnAmbiguousRefs
1922 core.whitespace
1923 core.worktree
1924 diff.autorefreshindex
1925 diff.external
1926 diff.mnemonicprefix
1927 diff.renameLimit
1928 diff.renameLimit.
1929 diff.renames
1930 diff.suppressBlankEmpty
1931 diff.tool
1932 diff.wordRegex
1933 difftool.
1934 difftool.prompt
1935 fetch.unpackLimit
1936 format.attach
1937 format.cc
1938 format.headers
1939 format.numbered
1940 format.pretty
1941 format.signature
1942 format.signoff
1943 format.subjectprefix
1944 format.suffix
1945 format.thread
1946 gc.aggressiveWindow
1947 gc.auto
1948 gc.autopacklimit
1949 gc.packrefs
1950 gc.pruneexpire
1951 gc.reflogexpire
1952 gc.reflogexpireunreachable
1953 gc.rerereresolved
1954 gc.rerereunresolved
1955 gitcvs.allbinary
1956 gitcvs.commitmsgannotation
1957 gitcvs.dbTableNamePrefix
1958 gitcvs.dbdriver
1959 gitcvs.dbname
1960 gitcvs.dbpass
1961 gitcvs.dbuser
1962 gitcvs.enabled
1963 gitcvs.logfile
1964 gitcvs.usecrlfattr
1965 guitool.
1966 gui.blamehistoryctx
1967 gui.commitmsgwidth
1968 gui.copyblamethreshold
1969 gui.diffcontext
1970 gui.encoding
1971 gui.fastcopyblame
1972 gui.matchtrackingbranch
1973 gui.newbranchtemplate
1974 gui.pruneduringfetch
1975 gui.spellingdictionary
1976 gui.trustmtime
1977 help.autocorrect
1978 help.browser
1979 help.format
1980 http.lowSpeedLimit
1981 http.lowSpeedTime
1982 http.maxRequests
1983 http.noEPSV
1984 http.proxy
1985 http.sslCAInfo
1986 http.sslCAPath
1987 http.sslCert
1988 http.sslKey
1989 http.sslVerify
1990 i18n.commitEncoding
1991 i18n.logOutputEncoding
1992 imap.folder
1993 imap.host
1994 imap.pass
1995 imap.port
1996 imap.preformattedHTML
1997 imap.sslverify
1998 imap.tunnel
1999 imap.user
2000 instaweb.browser
2001 instaweb.httpd
2002 instaweb.local
2003 instaweb.modulepath
2004 instaweb.port
2005 interactive.singlekey
2006 log.date
2007 log.showroot
2008 mailmap.file
2009 man.
2010 man.viewer
2011 merge.conflictstyle
2012 merge.log
2013 merge.renameLimit
2014 merge.stat
2015 merge.tool
2016 merge.verbosity
2017 mergetool.
2018 mergetool.keepBackup
2019 mergetool.prompt
2020 pack.compression
2021 pack.deltaCacheLimit
2022 pack.deltaCacheSize
2023 pack.depth
2024 pack.indexVersion
2025 pack.packSizeLimit
2026 pack.threads
2027 pack.window
2028 pack.windowMemory
2029 pager.
2030 pull.octopus
2031 pull.twohead
2032 push.default
2033 rebase.stat
2034 receive.denyCurrentBranch
2035 receive.denyDeletes
2036 receive.denyNonFastForwards
2037 receive.fsckObjects
2038 receive.unpackLimit
2039 repack.usedeltabaseoffset
2040 rerere.autoupdate
2041 rerere.enabled
2042 sendemail.aliasesfile
2043 sendemail.aliasesfiletype
2044 sendemail.bcc
2045 sendemail.cc
2046 sendemail.cccmd
2047 sendemail.chainreplyto
2048 sendemail.confirm
2049 sendemail.envelopesender
2050 sendemail.multiedit
2051 sendemail.signedoffbycc
2052 sendemail.smtpencryption
2053 sendemail.smtppass
2054 sendemail.smtpserver
2055 sendemail.smtpserverport
2056 sendemail.smtpuser
2057 sendemail.suppresscc
2058 sendemail.suppressfrom
2059 sendemail.thread
2060 sendemail.to
2061 sendemail.validate
2062 showbranch.default
2063 status.relativePaths
2064 status.showUntrackedFiles
2065 tar.umask
2066 transfer.unpackLimit
2067 url.
2068 user.email
2069 user.name
2070 user.signingkey
2071 web.browser
2072 branch. remote.
2073 "
2074}
2075
2076_git_remote ()
2077{
2078 local subcommands="add rename rm show prune update set-head"
2079 local subcommand="$(__git_find_on_cmdline "$subcommands")"
2080 if [ -z "$subcommand" ]; then
2081 __gitcomp "$subcommands"
2082 return
2083 fi
2084
2085 case "$subcommand" in
2086 rename|rm|show|prune)
2087 __gitcomp "$(__git_remotes)"
2088 ;;
2089 update)
2090 local i c='' IFS=$'\n'
2091 for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
2092 i="${i#remotes.}"
2093 c="$c ${i/ */}"
2094 done
2095 __gitcomp "$c"
2096 ;;
2097 *)
2098 COMPREPLY=()
2099 ;;
2100 esac
2101}
2102
2103_git_replace ()
2104{
2105 __gitcomp "$(__git_refs)"
2106}
2107
2108_git_reset ()
2109{
2110 __git_has_doubledash && return
2111
2112 local cur
2113 _get_comp_words_by_ref -n =: cur
2114 case "$cur" in
2115 --*)
2116 __gitcomp "--merge --mixed --hard --soft --patch"
2117 return
2118 ;;
2119 esac
2120 __gitcomp "$(__git_refs)"
2121}
2122
2123_git_revert ()
2124{
2125 local cur
2126 _get_comp_words_by_ref -n =: cur
2127 case "$cur" in
2128 --*)
2129 __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
2130 return
2131 ;;
2132 esac
2133 __gitcomp "$(__git_refs)"
2134}
2135
2136_git_rm ()
2137{
2138 __git_has_doubledash && return
2139
2140 local cur
2141 _get_comp_words_by_ref -n =: cur
2142 case "$cur" in
2143 --*)
2144 __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
2145 return
2146 ;;
2147 esac
2148 COMPREPLY=()
2149}
2150
2151_git_shortlog ()
2152{
2153 __git_has_doubledash && return
2154
2155 local cur
2156 _get_comp_words_by_ref -n =: cur
2157 case "$cur" in
2158 --*)
2159 __gitcomp "
2160 $__git_log_common_options
2161 $__git_log_shortlog_options
2162 --numbered --summary
2163 "
2164 return
2165 ;;
2166 esac
2167 __git_complete_revlist
2168}
2169
2170_git_show ()
2171{
2172 __git_has_doubledash && return
2173
2174 local cur
2175 _get_comp_words_by_ref -n =: cur
2176 case "$cur" in
2177 --pretty=*)
2178 __gitcomp "$__git_log_pretty_formats
2179 " "" "${cur##--pretty=}"
2180 return
2181 ;;
2182 --format=*)
2183 __gitcomp "$__git_log_pretty_formats
2184 " "" "${cur##--format=}"
2185 return
2186 ;;
2187 --*)
2188 __gitcomp "--pretty= --format= --abbrev-commit --oneline
2189 $__git_diff_common_options
2190 "
2191 return
2192 ;;
2193 esac
2194 __git_complete_file
2195}
2196
2197_git_show_branch ()
2198{
2199 local cur
2200 _get_comp_words_by_ref -n =: cur
2201 case "$cur" in
2202 --*)
2203 __gitcomp "
2204 --all --remotes --topo-order --current --more=
2205 --list --independent --merge-base --no-name
2206 --color --no-color
2207 --sha1-name --sparse --topics --reflog
2208 "
2209 return
2210 ;;
2211 esac
2212 __git_complete_revlist
2213}
2214
2215_git_stash ()
2216{
2217 local cur
2218 _get_comp_words_by_ref -n =: cur
2219 local save_opts='--keep-index --no-keep-index --quiet --patch'
2220 local subcommands='save list show apply clear drop pop create branch'
2221 local subcommand="$(__git_find_on_cmdline "$subcommands")"
2222 if [ -z "$subcommand" ]; then
2223 case "$cur" in
2224 --*)
2225 __gitcomp "$save_opts"
2226 ;;
2227 *)
2228 if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
2229 __gitcomp "$subcommands"
2230 else
2231 COMPREPLY=()
2232 fi
2233 ;;
2234 esac
2235 else
2236 case "$subcommand,$cur" in
2237 save,--*)
2238 __gitcomp "$save_opts"
2239 ;;
2240 apply,--*|pop,--*)
2241 __gitcomp "--index --quiet"
2242 ;;
2243 show,--*|drop,--*|branch,--*)
2244 COMPREPLY=()
2245 ;;
2246 show,*|apply,*|drop,*|pop,*|branch,*)
2247 __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
2248 | sed -n -e 's/:.*//p')"
2249 ;;
2250 *)
2251 COMPREPLY=()
2252 ;;
2253 esac
2254 fi
2255}
2256
2257_git_submodule ()
2258{
2259 __git_has_doubledash && return
2260
2261 local subcommands="add status init update summary foreach sync"
2262 if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
2263 local cur
2264 _get_comp_words_by_ref -n =: cur
2265 case "$cur" in
2266 --*)
2267 __gitcomp "--quiet --cached"
2268 ;;
2269 *)
2270 __gitcomp "$subcommands"
2271 ;;
2272 esac
2273 return
2274 fi
2275}
2276
2277_git_svn ()
2278{
2279 local subcommands="
2280 init fetch clone rebase dcommit log find-rev
2281 set-tree commit-diff info create-ignore propget
2282 proplist show-ignore show-externals branch tag blame
2283 migrate mkdirs reset gc
2284 "
2285 local subcommand="$(__git_find_on_cmdline "$subcommands")"
2286 if [ -z "$subcommand" ]; then
2287 __gitcomp "$subcommands"
2288 else
2289 local remote_opts="--username= --config-dir= --no-auth-cache"
2290 local fc_opts="
2291 --follow-parent --authors-file= --repack=
2292 --no-metadata --use-svm-props --use-svnsync-props
2293 --log-window-size= --no-checkout --quiet
2294 --repack-flags --use-log-author --localtime
2295 --ignore-paths= $remote_opts
2296 "
2297 local init_opts="
2298 --template= --shared= --trunk= --tags=
2299 --branches= --stdlayout --minimize-url
2300 --no-metadata --use-svm-props --use-svnsync-props
2301 --rewrite-root= --prefix= --use-log-author
2302 --add-author-from $remote_opts
2303 "
2304 local cmt_opts="
2305 --edit --rmdir --find-copies-harder --copy-similarity=
2306 "
2307
2308 local cur
2309 _get_comp_words_by_ref -n =: cur
2310 case "$subcommand,$cur" in
2311 fetch,--*)
2312 __gitcomp "--revision= --fetch-all $fc_opts"
2313 ;;
2314 clone,--*)
2315 __gitcomp "--revision= $fc_opts $init_opts"
2316 ;;
2317 init,--*)
2318 __gitcomp "$init_opts"
2319 ;;
2320 dcommit,--*)
2321 __gitcomp "
2322 --merge --strategy= --verbose --dry-run
2323 --fetch-all --no-rebase --commit-url
2324 --revision $cmt_opts $fc_opts
2325 "
2326 ;;
2327 set-tree,--*)
2328 __gitcomp "--stdin $cmt_opts $fc_opts"
2329 ;;
2330 create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
2331 show-externals,--*|mkdirs,--*)
2332 __gitcomp "--revision="
2333 ;;
2334 log,--*)
2335 __gitcomp "
2336 --limit= --revision= --verbose --incremental
2337 --oneline --show-commit --non-recursive
2338 --authors-file= --color
2339 "
2340 ;;
2341 rebase,--*)
2342 __gitcomp "
2343 --merge --verbose --strategy= --local
2344 --fetch-all --dry-run $fc_opts
2345 "
2346 ;;
2347 commit-diff,--*)
2348 __gitcomp "--message= --file= --revision= $cmt_opts"
2349 ;;
2350 info,--*)
2351 __gitcomp "--url"
2352 ;;
2353 branch,--*)
2354 __gitcomp "--dry-run --message --tag"
2355 ;;
2356 tag,--*)
2357 __gitcomp "--dry-run --message"
2358 ;;
2359 blame,--*)
2360 __gitcomp "--git-format"
2361 ;;
2362 migrate,--*)
2363 __gitcomp "
2364 --config-dir= --ignore-paths= --minimize
2365 --no-auth-cache --username=
2366 "
2367 ;;
2368 reset,--*)
2369 __gitcomp "--revision= --parent"
2370 ;;
2371 *)
2372 COMPREPLY=()
2373 ;;
2374 esac
2375 fi
2376}
2377
2378_git_tag ()
2379{
2380 local i c=1 f=0
2381 local words cword prev
2382 _get_comp_words_by_ref -n =: words cword prev
2383 while [ $c -lt $cword ]; do
2384 i="${words[c]}"
2385 case "$i" in
2386 -d|-v)
2387 __gitcomp "$(__git_tags)"
2388 return
2389 ;;
2390 -f)
2391 f=1
2392 ;;
2393 esac
2394 c=$((++c))
2395 done
2396
2397 case "$prev" in
2398 -m|-F)
2399 COMPREPLY=()
2400 ;;
2401 -*|tag)
2402 if [ $f = 1 ]; then
2403 __gitcomp "$(__git_tags)"
2404 else
2405 COMPREPLY=()
2406 fi
2407 ;;
2408 *)
2409 __gitcomp "$(__git_refs)"
2410 ;;
2411 esac
2412}
2413
2414_git_whatchanged ()
2415{
2416 _git_log
2417}
2418
2419_git ()
2420{
2421 local i c=1 command __git_dir
2422
2423 local cur words cword
2424 _get_comp_words_by_ref -n =: cur words cword
2425 while [ $c -lt $cword ]; do
2426 i="${words[c]}"
2427 case "$i" in
2428 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
2429 --bare) __git_dir="." ;;
2430 --version|-p|--paginate) ;;
2431 --help) command="help"; break ;;
2432 *) command="$i"; break ;;
2433 esac
2434 c=$((++c))
2435 done
2436
2437 if [ -z "$command" ]; then
2438 case "$cur" in
2439 --*) __gitcomp "
2440 --paginate
2441 --no-pager
2442 --git-dir=
2443 --bare
2444 --version
2445 --exec-path
2446 --html-path
2447 --work-tree=
2448 --help
2449 "
2450 ;;
2451 *) __git_compute_porcelain_commands
2452 __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2453 esac
2454 return
2455 fi
2456
2457 local completion_func="_git_${command//-/_}"
2458 declare -F $completion_func >/dev/null && $completion_func && return
2459
2460 local expansion=$(__git_aliased_command "$command")
2461 if [ -n "$expansion" ]; then
2462 completion_func="_git_${expansion//-/_}"
2463 declare -F $completion_func >/dev/null && $completion_func
2464 fi
2465}
2466
2467_gitk ()
2468{
2469 __git_has_doubledash && return
2470
2471 local cur
2472 local g="$(__gitdir)"
2473 local merge=""
2474 if [ -f "$g/MERGE_HEAD" ]; then
2475 merge="--merge"
2476 fi
2477 _get_comp_words_by_ref -n =: cur
2478 case "$cur" in
2479 --*)
2480 __gitcomp "
2481 $__git_log_common_options
2482 $__git_log_gitk_options
2483 $merge
2484 "
2485 return
2486 ;;
2487 esac
2488 __git_complete_revlist
2489}
2490
2491complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \
2492 || complete -o default -o nospace -F _git git
2493complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \
2494 || complete -o default -o nospace -F _gitk gitk
2495
2496# The following are necessary only for Cygwin, and only are needed
2497# when the user has tab-completed the executable name and consequently
2498# included the '.exe' suffix.
2499#
2500if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
2501complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
2502 || complete -o default -o nospace -F _git git.exe
2503fi