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