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