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