git-completion.bash 35.9 KB
Newer Older
1
#!bash
2 3 4
#
# bash completion support for core Git.
#
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 10 11 12 13 14 15
#
# The contained completion routines provide support for completing:
#
#    *) local and remote branch names
#    *) local and remote tag names
#    *) .git/remotes file names
#    *) git 'subcommands'
#    *) tree paths within 'ref:path/to/file' expressions
16
#    *) common --long-options
17 18 19 20 21 22 23
#
# To use these routines:
#
#    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
#    2) Added the following line to your .bashrc:
#        source ~/.git-completion.sh
#
24 25 26 27 28 29 30
#    3) You may want to make sure the git executable is available
#       in your PATH before this script is sourced, as some caching
#       is performed while the script loads.  If git isn't found
#       at source time then all lookups will be done on demand,
#       which may be slightly slower.
#
#    4) Consider changing your PS1 to also show the current branch:
31 32 33 34 35 36
#        PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
#
#       The argument to __git_ps1 will be displayed only if you
#       are currently in a git repository.  The %s token will be
#       the name of the current branch.
#
37 38 39 40 41
#       In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty
#       value, unstaged (*) and staged (+) changes will be shown next
#       to the branch name.  You can configure this per-repository
#       with the bash.showDirtyState variable, which defaults to true
#       once GIT_PS1_SHOWDIRTYSTATE is enabled.
42
#
43 44 45 46 47 48 49 50 51 52 53
# To submit patches:
#
#    *) Read Documentation/SubmittingPatches
#    *) Send all patches to the current maintainer:
#
#       "Shawn O. Pearce" <spearce@spearce.org>
#
#    *) Always CC the Git mailing list:
#
#       git@vger.kernel.org
#
54

55 56 57 58 59
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
esac

60 61
# __gitdir accepts 0 or 1 arguments (i.e., location)
# returns location of .git repo
62 63
__gitdir ()
{
64
	if [ -z "${1-}" ]; then
65 66 67 68 69 70 71 72 73 74 75 76
		if [ -n "$__git_dir" ]; then
			echo "$__git_dir"
		elif [ -d .git ]; then
			echo .git
		else
			git rev-parse --git-dir 2>/dev/null
		fi
	elif [ -d "$1/.git" ]; then
		echo "$1/.git"
	else
		echo "$1"
	fi
77 78
}

79 80
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
# returns text to add to bash PS1 prompt (includes branch name)
81 82
__git_ps1 ()
{
83 84 85 86
	local g="$(git rev-parse --git-dir 2>/dev/null)"
	if [ -n "$g" ]; then
		local r
		local b
87
		if [ -d "$g/rebase-apply" ]
88
		then
89
			if test -f "$g/rebase-apply/rebasing"
J
Junio C Hamano 已提交
90 91
			then
				r="|REBASE"
92
			elif test -f "$g/rebase-apply/applying"
J
Junio C Hamano 已提交
93 94 95 96 97
			then
				r="|AM"
			else
				r="|AM/REBASE"
			fi
98
			b="$(git symbolic-ref HEAD 2>/dev/null)"
99
		elif [ -f "$g/rebase-merge/interactive" ]
100 101
		then
			r="|REBASE-i"
102 103
			b="$(cat "$g/rebase-merge/head-name")"
		elif [ -d "$g/rebase-merge" ]
104 105
		then
			r="|REBASE-m"
106
			b="$(cat "$g/rebase-merge/head-name")"
107 108 109 110 111
		elif [ -f "$g/MERGE_HEAD" ]
		then
			r="|MERGING"
			b="$(git symbolic-ref HEAD 2>/dev/null)"
		else
112
			if [ -f "$g/BISECT_LOG" ]
113 114 115 116 117
			then
				r="|BISECTING"
			fi
			if ! b="$(git symbolic-ref HEAD 2>/dev/null)"
			then
118 119
				if ! b="$(git describe --exact-match HEAD 2>/dev/null)"
				then
120
					b="$(cut -c1-7 "$g/HEAD")..."
121
				fi
122 123 124
			fi
		fi

125 126 127
		local w
		local i

128
		if test -n "${GIT_PS1_SHOWDIRTYSTATE-}"; then
129 130 131 132 133 134 135 136 137 138 139 140
			if test "$(git config --bool bash.showDirtyState)" != "false"; then
				git diff --no-ext-diff --ignore-submodules \
					--quiet --exit-code || w="*"
				if git rev-parse --quiet --verify HEAD >/dev/null; then
					git diff-index --cached --quiet \
						--ignore-submodules HEAD -- || i="+"
				else
					i="#"
				fi
			fi
		fi

141
		if [ -n "${1-}" ]; then
142
			printf "$1" "${b##refs/heads/}$w$i$r"
143
		else
144
			printf " (%s)" "${b##refs/heads/}$w$i$r"
145 146 147 148
		fi
	fi
}

149
# __gitcomp_1 requires 2 arguments
150 151 152 153 154 155 156 157 158 159 160 161
__gitcomp_1 ()
{
	local c IFS=' '$'\t'$'\n'
	for c in $1; do
		case "$c$2" in
		--*=*) printf %s$'\n' "$c$2" ;;
		*.)    printf %s$'\n' "$c$2" ;;
		*)     printf %s$'\n' "$c$2 " ;;
		esac
	done
}

162 163
# __gitcomp accepts 1, 2, 3, or 4 arguments
# generates completion reply with compgen
164 165
__gitcomp ()
{
166
	local cur="${COMP_WORDS[COMP_CWORD]}"
167
	if [ $# -gt 2 ]; then
168 169
		cur="$3"
	fi
170 171 172 173 174
	case "$cur" in
	--*=)
		COMPREPLY=()
		;;
	*)
175
		local IFS=$'\n'
176 177
		COMPREPLY=($(compgen -P "${2-}" \
			-W "$(__gitcomp_1 "${1-}" "${4-}")" \
178
			-- "$cur"))
179 180
		;;
	esac
181 182
}

183
# __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
184 185
__git_heads ()
{
186
	local cmd i is_hash=y dir="$(__gitdir "${1-}")"
187
	if [ -d "$dir" ]; then
188 189
		git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
			refs/heads
190 191
		return
	fi
192
	for i in $(git ls-remote "${1-}" 2>/dev/null); do
193 194 195 196 197 198 199 200 201
		case "$is_hash,$i" in
		y,*) is_hash=n ;;
		n,*^{}) is_hash=y ;;
		n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
		n,*) is_hash=y; echo "$i" ;;
		esac
	done
}

202
# __git_tags accepts 0 or 1 arguments (to pass to __gitdir)
203 204
__git_tags ()
{
205
	local cmd i is_hash=y dir="$(__gitdir "${1-}")"
206
	if [ -d "$dir" ]; then
207 208
		git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
			refs/tags
209 210
		return
	fi
211
	for i in $(git ls-remote "${1-}" 2>/dev/null); do
212 213 214 215 216 217 218 219 220
		case "$is_hash,$i" in
		y,*) is_hash=n ;;
		n,*^{}) is_hash=y ;;
		n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
		n,*) is_hash=y; echo "$i" ;;
		esac
	done
}

221
# __git_refs accepts 0 or 1 arguments (to pass to __gitdir)
222 223
__git_refs ()
{
224
	local i is_hash=y dir="$(__gitdir "${1-}")"
S
SZEDER Gábor 已提交
225
	local cur="${COMP_WORDS[COMP_CWORD]}" format refs
226
	if [ -d "$dir" ]; then
S
SZEDER Gábor 已提交
227 228 229 230 231 232 233 234 235 236 237 238 239
		case "$cur" in
		refs|refs/*)
			format="refname"
			refs="${cur%/*}"
			;;
		*)
			if [ -e "$dir/HEAD" ]; then echo HEAD; fi
			format="refname:short"
			refs="refs/tags refs/heads refs/remotes"
			;;
		esac
		git --git-dir="$dir" for-each-ref --format="%($format)" \
			$refs
240
		return
241
	fi
242
	for i in $(git ls-remote "$dir" 2>/dev/null); do
243 244 245 246 247
		case "$is_hash,$i" in
		y,*) is_hash=n ;;
		n,*^{}) is_hash=y ;;
		n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
		n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
248
		n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
249 250 251 252 253
		n,*) is_hash=y; echo "$i" ;;
		esac
	done
}

254
# __git_refs2 requires 1 argument (to pass to __git_refs)
255 256
__git_refs2 ()
{
257 258 259
	local i
	for i in $(__git_refs "$1"); do
		echo "$i:$i"
260 261 262
	done
}

263
# __git_refs_remotes requires 1 argument (to pass to ls-remote)
264 265 266
__git_refs_remotes ()
{
	local cmd i is_hash=y
267
	for i in $(git ls-remote "$1" 2>/dev/null); do
268 269 270 271 272 273 274 275 276 277 278 279 280
		case "$is_hash,$i" in
		n,refs/heads/*)
			is_hash=y
			echo "$i:refs/remotes/$1/${i#refs/heads/}"
			;;
		y,*) is_hash=n ;;
		n,*^{}) is_hash=y ;;
		n,refs/tags/*) is_hash=y;;
		n,*) is_hash=y; ;;
		esac
	done
}

281 282
__git_remotes ()
{
283
	local i ngoff IFS=$'\n' d="$(__gitdir)"
284
	shopt -q nullglob || ngoff=1
285
	shopt -s nullglob
286 287
	for i in "$d/remotes"/*; do
		echo ${i#$d/remotes/}
288
	done
289
	[ "$ngoff" ] && shopt -u nullglob
290
	for i in $(git --git-dir="$d" config --list); do
291 292 293 294 295 296 297
		case "$i" in
		remote.*.url=*)
			i="${i#remote.}"
			echo "${i/.url=*/}"
			;;
		esac
	done
298 299
}

300 301
__git_merge_strategies ()
{
302 303 304 305
	if [ -n "$__git_merge_strategylist" ]; then
		echo "$__git_merge_strategylist"
		return
	fi
306 307 308 309 310 311
	git merge -s help 2>&1 |
	sed -n -e '/[Aa]vailable strategies are: /,/^$/{
		s/\.$//
		s/.*://
		s/^[ 	]*//
		s/[ 	]*$//
312
		p
313
	}'
314
}
315
__git_merge_strategylist=
316
__git_merge_strategylist=$(__git_merge_strategies 2>/dev/null)
317

318 319
__git_complete_file ()
{
320
	local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
321 322
	case "$cur" in
	?*:*)
323 324
		ref="${cur%%:*}"
		cur="${cur#*:}"
325 326
		case "$cur" in
		?*/*)
327 328
			pfx="${cur%/*}"
			cur="${cur##*/}"
329 330 331 332 333 334 335
			ls="$ref:$pfx"
			pfx="$pfx/"
			;;
		*)
			ls="$ref"
			;;
	    esac
336 337 338 339 340 341

		case "$COMP_WORDBREAKS" in
		*:*) : great ;;
		*)   pfx="$ref:$pfx" ;;
		esac

342
		local IFS=$'\n'
343
		COMPREPLY=($(compgen -P "$pfx" \
344
			-W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
345 346 347 348 349 350 351 352
				| sed '/^100... blob /{
				           s,^.*	,,
				           s,$, ,
				       }
				       /^120000 blob /{
				           s,^.*	,,
				           s,$, ,
				       }
353 354 355 356 357 358 359 360
				       /^040000 tree /{
				           s,^.*	,,
				           s,$,/,
				       }
				       s/^.*	//')" \
			-- "$cur"))
		;;
	*)
361
		__gitcomp "$(__git_refs)"
362 363 364 365
		;;
	esac
}

366 367 368 369 370 371 372
__git_complete_revlist ()
{
	local pfx cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	*...*)
		pfx="${cur%...*}..."
		cur="${cur#*...}"
373
		__gitcomp "$(__git_refs)" "$pfx" "$cur"
374 375 376 377
		;;
	*..*)
		pfx="${cur%..*}.."
		cur="${cur#*..}"
378 379
		__gitcomp "$(__git_refs)" "$pfx" "$cur"
		;;
380
	*)
381
		__gitcomp "$(__git_refs)"
382 383 384 385
		;;
	esac
}

386
__git_all_commands ()
387
{
388 389
	if [ -n "$__git_all_commandlist" ]; then
		echo "$__git_all_commandlist"
390 391
		return
	fi
392 393
	local i IFS=" "$'\n'
	for i in $(git help -a|egrep '^ ')
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
	do
		case $i in
		*--*)             : helper pattern;;
		*) echo $i;;
		esac
	done
}
__git_all_commandlist=
__git_all_commandlist="$(__git_all_commands 2>/dev/null)"

__git_porcelain_commands ()
{
	if [ -n "$__git_porcelain_commandlist" ]; then
		echo "$__git_porcelain_commandlist"
		return
	fi
	local i IFS=" "$'\n'
	for i in "help" $(__git_all_commands)
412 413
	do
		case $i in
414
		*--*)             : helper pattern;;
415 416 417
		applymbox)        : ask gittus;;
		applypatch)       : ask gittus;;
		archimport)       : import;;
418
		cat-file)         : plumbing;;
419
		check-attr)       : plumbing;;
420
		check-ref-format) : plumbing;;
421
		checkout-index)   : plumbing;;
422
		commit-tree)      : plumbing;;
423
		count-objects)    : infrequent;;
424 425
		cvsexportcommit)  : export;;
		cvsimport)        : import;;
426 427
		cvsserver)        : daemon;;
		daemon)           : daemon;;
428 429 430
		diff-files)       : plumbing;;
		diff-index)       : plumbing;;
		diff-tree)        : plumbing;;
S
Shawn O. Pearce 已提交
431
		fast-import)      : import;;
432
		fast-export)      : export;;
433
		fsck-objects)     : plumbing;;
434
		fetch-pack)       : plumbing;;
435
		fmt-merge-msg)    : plumbing;;
436
		for-each-ref)     : plumbing;;
437 438 439
		hash-object)      : plumbing;;
		http-*)           : transport;;
		index-pack)       : plumbing;;
440
		init-db)          : deprecated;;
441
		local-fetch)      : plumbing;;
442 443 444 445
		lost-found)       : infrequent;;
		ls-files)         : plumbing;;
		ls-remote)        : plumbing;;
		ls-tree)          : plumbing;;
446 447 448 449 450 451 452 453 454 455 456
		mailinfo)         : plumbing;;
		mailsplit)        : plumbing;;
		merge-*)          : plumbing;;
		mktree)           : plumbing;;
		mktag)            : plumbing;;
		pack-objects)     : plumbing;;
		pack-redundant)   : plumbing;;
		pack-refs)        : plumbing;;
		parse-remote)     : plumbing;;
		patch-id)         : plumbing;;
		peek-remote)      : plumbing;;
457 458 459
		prune)            : plumbing;;
		prune-packed)     : plumbing;;
		quiltimport)      : import;;
460 461
		read-tree)        : plumbing;;
		receive-pack)     : plumbing;;
462
		reflog)           : plumbing;;
463
		repo-config)      : deprecated;;
464 465 466 467 468 469
		rerere)           : plumbing;;
		rev-list)         : plumbing;;
		rev-parse)        : plumbing;;
		runstatus)        : plumbing;;
		sh-setup)         : internal;;
		shell)            : daemon;;
470
		show-ref)         : plumbing;;
471 472 473 474 475
		send-pack)        : plumbing;;
		show-index)       : plumbing;;
		ssh-*)            : transport;;
		stripspace)       : plumbing;;
		symbolic-ref)     : plumbing;;
476
		tar-tree)         : deprecated;;
477 478
		unpack-file)      : plumbing;;
		unpack-objects)   : plumbing;;
479
		update-index)     : plumbing;;
480 481 482 483 484
		update-ref)       : plumbing;;
		update-server-info) : daemon;;
		upload-archive)   : plumbing;;
		upload-pack)      : plumbing;;
		write-tree)       : plumbing;;
485 486
		var)              : infrequent;;
		verify-pack)      : infrequent;;
487
		verify-tag)       : plumbing;;
488 489 490 491
		*) echo $i;;
		esac
	done
}
492 493
__git_porcelain_commandlist=
__git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)"
494

495 496
__git_aliases ()
{
497
	local i IFS=$'\n'
498
	for i in $(git --git-dir="$(__gitdir)" config --list); do
499 500 501 502 503 504 505
		case "$i" in
		alias.*)
			i="${i#alias.}"
			echo "${i/=*/}"
			;;
		esac
	done
506 507
}

508
# __git_aliased_command requires 1 argument
509 510
__git_aliased_command ()
{
511
	local word cmdline=$(git --git-dir="$(__gitdir)" \
512
		config --get "alias.$1")
513 514 515 516 517 518 519 520
	for word in $cmdline; do
		if [ "${word##-*}" ]; then
			echo $word
			return
		fi
	done
}

521
# __git_find_subcommand requires 1 argument
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
__git_find_subcommand ()
{
	local word subcommand c=1

	while [ $c -lt $COMP_CWORD ]; do
		word="${COMP_WORDS[c]}"
		for subcommand in $1; do
			if [ "$subcommand" = "$word" ]; then
				echo "$subcommand"
				return
			fi
		done
		c=$((++c))
	done
}

538 539 540 541 542 543 544 545 546 547 548 549
__git_has_doubledash ()
{
	local c=1
	while [ $c -lt $COMP_CWORD ]; do
		if [ "--" = "${COMP_WORDS[c]}" ]; then
			return 0
		fi
		c=$((++c))
	done
	return 1
}

550
__git_whitespacelist="nowarn warn error error-all fix"
551 552 553

_git_am ()
{
554
	local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
555
	if [ -d "$dir"/rebase-apply ]; then
556
		__gitcomp "--skip --resolved --abort"
557 558 559 560
		return
	fi
	case "$cur" in
	--whitespace=*)
561
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
562 563 564
		return
		;;
	--*)
565
		__gitcomp "
566 567
			--signoff --utf8 --binary --3way --interactive
			--whitespace=
568
			"
569 570 571 572 573 574 575 576 577 578
		return
	esac
	COMPREPLY=()
}

_git_apply ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--whitespace=*)
579
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
580 581 582
		return
		;;
	--*)
583
		__gitcomp "
584 585 586 587
			--stat --numstat --summary --check --index
			--cached --index-info --reverse --reject --unidiff-zero
			--apply --no-add --exclude=
			--whitespace= --inaccurate-eof --verbose
588
			"
589 590 591 592 593
		return
	esac
	COMPREPLY=()
}

594 595
_git_add ()
{
596 597
	__git_has_doubledash && return

598 599 600
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
601 602
		__gitcomp "
			--interactive --refresh --patch --update --dry-run
603
			--ignore-errors --intent-to-add
604
			"
605 606 607 608 609
		return
	esac
	COMPREPLY=()
}

610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
_git_archive ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--format=*)
		__gitcomp "$(git archive --list)" "" "${cur##--format=}"
		return
		;;
	--remote=*)
		__gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
		return
		;;
	--*)
		__gitcomp "
			--format= --list --verbose
			--prefix= --remote= --exec=
			"
		return
		;;
	esac
	__git_complete_file
}

633 634
_git_bisect ()
{
635 636
	__git_has_doubledash && return

637
	local subcommands="start bad good skip reset visualize replay log run"
638 639 640
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
		__gitcomp "$subcommands"
641 642 643
		return
	fi

644
	case "$subcommand" in
645
	bad|good|reset|skip)
646 647 648 649 650 651 652 653
		__gitcomp "$(__git_refs)"
		;;
	*)
		COMPREPLY=()
		;;
	esac
}

654 655
_git_branch ()
{
656 657 658 659 660 661 662 663 664 665 666
	local i c=1 only_local_ref="n" has_r="n"

	while [ $c -lt $COMP_CWORD ]; do
		i="${COMP_WORDS[c]}"
		case "$i" in
		-d|-m)	only_local_ref="y" ;;
		-r)	has_r="y" ;;
		esac
		c=$((++c))
	done

S
SZEDER Gábor 已提交
667 668 669 670
	case "${COMP_WORDS[COMP_CWORD]}" in
	--*)
		__gitcomp "
			--color --no-color --verbose --abbrev= --no-abbrev
671
			--track --no-track --contains --merged --no-merged
S
SZEDER Gábor 已提交
672 673
			"
		;;
674 675 676 677 678 679 680
	*)
		if [ $only_local_ref = "y" -a $has_r = "n" ]; then
			__gitcomp "$(__git_heads)"
		else
			__gitcomp "$(__git_refs)"
		fi
		;;
S
SZEDER Gábor 已提交
681
	esac
682 683
}

684 685
_git_bundle ()
{
686 687 688
	local cmd="${COMP_WORDS[2]}"
	case "$COMP_CWORD" in
	2)
689 690
		__gitcomp "create list-heads verify unbundle"
		;;
691
	3)
692 693 694 695 696 697 698 699 700 701 702 703
		# looking for a file
		;;
	*)
		case "$cmd" in
			create)
				__git_complete_revlist
			;;
		esac
		;;
	esac
}

704 705
_git_checkout ()
{
706 707
	__git_has_doubledash && return

708
	__gitcomp "$(__git_refs)"
709 710
}

711 712 713 714 715
_git_cherry ()
{
	__gitcomp "$(__git_refs)"
}

716 717 718 719 720
_git_cherry_pick ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
721
		__gitcomp "--edit --no-commit"
722 723
		;;
	*)
724
		__gitcomp "$(__git_refs)"
725 726 727 728
		;;
	esac
}

729 730 731 732 733 734 735 736 737 738 739 740 741 742
_git_clean ()
{
	__git_has_doubledash && return

	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--dry-run --quiet"
		return
		;;
	esac
	COMPREPLY=()
}

743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
_git_clone ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--local
			--no-hardlinks
			--shared
			--reference
			--quiet
			--no-checkout
			--bare
			--mirror
			--origin
			--upload-pack
			--template=
			--depth
			"
		return
		;;
	esac
	COMPREPLY=()
}

768 769
_git_commit ()
{
770 771
	__git_has_doubledash && return

772 773 774
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
775
		__gitcomp "
776
			--all --author= --signoff --verify --no-verify
777
			--edit --amend --include --only --interactive
778
			"
779 780 781 782 783
		return
	esac
	COMPREPLY=()
}

784 785
_git_describe ()
{
786 787 788 789 790 791 792 793 794
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--all --tags --contains --abbrev= --candidates=
			--exact-match --debug --long --match --always
			"
		return
	esac
795 796 797
	__gitcomp "$(__git_refs)"
}

798
__git_diff_common_options="--stat --numstat --shortstat --summary
799 800
			--patch-with-stat --name-only --name-status --color
			--no-color --color-words --no-renames --check
801
			--full-index --binary --abbrev --diff-filter=
802
			--find-copies-harder
803 804
			--text --ignore-space-at-eol --ignore-space-change
			--ignore-all-space --exit-code --quiet --ext-diff
805 806
			--no-ext-diff
			--no-prefix --src-prefix= --dst-prefix=
807
			--inter-hunk-context=
808
			--patience
809 810 811 812 813 814 815 816 817 818 819 820 821
			--raw
"

_git_diff ()
{
	__git_has_doubledash && return

	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--cached --pickaxe-all --pickaxe-regex
			--base --ours --theirs
			$__git_diff_common_options
822
			"
823 824 825
		return
		;;
	esac
826 827 828 829 830 831 832
	__git_complete_file
}

_git_fetch ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"

833
	if [ "$COMP_CWORD" = 2 ]; then
834
		__gitcomp "$(__git_remotes)"
835
	else
836 837
		case "$cur" in
		*:*)
838 839 840 841 842 843
			local pfx=""
			case "$COMP_WORDBREAKS" in
			*:*) : great ;;
			*)   pfx="${cur%%:*}:" ;;
			esac
			__gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
844 845
			;;
		*)
846
			__gitcomp "$(__git_refs2 "${COMP_WORDS[2]}")"
847 848
			;;
		esac
849
	fi
850 851
}

852 853 854 855 856
_git_format_patch ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
857
		__gitcomp "
858 859 860
			--stdout --attach --thread
			--output-directory
			--numbered --start-number
861
			--numbered-files
862 863 864 865
			--keep-subject
			--signoff
			--in-reply-to=
			--full-index --binary
866
			--not --all
867
			--cover-letter
868
			--no-prefix --src-prefix= --dst-prefix=
869 870
			--inline --suffix= --ignore-if-in-upstream
			--subject-prefix=
871
			"
872 873 874 875 876 877
		return
		;;
	esac
	__git_complete_revlist
}

878 879 880 881 882
_git_gc ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
883
		__gitcomp "--prune --aggressive"
884 885 886 887 888 889
		return
		;;
	esac
	COMPREPLY=()
}

890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912
_git_grep ()
{
	__git_has_doubledash && return

	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--cached
			--text --ignore-case --word-regexp --invert-match
			--full-name
			--extended-regexp --basic-regexp --fixed-strings
			--files-with-matches --name-only
			--files-without-match
			--count
			--and --or --not --all-match
			"
		return
		;;
	esac
	COMPREPLY=()
}

913 914 915 916 917 918 919 920 921
_git_help ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--all --info --man --web"
		return
		;;
	esac
922 923 924 925
	__gitcomp "$(__git_all_commands)
		attributes cli core-tutorial cvs-migration
		diffcore gitk glossary hooks ignore modules
		repository-layout tutorial tutorial-2
926
		workflows
927
		"
928 929
}

930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947
_git_init ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--shared=*)
		__gitcomp "
			false true umask group all world everybody
			" "" "${cur##--shared=}"
		return
		;;
	--*)
		__gitcomp "--quiet --bare --template= --shared --shared="
		return
		;;
	esac
	COMPREPLY=()
}

948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967
_git_ls_files ()
{
	__git_has_doubledash && return

	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--cached --deleted --modified --others --ignored
			--stage --directory --no-empty-directory --unmerged
			--killed --exclude= --exclude-from=
			--exclude-per-directory= --exclude-standard
			--error-unmatch --with-tree= --full-name
			--abbrev --ignored --exclude-per-directory
			"
		return
		;;
	esac
	COMPREPLY=()
}

968 969
_git_ls_remote ()
{
970
	__gitcomp "$(__git_remotes)"
971 972 973 974 975 976 977
}

_git_ls_tree ()
{
	__git_complete_file
}

978 979
__git_log_pretty_formats="oneline short medium full fuller email raw format:"

980 981
_git_log ()
{
982 983
	__git_has_doubledash && return

984 985 986
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--pretty=*)
987
		__gitcomp "$__git_log_pretty_formats
988
			" "" "${cur##--pretty=}"
989 990
		return
		;;
991 992 993 994 995 996
	--date=*)
		__gitcomp "
			relative iso8601 rfc2822 short local default
		" "" "${cur##--date=}"
		return
		;;
997
	--*)
998
		__gitcomp "
999 1000
			--max-count= --max-age= --since= --after=
			--min-age= --before= --until=
1001
			--root --topo-order --date-order --reverse
1002
			--no-merges --follow
1003
			--abbrev-commit --abbrev=
1004
			--relative-date --date=
1005 1006
			--author= --committer= --grep=
			--all-match
1007
			--pretty=
1008
			--not --all
1009
			--left-right --cherry-pick
1010
			--graph
1011 1012
			--decorate
			--walk-reflogs
1013
			--parents --children --full-history
1014
			--merge
1015
			$__git_diff_common_options
1016
			--pickaxe-all --pickaxe-regex
1017
			"
1018 1019 1020
		return
		;;
	esac
1021
	__git_complete_revlist
1022 1023
}

1024 1025 1026
_git_merge ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
1027 1028
	case "${COMP_WORDS[COMP_CWORD-1]}" in
	-s|--strategy)
1029
		__gitcomp "$(__git_merge_strategies)"
1030 1031
		return
	esac
1032
	case "$cur" in
1033
	--strategy=*)
1034
		__gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
1035 1036
		return
		;;
1037
	--*)
1038
		__gitcomp "
1039
			--no-commit --no-stat --log --no-log --squash --strategy
1040
			--commit --stat --no-squash --ff --no-ff
1041
			"
1042 1043
		return
	esac
1044
	__gitcomp "$(__git_refs)"
1045 1046
}

1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065
_git_mergetool ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--tool=*)
		__gitcomp "
			kdiff3 tkdiff meld xxdiff emerge
			vimdiff gvimdiff ecmerge opendiff
			" "" "${cur##--tool=}"
		return
		;;
	--*)
		__gitcomp "--tool="
		return
		;;
	esac
	COMPREPLY=()
}

1066 1067
_git_merge_base ()
{
1068
	__gitcomp "$(__git_refs)"
1069 1070
}

1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
_git_mv ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--dry-run"
		return
		;;
	esac
	COMPREPLY=()
}

1083 1084
_git_name_rev ()
{
1085
	__gitcomp "--tags --all --stdin"
1086 1087
}

1088 1089 1090 1091
_git_pull ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"

1092
	if [ "$COMP_CWORD" = 2 ]; then
1093
		__gitcomp "$(__git_remotes)"
1094
	else
1095
		__gitcomp "$(__git_refs "${COMP_WORDS[2]}")"
1096
	fi
1097 1098 1099 1100 1101 1102
}

_git_push ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"

1103
	if [ "$COMP_CWORD" = 2 ]; then
1104
		__gitcomp "$(__git_remotes)"
1105
	else
1106 1107
		case "$cur" in
		*:*)
1108 1109 1110 1111 1112 1113
			local pfx=""
			case "$COMP_WORDBREAKS" in
			*:*) : great ;;
			*)   pfx="${cur%%:*}:" ;;
			esac

1114
			__gitcomp "$(__git_refs "${COMP_WORDS[2]}")" "$pfx" "${cur#*:}"
1115
			;;
1116 1117 1118
		+*)
			__gitcomp "$(__git_refs)" + "${cur#+}"
			;;
1119
		*)
1120
			__gitcomp "$(__git_refs)"
1121 1122
			;;
		esac
1123
	fi
1124 1125
}

1126 1127
_git_rebase ()
{
1128
	local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
1129
	if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1130
		__gitcomp "--continue --skip --abort"
1131 1132
		return
	fi
1133 1134
	case "${COMP_WORDS[COMP_CWORD-1]}" in
	-s|--strategy)
1135
		__gitcomp "$(__git_merge_strategies)"
1136 1137
		return
	esac
1138
	case "$cur" in
1139
	--strategy=*)
1140
		__gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
1141 1142
		return
		;;
1143
	--*)
1144
		__gitcomp "--onto --merge --strategy --interactive"
1145 1146
		return
	esac
1147
	__gitcomp "$(__git_refs)"
1148 1149
}

1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
_git_send_email ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
			--dry-run --envelope-sender --from --identity
			--in-reply-to --no-chain-reply-to --no-signed-off-by-cc
			--no-suppress-from --no-thread --quiet
			--signed-off-by-cc --smtp-pass --smtp-server
			--smtp-server-port --smtp-ssl --smtp-user --subject
1161 1162
			--suppress-cc --suppress-from --thread --to
			--validate --no-validate"
1163 1164 1165 1166 1167 1168
		return
		;;
	esac
	COMPREPLY=()
}

1169
_git_config ()
1170 1171 1172 1173 1174
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	local prv="${COMP_WORDS[COMP_CWORD-1]}"
	case "$prv" in
	branch.*.remote)
1175
		__gitcomp "$(__git_remotes)"
1176 1177 1178
		return
		;;
	branch.*.merge)
1179
		__gitcomp "$(__git_refs)"
1180 1181 1182 1183 1184
		return
		;;
	remote.*.fetch)
		local remote="${prv#remote.}"
		remote="${remote%.fetch}"
1185
		__gitcomp "$(__git_refs_remotes "$remote")"
1186 1187 1188 1189 1190
		return
		;;
	remote.*.push)
		local remote="${prv#remote.}"
		remote="${remote%.push}"
1191
		__gitcomp "$(git --git-dir="$(__gitdir)" \
1192
			for-each-ref --format='%(refname):%(refname)' \
1193 1194 1195 1196 1197 1198 1199
			refs/heads)"
		return
		;;
	pull.twohead|pull.octopus)
		__gitcomp "$(__git_merge_strategies)"
		return
		;;
1200
	color.branch|color.diff|color.interactive|color.status|color.ui)
1201 1202 1203
		__gitcomp "always never auto"
		return
		;;
1204 1205 1206 1207
	color.pager)
		__gitcomp "false true"
		return
		;;
1208 1209
	color.*.*)
		__gitcomp "
1210
			normal black red green yellow blue magenta cyan white
1211 1212
			bold dim ul blink reverse
			"
1213 1214 1215 1216 1217 1218 1219 1220 1221
		return
		;;
	*.*)
		COMPREPLY=()
		return
		;;
	esac
	case "$cur" in
	--*)
1222
		__gitcomp "
1223
			--global --system --file=
1224
			--list --replace-all
1225
			--get --get-all --get-regexp
1226
			--add --unset --unset-all
1227
			--remove-section --rename-section
1228
			"
1229 1230 1231 1232 1233
		return
		;;
	branch.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1234
		__gitcomp "remote merge mergeoptions" "$pfx" "$cur"
1235 1236 1237 1238 1239
		return
		;;
	branch.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
1240
		__gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1241 1242 1243 1244 1245
		return
		;;
	remote.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1246
		__gitcomp "
1247
			url proxy fetch push mirror skipDefaultUpdate
1248 1249
			receivepack uploadpack tagopt
			" "$pfx" "$cur"
1250 1251 1252 1253 1254
		return
		;;
	remote.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
1255
		__gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1256 1257 1258
		return
		;;
	esac
1259
	__gitcomp "
1260
		apply.whitespace
1261 1262
		branch.autosetupmerge
		branch.autosetuprebase
1263
		clean.requireForce
1264 1265 1266 1267
		color.branch
		color.branch.current
		color.branch.local
		color.branch.plain
1268
		color.branch.remote
1269
		color.diff
1270
		color.diff.commit
1271
		color.diff.frag
1272
		color.diff.meta
1273
		color.diff.new
1274 1275
		color.diff.old
		color.diff.plain
1276
		color.diff.whitespace
1277 1278 1279 1280
		color.interactive
		color.interactive.header
		color.interactive.help
		color.interactive.prompt
1281 1282
		color.pager
		color.status
1283 1284
		color.status.added
		color.status.changed
1285
		color.status.header
1286
		color.status.nobranch
1287
		color.status.untracked
1288 1289 1290 1291 1292
		color.status.updated
		color.ui
		commit.template
		core.autocrlf
		core.bare
1293
		core.compression
1294 1295 1296
		core.deltaBaseCacheLimit
		core.editor
		core.excludesfile
1297
		core.fileMode
1298
		core.fsyncobjectfiles
1299
		core.gitProxy
1300
		core.ignoreCygwinFSTricks
1301 1302 1303 1304 1305
		core.ignoreStat
		core.logAllRefUpdates
		core.loosecompression
		core.packedGitLimit
		core.packedGitWindowSize
1306
		core.pager
1307
		core.preferSymlinkRefs
1308 1309
		core.preloadindex
		core.quotepath
1310
		core.repositoryFormatVersion
1311
		core.safecrlf
1312
		core.sharedRepository
1313 1314
		core.symlinks
		core.trustctime
1315
		core.warnAmbiguousRefs
1316 1317 1318 1319 1320
		core.whitespace
		core.worktree
		diff.autorefreshindex
		diff.external
		diff.mnemonicprefix
1321
		diff.renameLimit
1322
		diff.renameLimit.
1323 1324 1325
		diff.renames
		fetch.unpackLimit
		format.headers
1326 1327 1328 1329 1330 1331
		format.numbered
		format.pretty
		format.suffix
		gc.aggressiveWindow
		gc.auto
		gc.autopacklimit
1332
		gc.packrefs
1333
		gc.pruneexpire
1334 1335 1336 1337
		gc.reflogexpire
		gc.reflogexpireunreachable
		gc.rerereresolved
		gc.rerereunresolved
1338
		gitcvs.allbinary
1339
		gitcvs.dbTableNamePrefix
1340 1341 1342 1343 1344 1345
		gitcvs.dbdriver
		gitcvs.dbname
		gitcvs.dbpass
		gitcvs.dbuser
		gitcvs.enabled
		gitcvs.logfile
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360
		gitcvs.usecrlfattr
		gui.blamehistoryctx
		gui.commitmsgwidth
		gui.copyblamethreshold
		gui.diffcontext
		gui.encoding
		gui.fastcopyblame
		gui.matchtrackingbranch
		gui.newbranchtemplate
		gui.pruneduringfetch
		gui.spellingdictionary
		gui.trustmtime
		help.autocorrect
		help.browser
		help.format
1361 1362
		http.lowSpeedLimit
		http.lowSpeedTime
1363
		http.maxRequests
1364
		http.noEPSV
1365
		http.proxy
1366 1367 1368 1369 1370
		http.sslCAInfo
		http.sslCAPath
		http.sslCert
		http.sslKey
		http.sslVerify
1371 1372
		i18n.commitEncoding
		i18n.logOutputEncoding
1373 1374 1375 1376 1377 1378
		instaweb.browser
		instaweb.httpd
		instaweb.local
		instaweb.modulepath
		instaweb.port
		log.date
1379
		log.showroot
1380 1381 1382 1383 1384
		man.viewer
		merge.conflictstyle
		merge.log
		merge.renameLimit
		merge.stat
1385
		merge.tool
1386
		merge.verbosity
1387
		mergetool.keepBackup
1388 1389
		pack.compression
		pack.deltaCacheLimit
1390 1391
		pack.deltaCacheSize
		pack.depth
1392 1393 1394
		pack.indexVersion
		pack.packSizeLimit
		pack.threads
1395 1396
		pack.window
		pack.windowMemory
1397 1398
		pull.octopus
		pull.twohead
1399 1400
		receive.denyCurrentBranch
		receive.denyDeletes
1401
		receive.denyNonFastForwards
1402
		receive.fsckObjects
1403
		receive.unpackLimit
1404 1405 1406
		repack.usedeltabaseoffset
		rerere.autoupdate
		rerere.enabled
1407
		showbranch.default
1408 1409
		status.relativePaths
		status.showUntrackedFiles
1410 1411 1412
		tar.umask
		transfer.unpackLimit
		user.email
1413
		user.name
1414
		user.signingkey
1415
		web.browser
1416
		branch. remote.
1417
	"
1418 1419
}

1420 1421
_git_remote ()
{
1422
	local subcommands="add rename rm show prune update"
1423 1424
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
1425
		__gitcomp "$subcommands"
1426 1427 1428
		return
	fi

1429
	case "$subcommand" in
1430
	rename|rm|show|prune)
1431 1432
		__gitcomp "$(__git_remotes)"
		;;
1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444
	update)
		local i c='' IFS=$'\n'
		for i in $(git --git-dir="$(__gitdir)" config --list); do
			case "$i" in
			remotes.*)
				i="${i#remotes.}"
				c="$c ${i/=*/}"
				;;
			esac
		done
		__gitcomp "$c"
		;;
1445 1446 1447 1448 1449 1450
	*)
		COMPREPLY=()
		;;
	esac
}

1451 1452
_git_reset ()
{
1453 1454
	__git_has_doubledash && return

1455
	local cur="${COMP_WORDS[COMP_CWORD]}"
1456 1457
	case "$cur" in
	--*)
1458
		__gitcomp "--merge --mixed --hard --soft"
1459 1460 1461 1462
		return
		;;
	esac
	__gitcomp "$(__git_refs)"
1463 1464
}

1465 1466 1467 1468 1469 1470 1471 1472 1473
_git_revert ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--edit --mainline --no-edit --no-commit --signoff"
		return
		;;
	esac
1474
	__gitcomp "$(__git_refs)"
1475 1476
}

1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
_git_rm ()
{
	__git_has_doubledash && return

	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--cached --dry-run --ignore-unmatch --quiet"
		return
		;;
	esac
	COMPREPLY=()
}

1491 1492
_git_shortlog ()
{
1493 1494
	__git_has_doubledash && return

1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--max-count= --max-age= --since= --after=
			--min-age= --before= --until=
			--no-merges
			--author= --committer= --grep=
			--all-match
			--not --all
			--numbered --summary
			"
		return
		;;
	esac
	__git_complete_revlist
}

1513 1514
_git_show ()
{
1515 1516
	__git_has_doubledash && return

1517 1518 1519
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--pretty=*)
1520
		__gitcomp "$__git_log_pretty_formats
1521
			" "" "${cur##--pretty=}"
1522 1523 1524
		return
		;;
	--*)
1525 1526 1527
		__gitcomp "--pretty=
			$__git_diff_common_options
			"
1528 1529 1530 1531 1532 1533
		return
		;;
	esac
	__git_complete_file
}

1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
_git_show_branch ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--all --remotes --topo-order --current --more=
			--list --independent --merge-base --no-name
			--sha1-name --topics --reflog
			"
		return
		;;
	esac
	__git_complete_revlist
}

J
Junio C Hamano 已提交
1550 1551
_git_stash ()
{
1552
	local subcommands='save list show apply clear drop pop create branch'
1553 1554
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
1555
		__gitcomp "$subcommands"
1556 1557 1558 1559 1560 1561
	else
		local cur="${COMP_WORDS[COMP_CWORD]}"
		case "$subcommand,$cur" in
		save,--*)
			__gitcomp "--keep-index"
			;;
1562 1563 1564
		apply,--*)
			__gitcomp "--index"
			;;
1565
		show,--*|drop,--*|pop,--*|branch,--*)
1566 1567 1568 1569 1570 1571
			COMPREPLY=()
			;;
		show,*|apply,*|drop,*|pop,*|branch,*)
			__gitcomp "$(git --git-dir="$(__gitdir)" stash list \
					| sed -n -e 's/:.*//p')"
			;;
1572 1573 1574 1575
		*)
			COMPREPLY=()
			;;
		esac
1576
	fi
J
Junio C Hamano 已提交
1577 1578
}

1579 1580
_git_submodule ()
{
1581 1582
	__git_has_doubledash && return

1583
	local subcommands="add status init update summary foreach sync"
1584
	if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1585 1586 1587 1588 1589 1590
		local cur="${COMP_WORDS[COMP_CWORD]}"
		case "$cur" in
		--*)
			__gitcomp "--quiet --cached"
			;;
		*)
1591
			__gitcomp "$subcommands"
1592 1593 1594 1595 1596 1597
			;;
		esac
		return
	fi
}

1598 1599 1600 1601 1602
_git_svn ()
{
	local subcommands="
		init fetch clone rebase dcommit log find-rev
		set-tree commit-diff info create-ignore propget
S
SZEDER Gábor 已提交
1603 1604
		proplist show-ignore show-externals branch tag blame
		migrate
1605 1606 1607 1608 1609 1610 1611 1612 1613 1614
		"
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
		__gitcomp "$subcommands"
	else
		local remote_opts="--username= --config-dir= --no-auth-cache"
		local fc_opts="
			--follow-parent --authors-file= --repack=
			--no-metadata --use-svm-props --use-svnsync-props
			--log-window-size= --no-checkout --quiet
S
SZEDER Gábor 已提交
1615 1616
			--repack-flags --use-log-author --localtime
			--ignore-paths= $remote_opts
1617 1618 1619 1620 1621
			"
		local init_opts="
			--template= --shared= --trunk= --tags=
			--branches= --stdlayout --minimize-url
			--no-metadata --use-svm-props --use-svnsync-props
S
SZEDER Gábor 已提交
1622 1623
			--rewrite-root= --prefix= --use-log-author
			--add-author-from $remote_opts
1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642
			"
		local cmt_opts="
			--edit --rmdir --find-copies-harder --copy-similarity=
			"

		local cur="${COMP_WORDS[COMP_CWORD]}"
		case "$subcommand,$cur" in
		fetch,--*)
			__gitcomp "--revision= --fetch-all $fc_opts"
			;;
		clone,--*)
			__gitcomp "--revision= $fc_opts $init_opts"
			;;
		init,--*)
			__gitcomp "$init_opts"
			;;
		dcommit,--*)
			__gitcomp "
				--merge --strategy= --verbose --dry-run
S
SZEDER Gábor 已提交
1643 1644
				--fetch-all --no-rebase --commit-url
				--revision $cmt_opts $fc_opts
1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657
				"
			;;
		set-tree,--*)
			__gitcomp "--stdin $cmt_opts $fc_opts"
			;;
		create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
		show-externals,--*)
			__gitcomp "--revision="
			;;
		log,--*)
			__gitcomp "
				--limit= --revision= --verbose --incremental
				--oneline --show-commit --non-recursive
S
SZEDER Gábor 已提交
1658
				--authors-file= --color
1659 1660 1661 1662 1663
				"
			;;
		rebase,--*)
			__gitcomp "
				--merge --verbose --strategy= --local
S
SZEDER Gábor 已提交
1664
				--fetch-all --dry-run $fc_opts
1665 1666 1667 1668 1669 1670 1671 1672
				"
			;;
		commit-diff,--*)
			__gitcomp "--message= --file= --revision= $cmt_opts"
			;;
		info,--*)
			__gitcomp "--url"
			;;
S
SZEDER Gábor 已提交
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687
		branch,--*)
			__gitcomp "--dry-run --message --tag"
			;;
		tag,--*)
			__gitcomp "--dry-run --message"
			;;
		blame,--*)
			__gitcomp "--git-format"
			;;
		migrate,--*)
			__gitcomp "
				--config-dir= --ignore-paths= --minimize
				--no-auth-cache --username=
				"
			;;
1688 1689 1690 1691 1692 1693 1694
		*)
			COMPREPLY=()
			;;
		esac
	fi
}

1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715
_git_tag ()
{
	local i c=1 f=0
	while [ $c -lt $COMP_CWORD ]; do
		i="${COMP_WORDS[c]}"
		case "$i" in
		-d|-v)
			__gitcomp "$(__git_tags)"
			return
			;;
		-f)
			f=1
			;;
		esac
		c=$((++c))
	done

	case "${COMP_WORDS[COMP_CWORD-1]}" in
	-m|-F)
		COMPREPLY=()
		;;
1716
	-*|tag)
1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728
		if [ $f = 1 ]; then
			__gitcomp "$(__git_tags)"
		else
			COMPREPLY=()
		fi
		;;
	*)
		__gitcomp "$(__git_refs)"
		;;
	esac
}

1729 1730
_git ()
{
1731 1732 1733 1734 1735 1736 1737
	local i c=1 command __git_dir

	while [ $c -lt $COMP_CWORD ]; do
		i="${COMP_WORDS[c]}"
		case "$i" in
		--git-dir=*) __git_dir="${i#--git-dir=}" ;;
		--bare)      __git_dir="." ;;
1738 1739
		--version|-p|--paginate) ;;
		--help) command="help"; break ;;
1740 1741 1742 1743 1744
		*) command="$i"; break ;;
		esac
		c=$((++c))
	done

1745
	if [ -z "$command" ]; then
1746
		case "${COMP_WORDS[COMP_CWORD]}" in
1747
		--*)   __gitcomp "
1748
			--paginate
1749 1750 1751 1752 1753
			--no-pager
			--git-dir=
			--bare
			--version
			--exec-path
1754 1755
			--work-tree=
			--help
1756 1757
			"
			;;
1758
		*)     __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
1759 1760
		esac
		return
1761
	fi
1762

1763 1764
	local expansion=$(__git_aliased_command "$command")
	[ "$expansion" ] && command="$expansion"
1765

1766
	case "$command" in
1767
	am)          _git_am ;;
1768
	add)         _git_add ;;
1769
	apply)       _git_apply ;;
1770
	archive)     _git_archive ;;
1771
	bisect)      _git_bisect ;;
1772
	bundle)      _git_bundle ;;
1773 1774
	branch)      _git_branch ;;
	checkout)    _git_checkout ;;
1775
	cherry)      _git_cherry ;;
1776
	cherry-pick) _git_cherry_pick ;;
1777
	clean)       _git_clean ;;
1778
	clone)       _git_clone ;;
1779
	commit)      _git_commit ;;
1780
	config)      _git_config ;;
1781
	describe)    _git_describe ;;
1782 1783
	diff)        _git_diff ;;
	fetch)       _git_fetch ;;
1784
	format-patch) _git_format_patch ;;
1785
	gc)          _git_gc ;;
1786
	grep)        _git_grep ;;
1787
	help)        _git_help ;;
1788
	init)        _git_init ;;
1789
	log)         _git_log ;;
1790
	ls-files)    _git_ls_files ;;
1791 1792
	ls-remote)   _git_ls_remote ;;
	ls-tree)     _git_ls_tree ;;
1793
	merge)       _git_merge;;
1794
	mergetool)   _git_mergetool;;
1795
	merge-base)  _git_merge_base ;;
1796
	mv)          _git_mv ;;
1797
	name-rev)    _git_name_rev ;;
1798 1799
	pull)        _git_pull ;;
	push)        _git_push ;;
1800
	rebase)      _git_rebase ;;
1801
	remote)      _git_remote ;;
1802
	reset)       _git_reset ;;
1803
	revert)      _git_revert ;;
1804
	rm)          _git_rm ;;
1805
	send-email)  _git_send_email ;;
1806
	shortlog)    _git_shortlog ;;
1807
	show)        _git_show ;;
1808
	show-branch) _git_show_branch ;;
J
Junio C Hamano 已提交
1809
	stash)       _git_stash ;;
1810
	stage)       _git_add ;;
1811
	submodule)   _git_submodule ;;
1812
	svn)         _git_svn ;;
1813
	tag)         _git_tag ;;
1814 1815 1816
	whatchanged) _git_log ;;
	*)           COMPREPLY=() ;;
	esac
1817 1818 1819 1820
}

_gitk ()
{
1821 1822
	__git_has_doubledash && return

1823
	local cur="${COMP_WORDS[COMP_CWORD]}"
1824 1825 1826 1827 1828
	local g="$(git rev-parse --git-dir 2>/dev/null)"
	local merge=""
	if [ -f $g/MERGE_HEAD ]; then
		merge="--merge"
	fi
1829 1830
	case "$cur" in
	--*)
1831
		__gitcomp "--not --all $merge"
1832 1833 1834
		return
		;;
	esac
1835
	__git_complete_revlist
1836 1837
}

1838 1839 1840 1841
complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \
	|| complete -o default -o nospace -F _git git
complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \
	|| complete -o default -o nospace -F _gitk gitk
1842 1843 1844 1845 1846

# The following are necessary only for Cygwin, and only are needed
# when the user has tab-completed the executable name and consequently
# included the '.exe' suffix.
#
1847
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1848 1849
complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
	|| complete -o default -o nospace -F _git git.exe
1850
fi