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