bash completion: Support "divergence from upstream" messages in __git_ps1
[git/git.git] / contrib / completion / git-completion.bash
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
75 case "$COMP_WORDBREAKS" in
76 *:*) : great ;;
77 *) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
78 esac
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 --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
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 }
344
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 }
363
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 }
382
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 }
417
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 }
426
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 }
444
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 }
459
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 }
471
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 }
482
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
501
502 case "$COMP_WORDBREAKS" in
503 *:*) : great ;;
504 *) pfx="$ref:$pfx" ;;
505 esac
506
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 }
530
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 }
550
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 }
622
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 }
640
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 }
652
653 __git_all_commands=
654 __git_compute_all_commands ()
655 {
656 : ${__git_all_commands:=$(__git_list_all_commands)}
657 }
658
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 }
745
746 __git_porcelain_commands=
747 __git_compute_porcelain_commands ()
748 {
749 __git_compute_all_commands
750 : ${__git_porcelain_commands:=$(__git_list_porcelain_commands)}
751 }
752
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 }
765
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 }
787
788 # __git_find_on_cmdline requires 1 argument
789 __git_find_on_cmdline ()
790 {
791 local word subcommand c=1
792
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 }
804
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 }
816
817 __git_whitespacelist="nowarn warn error error-all fix"
818
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 }
842
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 }
863
864 _git_add ()
865 {
866 __git_has_doubledash && return
867
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 }
879
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 }
902
903 _git_bisect ()
904 {
905 __git_has_doubledash && return
906
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 __gitcomp "$subcommands"
911 return
912 fi
913
914 case "$subcommand" in
915 bad|good|reset|skip)
916 __gitcomp "$(__git_refs)"
917 ;;
918 *)
919 COMPREPLY=()
920 ;;
921 esac
922 }
923
924 _git_branch ()
925 {
926 local i c=1 only_local_ref="n" has_r="n"
927
928 while [ $c -lt $COMP_CWORD ]; do
929 i="${COMP_WORDS[c]}"
930 case "$i" in
931 -d|-m) only_local_ref="y" ;;
932 -r) has_r="y" ;;
933 esac
934 c=$((++c))
935 done
936
937 case "${COMP_WORDS[COMP_CWORD]}" in
938 --*)
939 __gitcomp "
940 --color --no-color --verbose --abbrev= --no-abbrev
941 --track --no-track --contains --merged --no-merged
942 --set-upstream
943 "
944 ;;
945 *)
946 if [ $only_local_ref = "y" -a $has_r = "n" ]; then
947 __gitcomp "$(__git_heads)"
948 else
949 __gitcomp "$(__git_refs)"
950 fi
951 ;;
952 esac
953 }
954
955 _git_bundle ()
956 {
957 local cmd="${COMP_WORDS[2]}"
958 case "$COMP_CWORD" in
959 2)
960 __gitcomp "create list-heads verify unbundle"
961 ;;
962 3)
963 # looking for a file
964 ;;
965 *)
966 case "$cmd" in
967 create)
968 __git_complete_revlist
969 ;;
970 esac
971 ;;
972 esac
973 }
974
975 _git_checkout ()
976 {
977 __git_has_doubledash && return
978
979 local cur="${COMP_WORDS[COMP_CWORD]}"
980 case "$cur" in
981 --conflict=*)
982 __gitcomp "diff3 merge" "" "${cur##--conflict=}"
983 ;;
984 --*)
985 __gitcomp "
986 --quiet --ours --theirs --track --no-track --merge
987 --conflict= --patch
988 "
989 ;;
990 *)
991 __gitcomp "$(__git_refs)"
992 ;;
993 esac
994 }
995
996 _git_cherry ()
997 {
998 __gitcomp "$(__git_refs)"
999 }
1000
1001 _git_cherry_pick ()
1002 {
1003 local cur="${COMP_WORDS[COMP_CWORD]}"
1004 case "$cur" in
1005 --*)
1006 __gitcomp "--edit --no-commit"
1007 ;;
1008 *)
1009 __gitcomp "$(__git_refs)"
1010 ;;
1011 esac
1012 }
1013
1014 _git_clean ()
1015 {
1016 __git_has_doubledash && return
1017
1018 local cur="${COMP_WORDS[COMP_CWORD]}"
1019 case "$cur" in
1020 --*)
1021 __gitcomp "--dry-run --quiet"
1022 return
1023 ;;
1024 esac
1025 COMPREPLY=()
1026 }
1027
1028 _git_clone ()
1029 {
1030 local cur="${COMP_WORDS[COMP_CWORD]}"
1031 case "$cur" in
1032 --*)
1033 __gitcomp "
1034 --local
1035 --no-hardlinks
1036 --shared
1037 --reference
1038 --quiet
1039 --no-checkout
1040 --bare
1041 --mirror
1042 --origin
1043 --upload-pack
1044 --template=
1045 --depth
1046 "
1047 return
1048 ;;
1049 esac
1050 COMPREPLY=()
1051 }
1052
1053 _git_commit ()
1054 {
1055 __git_has_doubledash && return
1056
1057 local cur="${COMP_WORDS[COMP_CWORD]}"
1058 case "$cur" in
1059 --cleanup=*)
1060 __gitcomp "default strip verbatim whitespace
1061 " "" "${cur##--cleanup=}"
1062 return
1063 ;;
1064 --reuse-message=*)
1065 __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
1066 return
1067 ;;
1068 --reedit-message=*)
1069 __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
1070 return
1071 ;;
1072 --untracked-files=*)
1073 __gitcomp "all no normal" "" "${cur##--untracked-files=}"
1074 return
1075 ;;
1076 --*)
1077 __gitcomp "
1078 --all --author= --signoff --verify --no-verify
1079 --edit --amend --include --only --interactive
1080 --dry-run --reuse-message= --reedit-message=
1081 --reset-author --file= --message= --template=
1082 --cleanup= --untracked-files --untracked-files=
1083 --verbose --quiet
1084 "
1085 return
1086 esac
1087 COMPREPLY=()
1088 }
1089
1090 _git_describe ()
1091 {
1092 local cur="${COMP_WORDS[COMP_CWORD]}"
1093 case "$cur" in
1094 --*)
1095 __gitcomp "
1096 --all --tags --contains --abbrev= --candidates=
1097 --exact-match --debug --long --match --always
1098 "
1099 return
1100 esac
1101 __gitcomp "$(__git_refs)"
1102 }
1103
1104 __git_diff_common_options="--stat --numstat --shortstat --summary
1105 --patch-with-stat --name-only --name-status --color
1106 --no-color --color-words --no-renames --check
1107 --full-index --binary --abbrev --diff-filter=
1108 --find-copies-harder
1109 --text --ignore-space-at-eol --ignore-space-change
1110 --ignore-all-space --exit-code --quiet --ext-diff
1111 --no-ext-diff
1112 --no-prefix --src-prefix= --dst-prefix=
1113 --inter-hunk-context=
1114 --patience
1115 --raw
1116 --dirstat --dirstat= --dirstat-by-file
1117 --dirstat-by-file= --cumulative
1118 "
1119
1120 _git_diff ()
1121 {
1122 __git_has_doubledash && return
1123
1124 local cur="${COMP_WORDS[COMP_CWORD]}"
1125 case "$cur" in
1126 --*)
1127 __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1128 --base --ours --theirs
1129 $__git_diff_common_options
1130 "
1131 return
1132 ;;
1133 esac
1134 __git_complete_file
1135 }
1136
1137 __git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
1138 tkdiff vimdiff gvimdiff xxdiff araxis p4merge
1139 "
1140
1141 _git_difftool ()
1142 {
1143 __git_has_doubledash && return
1144
1145 local cur="${COMP_WORDS[COMP_CWORD]}"
1146 case "$cur" in
1147 --tool=*)
1148 __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
1149 return
1150 ;;
1151 --*)
1152 __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1153 --base --ours --theirs
1154 --no-renames --diff-filter= --find-copies-harder
1155 --relative --ignore-submodules
1156 --tool="
1157 return
1158 ;;
1159 esac
1160 __git_complete_file
1161 }
1162
1163 __git_fetch_options="
1164 --quiet --verbose --append --upload-pack --force --keep --depth=
1165 --tags --no-tags --all --prune --dry-run
1166 "
1167
1168 _git_fetch ()
1169 {
1170 local cur="${COMP_WORDS[COMP_CWORD]}"
1171 case "$cur" in
1172 --*)
1173 __gitcomp "$__git_fetch_options"
1174 return
1175 ;;
1176 esac
1177 __git_complete_remote_or_refspec
1178 }
1179
1180 _git_format_patch ()
1181 {
1182 local cur="${COMP_WORDS[COMP_CWORD]}"
1183 case "$cur" in
1184 --thread=*)
1185 __gitcomp "
1186 deep shallow
1187 " "" "${cur##--thread=}"
1188 return
1189 ;;
1190 --*)
1191 __gitcomp "
1192 --stdout --attach --no-attach --thread --thread=
1193 --output-directory
1194 --numbered --start-number
1195 --numbered-files
1196 --keep-subject
1197 --signoff
1198 --in-reply-to= --cc=
1199 --full-index --binary
1200 --not --all
1201 --cover-letter
1202 --no-prefix --src-prefix= --dst-prefix=
1203 --inline --suffix= --ignore-if-in-upstream
1204 --subject-prefix=
1205 "
1206 return
1207 ;;
1208 esac
1209 __git_complete_revlist
1210 }
1211
1212 _git_fsck ()
1213 {
1214 local cur="${COMP_WORDS[COMP_CWORD]}"
1215 case "$cur" in
1216 --*)
1217 __gitcomp "
1218 --tags --root --unreachable --cache --no-reflogs --full
1219 --strict --verbose --lost-found
1220 "
1221 return
1222 ;;
1223 esac
1224 COMPREPLY=()
1225 }
1226
1227 _git_gc ()
1228 {
1229 local cur="${COMP_WORDS[COMP_CWORD]}"
1230 case "$cur" in
1231 --*)
1232 __gitcomp "--prune --aggressive"
1233 return
1234 ;;
1235 esac
1236 COMPREPLY=()
1237 }
1238
1239 _git_gitk ()
1240 {
1241 _gitk
1242 }
1243
1244 _git_grep ()
1245 {
1246 __git_has_doubledash && return
1247
1248 local cur="${COMP_WORDS[COMP_CWORD]}"
1249 case "$cur" in
1250 --*)
1251 __gitcomp "
1252 --cached
1253 --text --ignore-case --word-regexp --invert-match
1254 --full-name
1255 --extended-regexp --basic-regexp --fixed-strings
1256 --files-with-matches --name-only
1257 --files-without-match
1258 --max-depth
1259 --count
1260 --and --or --not --all-match
1261 "
1262 return
1263 ;;
1264 esac
1265
1266 __gitcomp "$(__git_refs)"
1267 }
1268
1269 _git_help ()
1270 {
1271 local cur="${COMP_WORDS[COMP_CWORD]}"
1272 case "$cur" in
1273 --*)
1274 __gitcomp "--all --info --man --web"
1275 return
1276 ;;
1277 esac
1278 __git_compute_all_commands
1279 __gitcomp "$__git_all_commands
1280 attributes cli core-tutorial cvs-migration
1281 diffcore gitk glossary hooks ignore modules
1282 repository-layout tutorial tutorial-2
1283 workflows
1284 "
1285 }
1286
1287 _git_init ()
1288 {
1289 local cur="${COMP_WORDS[COMP_CWORD]}"
1290 case "$cur" in
1291 --shared=*)
1292 __gitcomp "
1293 false true umask group all world everybody
1294 " "" "${cur##--shared=}"
1295 return
1296 ;;
1297 --*)
1298 __gitcomp "--quiet --bare --template= --shared --shared="
1299 return
1300 ;;
1301 esac
1302 COMPREPLY=()
1303 }
1304
1305 _git_ls_files ()
1306 {
1307 __git_has_doubledash && return
1308
1309 local cur="${COMP_WORDS[COMP_CWORD]}"
1310 case "$cur" in
1311 --*)
1312 __gitcomp "--cached --deleted --modified --others --ignored
1313 --stage --directory --no-empty-directory --unmerged
1314 --killed --exclude= --exclude-from=
1315 --exclude-per-directory= --exclude-standard
1316 --error-unmatch --with-tree= --full-name
1317 --abbrev --ignored --exclude-per-directory
1318 "
1319 return
1320 ;;
1321 esac
1322 COMPREPLY=()
1323 }
1324
1325 _git_ls_remote ()
1326 {
1327 __gitcomp "$(__git_remotes)"
1328 }
1329
1330 _git_ls_tree ()
1331 {
1332 __git_complete_file
1333 }
1334
1335 # Options that go well for log, shortlog and gitk
1336 __git_log_common_options="
1337 --not --all
1338 --branches --tags --remotes
1339 --first-parent --merges --no-merges
1340 --max-count=
1341 --max-age= --since= --after=
1342 --min-age= --until= --before=
1343 "
1344 # Options that go well for log and gitk (not shortlog)
1345 __git_log_gitk_options="
1346 --dense --sparse --full-history
1347 --simplify-merges --simplify-by-decoration
1348 --left-right
1349 "
1350 # Options that go well for log and shortlog (not gitk)
1351 __git_log_shortlog_options="
1352 --author= --committer= --grep=
1353 --all-match
1354 "
1355
1356 __git_log_pretty_formats="oneline short medium full fuller email raw format:"
1357 __git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1358
1359 _git_log ()
1360 {
1361 __git_has_doubledash && return
1362
1363 local cur="${COMP_WORDS[COMP_CWORD]}"
1364 local g="$(git rev-parse --git-dir 2>/dev/null)"
1365 local merge=""
1366 if [ -f "$g/MERGE_HEAD" ]; then
1367 merge="--merge"
1368 fi
1369 case "$cur" in
1370 --pretty=*)
1371 __gitcomp "$__git_log_pretty_formats
1372 " "" "${cur##--pretty=}"
1373 return
1374 ;;
1375 --format=*)
1376 __gitcomp "$__git_log_pretty_formats
1377 " "" "${cur##--format=}"
1378 return
1379 ;;
1380 --date=*)
1381 __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1382 return
1383 ;;
1384 --decorate=*)
1385 __gitcomp "long short" "" "${cur##--decorate=}"
1386 return
1387 ;;
1388 --*)
1389 __gitcomp "
1390 $__git_log_common_options
1391 $__git_log_shortlog_options
1392 $__git_log_gitk_options
1393 --root --topo-order --date-order --reverse
1394 --follow --full-diff
1395 --abbrev-commit --abbrev=
1396 --relative-date --date=
1397 --pretty= --format= --oneline
1398 --cherry-pick
1399 --graph
1400 --decorate --decorate=
1401 --walk-reflogs
1402 --parents --children
1403 $merge
1404 $__git_diff_common_options
1405 --pickaxe-all --pickaxe-regex
1406 "
1407 return
1408 ;;
1409 esac
1410 __git_complete_revlist
1411 }
1412
1413 __git_merge_options="
1414 --no-commit --no-stat --log --no-log --squash --strategy
1415 --commit --stat --no-squash --ff --no-ff --ff-only
1416 "
1417
1418 _git_merge ()
1419 {
1420 __git_complete_strategy && return
1421
1422 local cur="${COMP_WORDS[COMP_CWORD]}"
1423 case "$cur" in
1424 --*)
1425 __gitcomp "$__git_merge_options"
1426 return
1427 esac
1428 __gitcomp "$(__git_refs)"
1429 }
1430
1431 _git_mergetool ()
1432 {
1433 local cur="${COMP_WORDS[COMP_CWORD]}"
1434 case "$cur" in
1435 --tool=*)
1436 __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1437 return
1438 ;;
1439 --*)
1440 __gitcomp "--tool="
1441 return
1442 ;;
1443 esac
1444 COMPREPLY=()
1445 }
1446
1447 _git_merge_base ()
1448 {
1449 __gitcomp "$(__git_refs)"
1450 }
1451
1452 _git_mv ()
1453 {
1454 local cur="${COMP_WORDS[COMP_CWORD]}"
1455 case "$cur" in
1456 --*)
1457 __gitcomp "--dry-run"
1458 return
1459 ;;
1460 esac
1461 COMPREPLY=()
1462 }
1463
1464 _git_name_rev ()
1465 {
1466 __gitcomp "--tags --all --stdin"
1467 }
1468
1469 _git_notes ()
1470 {
1471 local subcommands="edit show"
1472 if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
1473 __gitcomp "$subcommands"
1474 return
1475 fi
1476
1477 case "${COMP_WORDS[COMP_CWORD-1]}" in
1478 -m|-F)
1479 COMPREPLY=()
1480 ;;
1481 *)
1482 __gitcomp "$(__git_refs)"
1483 ;;
1484 esac
1485 }
1486
1487 _git_pull ()
1488 {
1489 __git_complete_strategy && return
1490
1491 local cur="${COMP_WORDS[COMP_CWORD]}"
1492 case "$cur" in
1493 --*)
1494 __gitcomp "
1495 --rebase --no-rebase
1496 $__git_merge_options
1497 $__git_fetch_options
1498 "
1499 return
1500 ;;
1501 esac
1502 __git_complete_remote_or_refspec
1503 }
1504
1505 _git_push ()
1506 {
1507 local cur="${COMP_WORDS[COMP_CWORD]}"
1508 case "${COMP_WORDS[COMP_CWORD-1]}" in
1509 --repo)
1510 __gitcomp "$(__git_remotes)"
1511 return
1512 esac
1513 case "$cur" in
1514 --repo=*)
1515 __gitcomp "$(__git_remotes)" "" "${cur##--repo=}"
1516 return
1517 ;;
1518 --*)
1519 __gitcomp "
1520 --all --mirror --tags --dry-run --force --verbose
1521 --receive-pack= --repo=
1522 "
1523 return
1524 ;;
1525 esac
1526 __git_complete_remote_or_refspec
1527 }
1528
1529 _git_rebase ()
1530 {
1531 local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
1532 if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1533 __gitcomp "--continue --skip --abort"
1534 return
1535 fi
1536 __git_complete_strategy && return
1537 case "$cur" in
1538 --whitespace=*)
1539 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1540 return
1541 ;;
1542 --*)
1543 __gitcomp "
1544 --onto --merge --strategy --interactive
1545 --preserve-merges --stat --no-stat
1546 --committer-date-is-author-date --ignore-date
1547 --ignore-whitespace --whitespace=
1548 --autosquash
1549 "
1550
1551 return
1552 esac
1553 __gitcomp "$(__git_refs)"
1554 }
1555
1556 __git_send_email_confirm_options="always never auto cc compose"
1557 __git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1558
1559 _git_send_email ()
1560 {
1561 local cur="${COMP_WORDS[COMP_CWORD]}"
1562 case "$cur" in
1563 --confirm=*)
1564 __gitcomp "
1565 $__git_send_email_confirm_options
1566 " "" "${cur##--confirm=}"
1567 return
1568 ;;
1569 --suppress-cc=*)
1570 __gitcomp "
1571 $__git_send_email_suppresscc_options
1572 " "" "${cur##--suppress-cc=}"
1573
1574 return
1575 ;;
1576 --smtp-encryption=*)
1577 __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
1578 return
1579 ;;
1580 --*)
1581 __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1582 --compose --confirm= --dry-run --envelope-sender
1583 --from --identity
1584 --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1585 --no-suppress-from --no-thread --quiet
1586 --signed-off-by-cc --smtp-pass --smtp-server
1587 --smtp-server-port --smtp-encryption= --smtp-user
1588 --subject --suppress-cc= --suppress-from --thread --to
1589 --validate --no-validate"
1590 return
1591 ;;
1592 esac
1593 COMPREPLY=()
1594 }
1595
1596 _git_stage ()
1597 {
1598 _git_add
1599 }
1600
1601 __git_config_get_set_variables ()
1602 {
1603 local prevword word config_file= c=$COMP_CWORD
1604 while [ $c -gt 1 ]; do
1605 word="${COMP_WORDS[c]}"
1606 case "$word" in
1607 --global|--system|--file=*)
1608 config_file="$word"
1609 break
1610 ;;
1611 -f|--file)
1612 config_file="$word $prevword"
1613 break
1614 ;;
1615 esac
1616 prevword=$word
1617 c=$((--c))
1618 done
1619
1620 git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1621 while read line
1622 do
1623 case "$line" in
1624 *.*=*)
1625 echo "${line/=*/}"
1626 ;;
1627 esac
1628 done
1629 }
1630
1631 _git_config ()
1632 {
1633 local cur="${COMP_WORDS[COMP_CWORD]}"
1634 local prv="${COMP_WORDS[COMP_CWORD-1]}"
1635 case "$prv" in
1636 branch.*.remote)
1637 __gitcomp "$(__git_remotes)"
1638 return
1639 ;;
1640 branch.*.merge)
1641 __gitcomp "$(__git_refs)"
1642 return
1643 ;;
1644 remote.*.fetch)
1645 local remote="${prv#remote.}"
1646 remote="${remote%.fetch}"
1647 __gitcomp "$(__git_refs_remotes "$remote")"
1648 return
1649 ;;
1650 remote.*.push)
1651 local remote="${prv#remote.}"
1652 remote="${remote%.push}"
1653 __gitcomp "$(git --git-dir="$(__gitdir)" \
1654 for-each-ref --format='%(refname):%(refname)' \
1655 refs/heads)"
1656 return
1657 ;;
1658 pull.twohead|pull.octopus)
1659 __git_compute_merge_strategies
1660 __gitcomp "$__git_merge_strategies"
1661 return
1662 ;;
1663 color.branch|color.diff|color.interactive|\
1664 color.showbranch|color.status|color.ui)
1665 __gitcomp "always never auto"
1666 return
1667 ;;
1668 color.pager)
1669 __gitcomp "false true"
1670 return
1671 ;;
1672 color.*.*)
1673 __gitcomp "
1674 normal black red green yellow blue magenta cyan white
1675 bold dim ul blink reverse
1676 "
1677 return
1678 ;;
1679 help.format)
1680 __gitcomp "man info web html"
1681 return
1682 ;;
1683 log.date)
1684 __gitcomp "$__git_log_date_formats"
1685 return
1686 ;;
1687 sendemail.aliasesfiletype)
1688 __gitcomp "mutt mailrc pine elm gnus"
1689 return
1690 ;;
1691 sendemail.confirm)
1692 __gitcomp "$__git_send_email_confirm_options"
1693 return
1694 ;;
1695 sendemail.suppresscc)
1696 __gitcomp "$__git_send_email_suppresscc_options"
1697 return
1698 ;;
1699 --get|--get-all|--unset|--unset-all)
1700 __gitcomp "$(__git_config_get_set_variables)"
1701 return
1702 ;;
1703 *.*)
1704 COMPREPLY=()
1705 return
1706 ;;
1707 esac
1708 case "$cur" in
1709 --*)
1710 __gitcomp "
1711 --global --system --file=
1712 --list --replace-all
1713 --get --get-all --get-regexp
1714 --add --unset --unset-all
1715 --remove-section --rename-section
1716 "
1717 return
1718 ;;
1719 branch.*.*)
1720 local pfx="${cur%.*}."
1721 cur="${cur##*.}"
1722 __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur"
1723 return
1724 ;;
1725 branch.*)
1726 local pfx="${cur%.*}."
1727 cur="${cur#*.}"
1728 __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1729 return
1730 ;;
1731 guitool.*.*)
1732 local pfx="${cur%.*}."
1733 cur="${cur##*.}"
1734 __gitcomp "
1735 argprompt cmd confirm needsfile noconsole norescan
1736 prompt revprompt revunmerged title
1737 " "$pfx" "$cur"
1738 return
1739 ;;
1740 difftool.*.*)
1741 local pfx="${cur%.*}."
1742 cur="${cur##*.}"
1743 __gitcomp "cmd path" "$pfx" "$cur"
1744 return
1745 ;;
1746 man.*.*)
1747 local pfx="${cur%.*}."
1748 cur="${cur##*.}"
1749 __gitcomp "cmd path" "$pfx" "$cur"
1750 return
1751 ;;
1752 mergetool.*.*)
1753 local pfx="${cur%.*}."
1754 cur="${cur##*.}"
1755 __gitcomp "cmd path trustExitCode" "$pfx" "$cur"
1756 return
1757 ;;
1758 pager.*)
1759 local pfx="${cur%.*}."
1760 cur="${cur#*.}"
1761 __git_compute_all_commands
1762 __gitcomp "$__git_all_commands" "$pfx" "$cur"
1763 return
1764 ;;
1765 remote.*.*)
1766 local pfx="${cur%.*}."
1767 cur="${cur##*.}"
1768 __gitcomp "
1769 url proxy fetch push mirror skipDefaultUpdate
1770 receivepack uploadpack tagopt pushurl
1771 " "$pfx" "$cur"
1772 return
1773 ;;
1774 remote.*)
1775 local pfx="${cur%.*}."
1776 cur="${cur#*.}"
1777 __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1778 return
1779 ;;
1780 url.*.*)
1781 local pfx="${cur%.*}."
1782 cur="${cur##*.}"
1783 __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur"
1784 return
1785 ;;
1786 esac
1787 __gitcomp "
1788 add.ignore-errors
1789 alias.
1790 apply.ignorewhitespace
1791 apply.whitespace
1792 branch.autosetupmerge
1793 branch.autosetuprebase
1794 clean.requireForce
1795 color.branch
1796 color.branch.current
1797 color.branch.local
1798 color.branch.plain
1799 color.branch.remote
1800 color.diff
1801 color.diff.commit
1802 color.diff.frag
1803 color.diff.meta
1804 color.diff.new
1805 color.diff.old
1806 color.diff.plain
1807 color.diff.whitespace
1808 color.grep
1809 color.grep.external
1810 color.grep.match
1811 color.interactive
1812 color.interactive.header
1813 color.interactive.help
1814 color.interactive.prompt
1815 color.pager
1816 color.showbranch
1817 color.status
1818 color.status.added
1819 color.status.changed
1820 color.status.header
1821 color.status.nobranch
1822 color.status.untracked
1823 color.status.updated
1824 color.ui
1825 commit.template
1826 core.autocrlf
1827 core.bare
1828 core.compression
1829 core.createObject
1830 core.deltaBaseCacheLimit
1831 core.editor
1832 core.excludesfile
1833 core.fileMode
1834 core.fsyncobjectfiles
1835 core.gitProxy
1836 core.ignoreCygwinFSTricks
1837 core.ignoreStat
1838 core.logAllRefUpdates
1839 core.loosecompression
1840 core.packedGitLimit
1841 core.packedGitWindowSize
1842 core.pager
1843 core.preferSymlinkRefs
1844 core.preloadindex
1845 core.quotepath
1846 core.repositoryFormatVersion
1847 core.safecrlf
1848 core.sharedRepository
1849 core.symlinks
1850 core.trustctime
1851 core.warnAmbiguousRefs
1852 core.whitespace
1853 core.worktree
1854 diff.autorefreshindex
1855 diff.external
1856 diff.mnemonicprefix
1857 diff.renameLimit
1858 diff.renameLimit.
1859 diff.renames
1860 diff.suppressBlankEmpty
1861 diff.tool
1862 diff.wordRegex
1863 difftool.
1864 difftool.prompt
1865 fetch.unpackLimit
1866 format.attach
1867 format.cc
1868 format.headers
1869 format.numbered
1870 format.pretty
1871 format.signoff
1872 format.subjectprefix
1873 format.suffix
1874 format.thread
1875 gc.aggressiveWindow
1876 gc.auto
1877 gc.autopacklimit
1878 gc.packrefs
1879 gc.pruneexpire
1880 gc.reflogexpire
1881 gc.reflogexpireunreachable
1882 gc.rerereresolved
1883 gc.rerereunresolved
1884 gitcvs.allbinary
1885 gitcvs.commitmsgannotation
1886 gitcvs.dbTableNamePrefix
1887 gitcvs.dbdriver
1888 gitcvs.dbname
1889 gitcvs.dbpass
1890 gitcvs.dbuser
1891 gitcvs.enabled
1892 gitcvs.logfile
1893 gitcvs.usecrlfattr
1894 guitool.
1895 gui.blamehistoryctx
1896 gui.commitmsgwidth
1897 gui.copyblamethreshold
1898 gui.diffcontext
1899 gui.encoding
1900 gui.fastcopyblame
1901 gui.matchtrackingbranch
1902 gui.newbranchtemplate
1903 gui.pruneduringfetch
1904 gui.spellingdictionary
1905 gui.trustmtime
1906 help.autocorrect
1907 help.browser
1908 help.format
1909 http.lowSpeedLimit
1910 http.lowSpeedTime
1911 http.maxRequests
1912 http.noEPSV
1913 http.proxy
1914 http.sslCAInfo
1915 http.sslCAPath
1916 http.sslCert
1917 http.sslKey
1918 http.sslVerify
1919 i18n.commitEncoding
1920 i18n.logOutputEncoding
1921 imap.folder
1922 imap.host
1923 imap.pass
1924 imap.port
1925 imap.preformattedHTML
1926 imap.sslverify
1927 imap.tunnel
1928 imap.user
1929 instaweb.browser
1930 instaweb.httpd
1931 instaweb.local
1932 instaweb.modulepath
1933 instaweb.port
1934 interactive.singlekey
1935 log.date
1936 log.showroot
1937 mailmap.file
1938 man.
1939 man.viewer
1940 merge.conflictstyle
1941 merge.log
1942 merge.renameLimit
1943 merge.stat
1944 merge.tool
1945 merge.verbosity
1946 mergetool.
1947 mergetool.keepBackup
1948 mergetool.prompt
1949 pack.compression
1950 pack.deltaCacheLimit
1951 pack.deltaCacheSize
1952 pack.depth
1953 pack.indexVersion
1954 pack.packSizeLimit
1955 pack.threads
1956 pack.window
1957 pack.windowMemory
1958 pager.
1959 pull.octopus
1960 pull.twohead
1961 push.default
1962 rebase.stat
1963 receive.denyCurrentBranch
1964 receive.denyDeletes
1965 receive.denyNonFastForwards
1966 receive.fsckObjects
1967 receive.unpackLimit
1968 repack.usedeltabaseoffset
1969 rerere.autoupdate
1970 rerere.enabled
1971 sendemail.aliasesfile
1972 sendemail.aliasesfiletype
1973 sendemail.bcc
1974 sendemail.cc
1975 sendemail.cccmd
1976 sendemail.chainreplyto
1977 sendemail.confirm
1978 sendemail.envelopesender
1979 sendemail.multiedit
1980 sendemail.signedoffbycc
1981 sendemail.smtpencryption
1982 sendemail.smtppass
1983 sendemail.smtpserver
1984 sendemail.smtpserverport
1985 sendemail.smtpuser
1986 sendemail.suppresscc
1987 sendemail.suppressfrom
1988 sendemail.thread
1989 sendemail.to
1990 sendemail.validate
1991 showbranch.default
1992 status.relativePaths
1993 status.showUntrackedFiles
1994 tar.umask
1995 transfer.unpackLimit
1996 url.
1997 user.email
1998 user.name
1999 user.signingkey
2000 web.browser
2001 branch. remote.
2002 "
2003 }
2004
2005 _git_remote ()
2006 {
2007 local subcommands="add rename rm show prune update set-head"
2008 local subcommand="$(__git_find_on_cmdline "$subcommands")"
2009 if [ -z "$subcommand" ]; then
2010 __gitcomp "$subcommands"
2011 return
2012 fi
2013
2014 case "$subcommand" in
2015 rename|rm|show|prune)
2016 __gitcomp "$(__git_remotes)"
2017 ;;
2018 update)
2019 local i c='' IFS=$'\n'
2020 for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
2021 i="${i#remotes.}"
2022 c="$c ${i/ */}"
2023 done
2024 __gitcomp "$c"
2025 ;;
2026 *)
2027 COMPREPLY=()
2028 ;;
2029 esac
2030 }
2031
2032 _git_replace ()
2033 {
2034 __gitcomp "$(__git_refs)"
2035 }
2036
2037 _git_reset ()
2038 {
2039 __git_has_doubledash && return
2040
2041 local cur="${COMP_WORDS[COMP_CWORD]}"
2042 case "$cur" in
2043 --*)
2044 __gitcomp "--merge --mixed --hard --soft --patch"
2045 return
2046 ;;
2047 esac
2048 __gitcomp "$(__git_refs)"
2049 }
2050
2051 _git_revert ()
2052 {
2053 local cur="${COMP_WORDS[COMP_CWORD]}"
2054 case "$cur" in
2055 --*)
2056 __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
2057 return
2058 ;;
2059 esac
2060 __gitcomp "$(__git_refs)"
2061 }
2062
2063 _git_rm ()
2064 {
2065 __git_has_doubledash && return
2066
2067 local cur="${COMP_WORDS[COMP_CWORD]}"
2068 case "$cur" in
2069 --*)
2070 __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
2071 return
2072 ;;
2073 esac
2074 COMPREPLY=()
2075 }
2076
2077 _git_shortlog ()
2078 {
2079 __git_has_doubledash && return
2080
2081 local cur="${COMP_WORDS[COMP_CWORD]}"
2082 case "$cur" in
2083 --*)
2084 __gitcomp "
2085 $__git_log_common_options
2086 $__git_log_shortlog_options
2087 --numbered --summary
2088 "
2089 return
2090 ;;
2091 esac
2092 __git_complete_revlist
2093 }
2094
2095 _git_show ()
2096 {
2097 __git_has_doubledash && return
2098
2099 local cur="${COMP_WORDS[COMP_CWORD]}"
2100 case "$cur" in
2101 --pretty=*)
2102 __gitcomp "$__git_log_pretty_formats
2103 " "" "${cur##--pretty=}"
2104 return
2105 ;;
2106 --format=*)
2107 __gitcomp "$__git_log_pretty_formats
2108 " "" "${cur##--format=}"
2109 return
2110 ;;
2111 --*)
2112 __gitcomp "--pretty= --format= --abbrev-commit --oneline
2113 $__git_diff_common_options
2114 "
2115 return
2116 ;;
2117 esac
2118 __git_complete_file
2119 }
2120
2121 _git_show_branch ()
2122 {
2123 local cur="${COMP_WORDS[COMP_CWORD]}"
2124 case "$cur" in
2125 --*)
2126 __gitcomp "
2127 --all --remotes --topo-order --current --more=
2128 --list --independent --merge-base --no-name
2129 --color --no-color
2130 --sha1-name --sparse --topics --reflog
2131 "
2132 return
2133 ;;
2134 esac
2135 __git_complete_revlist
2136 }
2137
2138 _git_stash ()
2139 {
2140 local cur="${COMP_WORDS[COMP_CWORD]}"
2141 local save_opts='--keep-index --no-keep-index --quiet --patch'
2142 local subcommands='save list show apply clear drop pop create branch'
2143 local subcommand="$(__git_find_on_cmdline "$subcommands")"
2144 if [ -z "$subcommand" ]; then
2145 case "$cur" in
2146 --*)
2147 __gitcomp "$save_opts"
2148 ;;
2149 *)
2150 if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
2151 __gitcomp "$subcommands"
2152 else
2153 COMPREPLY=()
2154 fi
2155 ;;
2156 esac
2157 else
2158 case "$subcommand,$cur" in
2159 save,--*)
2160 __gitcomp "$save_opts"
2161 ;;
2162 apply,--*|pop,--*)
2163 __gitcomp "--index --quiet"
2164 ;;
2165 show,--*|drop,--*|branch,--*)
2166 COMPREPLY=()
2167 ;;
2168 show,*|apply,*|drop,*|pop,*|branch,*)
2169 __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
2170 | sed -n -e 's/:.*//p')"
2171 ;;
2172 *)
2173 COMPREPLY=()
2174 ;;
2175 esac
2176 fi
2177 }
2178
2179 _git_submodule ()
2180 {
2181 __git_has_doubledash && return
2182
2183 local subcommands="add status init update summary foreach sync"
2184 if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
2185 local cur="${COMP_WORDS[COMP_CWORD]}"
2186 case "$cur" in
2187 --*)
2188 __gitcomp "--quiet --cached"
2189 ;;
2190 *)
2191 __gitcomp "$subcommands"
2192 ;;
2193 esac
2194 return
2195 fi
2196 }
2197
2198 _git_svn ()
2199 {
2200 local subcommands="
2201 init fetch clone rebase dcommit log find-rev
2202 set-tree commit-diff info create-ignore propget
2203 proplist show-ignore show-externals branch tag blame
2204 migrate mkdirs reset gc
2205 "
2206 local subcommand="$(__git_find_on_cmdline "$subcommands")"
2207 if [ -z "$subcommand" ]; then
2208 __gitcomp "$subcommands"
2209 else
2210 local remote_opts="--username= --config-dir= --no-auth-cache"
2211 local fc_opts="
2212 --follow-parent --authors-file= --repack=
2213 --no-metadata --use-svm-props --use-svnsync-props
2214 --log-window-size= --no-checkout --quiet
2215 --repack-flags --use-log-author --localtime
2216 --ignore-paths= $remote_opts
2217 "
2218 local init_opts="
2219 --template= --shared= --trunk= --tags=
2220 --branches= --stdlayout --minimize-url
2221 --no-metadata --use-svm-props --use-svnsync-props
2222 --rewrite-root= --prefix= --use-log-author
2223 --add-author-from $remote_opts
2224 "
2225 local cmt_opts="
2226 --edit --rmdir --find-copies-harder --copy-similarity=
2227 "
2228
2229 local cur="${COMP_WORDS[COMP_CWORD]}"
2230 case "$subcommand,$cur" in
2231 fetch,--*)
2232 __gitcomp "--revision= --fetch-all $fc_opts"
2233 ;;
2234 clone,--*)
2235 __gitcomp "--revision= $fc_opts $init_opts"
2236 ;;
2237 init,--*)
2238 __gitcomp "$init_opts"
2239 ;;
2240 dcommit,--*)
2241 __gitcomp "
2242 --merge --strategy= --verbose --dry-run
2243 --fetch-all --no-rebase --commit-url
2244 --revision $cmt_opts $fc_opts
2245 "
2246 ;;
2247 set-tree,--*)
2248 __gitcomp "--stdin $cmt_opts $fc_opts"
2249 ;;
2250 create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
2251 show-externals,--*|mkdirs,--*)
2252 __gitcomp "--revision="
2253 ;;
2254 log,--*)
2255 __gitcomp "
2256 --limit= --revision= --verbose --incremental
2257 --oneline --show-commit --non-recursive
2258 --authors-file= --color
2259 "
2260 ;;
2261 rebase,--*)
2262 __gitcomp "
2263 --merge --verbose --strategy= --local
2264 --fetch-all --dry-run $fc_opts
2265 "
2266 ;;
2267 commit-diff,--*)
2268 __gitcomp "--message= --file= --revision= $cmt_opts"
2269 ;;
2270 info,--*)
2271 __gitcomp "--url"
2272 ;;
2273 branch,--*)
2274 __gitcomp "--dry-run --message --tag"
2275 ;;
2276 tag,--*)
2277 __gitcomp "--dry-run --message"
2278 ;;
2279 blame,--*)
2280 __gitcomp "--git-format"
2281 ;;
2282 migrate,--*)
2283 __gitcomp "
2284 --config-dir= --ignore-paths= --minimize
2285 --no-auth-cache --username=
2286 "
2287 ;;
2288 reset,--*)
2289 __gitcomp "--revision= --parent"
2290 ;;
2291 *)
2292 COMPREPLY=()
2293 ;;
2294 esac
2295 fi
2296 }
2297
2298 _git_tag ()
2299 {
2300 local i c=1 f=0
2301 while [ $c -lt $COMP_CWORD ]; do
2302 i="${COMP_WORDS[c]}"
2303 case "$i" in
2304 -d|-v)
2305 __gitcomp "$(__git_tags)"
2306 return
2307 ;;
2308 -f)
2309 f=1
2310 ;;
2311 esac
2312 c=$((++c))
2313 done
2314
2315 case "${COMP_WORDS[COMP_CWORD-1]}" in
2316 -m|-F)
2317 COMPREPLY=()
2318 ;;
2319 -*|tag)
2320 if [ $f = 1 ]; then
2321 __gitcomp "$(__git_tags)"
2322 else
2323 COMPREPLY=()
2324 fi
2325 ;;
2326 *)
2327 __gitcomp "$(__git_refs)"
2328 ;;
2329 esac
2330 }
2331
2332 _git_whatchanged ()
2333 {
2334 _git_log
2335 }
2336
2337 _git ()
2338 {
2339 local i c=1 command __git_dir
2340
2341 while [ $c -lt $COMP_CWORD ]; do
2342 i="${COMP_WORDS[c]}"
2343 case "$i" in
2344 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
2345 --bare) __git_dir="." ;;
2346 --version|-p|--paginate) ;;
2347 --help) command="help"; break ;;
2348 *) command="$i"; break ;;
2349 esac
2350 c=$((++c))
2351 done
2352
2353 if [ -z "$command" ]; then
2354 case "${COMP_WORDS[COMP_CWORD]}" in
2355 --*) __gitcomp "
2356 --paginate
2357 --no-pager
2358 --git-dir=
2359 --bare
2360 --version
2361 --exec-path
2362 --html-path
2363 --work-tree=
2364 --help
2365 "
2366 ;;
2367 *) __git_compute_porcelain_commands
2368 __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2369 esac
2370 return
2371 fi
2372
2373 local completion_func="_git_${command//-/_}"
2374 declare -F $completion_func >/dev/null && $completion_func && return
2375
2376 local expansion=$(__git_aliased_command "$command")
2377 if [ -n "$expansion" ]; then
2378 completion_func="_git_${expansion//-/_}"
2379 declare -F $completion_func >/dev/null && $completion_func
2380 fi
2381 }
2382
2383 _gitk ()
2384 {
2385 __git_has_doubledash && return
2386
2387 local cur="${COMP_WORDS[COMP_CWORD]}"
2388 local g="$(__gitdir)"
2389 local merge=""
2390 if [ -f "$g/MERGE_HEAD" ]; then
2391 merge="--merge"
2392 fi
2393 case "$cur" in
2394 --*)
2395 __gitcomp "
2396 $__git_log_common_options
2397 $__git_log_gitk_options
2398 $merge
2399 "
2400 return
2401 ;;
2402 esac
2403 __git_complete_revlist
2404 }
2405
2406 complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \
2407 || complete -o default -o nospace -F _git git
2408 complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \
2409 || complete -o default -o nospace -F _gitk gitk
2410
2411 # The following are necessary only for Cygwin, and only are needed
2412 # when the user has tab-completed the executable name and consequently
2413 # included the '.exe' suffix.
2414 #
2415 if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
2416 complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
2417 || complete -o default -o nospace -F _git git.exe
2418 fi