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