git-completion.bash 28.5 KB
Newer Older
1 2 3
#
# bash completion support for core Git.
#
4
# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
5
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
6
# Distributed under the GNU General Public License, version 2.0.
7 8 9 10 11 12 13 14
#
# 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
15
#    *) common --long-options
16 17 18 19 20 21 22
#
# 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
#
23 24 25 26 27 28 29
#    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:
30 31 32 33 34 35
#        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.
#
36 37 38 39 40 41 42 43 44 45 46
# 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
#
47

48 49 50 51 52
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
esac

53 54
__gitdir ()
{
55 56 57 58 59 60 61 62 63 64 65 66 67
	if [ -z "$1" ]; then
		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
68 69
}

70 71
__git_ps1 ()
{
72 73 74 75
	local g="$(git rev-parse --git-dir 2>/dev/null)"
	if [ -n "$g" ]; then
		local r
		local b
76
		if [ -d "$g/rebase-apply" ]
77
		then
78
			if test -f "$g/rebase-apply/rebasing"
J
Junio C Hamano 已提交
79 80
			then
				r="|REBASE"
81
			elif test -f "$g/rebase-apply/applying"
J
Junio C Hamano 已提交
82 83 84 85 86
			then
				r="|AM"
			else
				r="|AM/REBASE"
			fi
87
			b="$(git symbolic-ref HEAD 2>/dev/null)"
88
		elif [ -f "$g/rebase-merge/interactive" ]
89 90
		then
			r="|REBASE-i"
91 92
			b="$(cat "$g/rebase-merge/head-name")"
		elif [ -d "$g/rebase-merge" ]
93 94
		then
			r="|REBASE-m"
95
			b="$(cat "$g/rebase-merge/head-name")"
96 97 98 99 100
		elif [ -f "$g/MERGE_HEAD" ]
		then
			r="|MERGING"
			b="$(git symbolic-ref HEAD 2>/dev/null)"
		else
101
			if [ -f "$g/BISECT_LOG" ]
102 103 104 105 106
			then
				r="|BISECTING"
			fi
			if ! b="$(git symbolic-ref HEAD 2>/dev/null)"
			then
107 108
				if ! b="$(git describe --exact-match HEAD 2>/dev/null)"
				then
109
					b="$(cut -c1-7 "$g/HEAD")..."
110
				fi
111 112 113
			fi
		fi

114
		if [ -n "$1" ]; then
115
			printf "$1" "${b##refs/heads/}$r"
116
		else
117
			printf " (%s)" "${b##refs/heads/}$r"
118 119 120 121
		fi
	fi
}

122 123 124 125 126 127 128 129 130 131 132 133
__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
}

134 135
__gitcomp ()
{
136
	local cur="${COMP_WORDS[COMP_CWORD]}"
137
	if [ $# -gt 2 ]; then
138 139
		cur="$3"
	fi
140 141 142 143 144
	case "$cur" in
	--*=)
		COMPREPLY=()
		;;
	*)
145 146 147 148
		local IFS=$'\n'
		COMPREPLY=($(compgen -P "$2" \
			-W "$(__gitcomp_1 "$1" "$4")" \
			-- "$cur"))
149 150
		;;
	esac
151 152
}

153 154
__git_heads ()
{
155
	local cmd i is_hash=y dir="$(__gitdir "$1")"
156 157 158 159 160 161 162 163
	if [ -d "$dir" ]; then
		for i in $(git --git-dir="$dir" \
			for-each-ref --format='%(refname)' \
			refs/heads ); do
			echo "${i#refs/heads/}"
		done
		return
	fi
164
	for i in $(git ls-remote "$1" 2>/dev/null); do
165 166 167 168 169 170 171 172 173
		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
}

174 175 176 177 178 179 180 181 182 183 184
__git_tags ()
{
	local cmd i is_hash=y dir="$(__gitdir "$1")"
	if [ -d "$dir" ]; then
		for i in $(git --git-dir="$dir" \
			for-each-ref --format='%(refname)' \
			refs/tags ); do
			echo "${i#refs/tags/}"
		done
		return
	fi
185
	for i in $(git ls-remote "$1" 2>/dev/null); do
186 187 188 189 190 191 192 193 194
		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
}

195 196
__git_refs ()
{
197
	local cmd i is_hash=y dir="$(__gitdir "$1")"
198
	if [ -d "$dir" ]; then
199 200 201 202 203 204 205 206 207 208 209 210
		if [ -e "$dir/HEAD" ]; then echo HEAD; fi
		for i in $(git --git-dir="$dir" \
			for-each-ref --format='%(refname)' \
			refs/tags refs/heads refs/remotes); do
			case "$i" in
				refs/tags/*)    echo "${i#refs/tags/}" ;;
				refs/heads/*)   echo "${i#refs/heads/}" ;;
				refs/remotes/*) echo "${i#refs/remotes/}" ;;
				*)              echo "$i" ;;
			esac
		done
		return
211
	fi
212
	for i in $(git ls-remote "$dir" 2>/dev/null); do
213 214 215 216 217
		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/}" ;;
218
		n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
219 220 221 222 223 224 225
		n,*) is_hash=y; echo "$i" ;;
		esac
	done
}

__git_refs2 ()
{
226 227 228
	local i
	for i in $(__git_refs "$1"); do
		echo "$i:$i"
229 230 231
	done
}

232 233 234
__git_refs_remotes ()
{
	local cmd i is_hash=y
235
	for i in $(git ls-remote "$1" 2>/dev/null); do
236 237 238 239 240 241 242 243 244 245 246 247 248
		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
}

249 250
__git_remotes ()
{
251
	local i ngoff IFS=$'\n' d="$(__gitdir)"
252
	shopt -q nullglob || ngoff=1
253
	shopt -s nullglob
254 255
	for i in "$d/remotes"/*; do
		echo ${i#$d/remotes/}
256
	done
257
	[ "$ngoff" ] && shopt -u nullglob
258
	for i in $(git --git-dir="$d" config --list); do
259 260 261 262 263 264 265
		case "$i" in
		remote.*.url=*)
			i="${i#remote.}"
			echo "${i/.url=*/}"
			;;
		esac
	done
266 267
}

268 269
__git_merge_strategies ()
{
270 271 272 273
	if [ -n "$__git_merge_strategylist" ]; then
		echo "$__git_merge_strategylist"
		return
	fi
274 275 276 277 278 279 280
	sed -n "/^all_strategies='/{
		s/^all_strategies='//
		s/'//
		p
		q
		}" "$(git --exec-path)/git-merge"
}
281 282
__git_merge_strategylist=
__git_merge_strategylist="$(__git_merge_strategies 2>/dev/null)"
283

284 285
__git_complete_file ()
{
286
	local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
287 288
	case "$cur" in
	?*:*)
289 290
		ref="${cur%%:*}"
		cur="${cur#*:}"
291 292
		case "$cur" in
		?*/*)
293 294
			pfx="${cur%/*}"
			cur="${cur##*/}"
295 296 297 298 299 300 301
			ls="$ref:$pfx"
			pfx="$pfx/"
			;;
		*)
			ls="$ref"
			;;
	    esac
302 303 304 305 306 307

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

308
		local IFS=$'\n'
309
		COMPREPLY=($(compgen -P "$pfx" \
310
			-W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
311 312 313 314 315 316 317 318
				| sed '/^100... blob /{
				           s,^.*	,,
				           s,$, ,
				       }
				       /^120000 blob /{
				           s,^.*	,,
				           s,$, ,
				       }
319 320 321 322 323 324 325 326
				       /^040000 tree /{
				           s,^.*	,,
				           s,$,/,
				       }
				       s/^.*	//')" \
			-- "$cur"))
		;;
	*)
327
		__gitcomp "$(__git_refs)"
328 329 330 331
		;;
	esac
}

332 333 334 335 336 337 338
__git_complete_revlist ()
{
	local pfx cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	*...*)
		pfx="${cur%...*}..."
		cur="${cur#*...}"
339
		__gitcomp "$(__git_refs)" "$pfx" "$cur"
340 341 342 343
		;;
	*..*)
		pfx="${cur%..*}.."
		cur="${cur#*..}"
344 345
		__gitcomp "$(__git_refs)" "$pfx" "$cur"
		;;
346
	*)
347
		__gitcomp "$(__git_refs)"
348 349 350 351
		;;
	esac
}

352 353
__git_commands ()
{
354 355 356 357
	if [ -n "$__git_commandlist" ]; then
		echo "$__git_commandlist"
		return
	fi
358 359 360 361
	local i IFS=" "$'\n'
	for i in $(git help -a|egrep '^ ')
	do
		case $i in
362
		*--*)             : helper pattern;;
363 364 365
		applymbox)        : ask gittus;;
		applypatch)       : ask gittus;;
		archimport)       : import;;
366
		cat-file)         : plumbing;;
367
		check-attr)       : plumbing;;
368 369
		check-ref-format) : plumbing;;
		commit-tree)      : plumbing;;
370 371
		cvsexportcommit)  : export;;
		cvsimport)        : import;;
372 373
		cvsserver)        : daemon;;
		daemon)           : daemon;;
374 375 376
		diff-files)       : plumbing;;
		diff-index)       : plumbing;;
		diff-tree)        : plumbing;;
S
Shawn O. Pearce 已提交
377
		fast-import)      : import;;
378
		fsck-objects)     : plumbing;;
379
		fetch-pack)       : plumbing;;
380
		fmt-merge-msg)    : plumbing;;
381
		for-each-ref)     : plumbing;;
382 383 384
		hash-object)      : plumbing;;
		http-*)           : transport;;
		index-pack)       : plumbing;;
385
		init-db)          : deprecated;;
386 387 388 389 390 391 392 393 394 395 396 397
		local-fetch)      : plumbing;;
		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;;
398 399 400
		prune)            : plumbing;;
		prune-packed)     : plumbing;;
		quiltimport)      : import;;
401 402
		read-tree)        : plumbing;;
		receive-pack)     : plumbing;;
403
		reflog)           : plumbing;;
404
		repo-config)      : deprecated;;
405 406 407 408 409 410 411 412 413 414 415
		rerere)           : plumbing;;
		rev-list)         : plumbing;;
		rev-parse)        : plumbing;;
		runstatus)        : plumbing;;
		sh-setup)         : internal;;
		shell)            : daemon;;
		send-pack)        : plumbing;;
		show-index)       : plumbing;;
		ssh-*)            : transport;;
		stripspace)       : plumbing;;
		symbolic-ref)     : plumbing;;
416
		tar-tree)         : deprecated;;
417 418
		unpack-file)      : plumbing;;
		unpack-objects)   : plumbing;;
419
		update-index)     : plumbing;;
420 421 422 423 424
		update-ref)       : plumbing;;
		update-server-info) : daemon;;
		upload-archive)   : plumbing;;
		upload-pack)      : plumbing;;
		write-tree)       : plumbing;;
425
		verify-tag)       : plumbing;;
426 427 428 429
		*) echo $i;;
		esac
	done
}
430 431
__git_commandlist=
__git_commandlist="$(__git_commands 2>/dev/null)"
432

433 434
__git_aliases ()
{
435
	local i IFS=$'\n'
436
	for i in $(git --git-dir="$(__gitdir)" config --list); do
437 438 439 440 441 442 443
		case "$i" in
		alias.*)
			i="${i#alias.}"
			echo "${i/=*/}"
			;;
		esac
	done
444 445 446 447
}

__git_aliased_command ()
{
448
	local word cmdline=$(git --git-dir="$(__gitdir)" \
449
		config --get "alias.$1")
450 451 452 453 454 455 456 457
	for word in $cmdline; do
		if [ "${word##-*}" ]; then
			echo $word
			return
		fi
	done
}

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
__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
}

474 475 476 477 478 479 480 481 482 483 484 485
__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
}

486 487 488 489
__git_whitespacelist="nowarn warn error error-all strip"

_git_am ()
{
490
	local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
491
	if [ -d "$dir"/rebase-apply ]; then
492
		__gitcomp "--skip --resolved --abort"
493 494 495 496
		return
	fi
	case "$cur" in
	--whitespace=*)
497
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
498 499 500
		return
		;;
	--*)
501
		__gitcomp "
502 503
			--signoff --utf8 --binary --3way --interactive
			--whitespace=
504
			"
505 506 507 508 509 510 511 512 513 514
		return
	esac
	COMPREPLY=()
}

_git_apply ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--whitespace=*)
515
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
516 517 518
		return
		;;
	--*)
519
		__gitcomp "
520 521 522 523
			--stat --numstat --summary --check --index
			--cached --index-info --reverse --reject --unidiff-zero
			--apply --no-add --exclude=
			--whitespace= --inaccurate-eof --verbose
524
			"
525 526 527 528 529
		return
	esac
	COMPREPLY=()
}

530 531
_git_add ()
{
532 533
	__git_has_doubledash && return

534 535 536
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
537 538 539 540
		__gitcomp "
			--interactive --refresh --patch --update --dry-run
			--ignore-errors
			"
541 542 543 544 545
		return
	esac
	COMPREPLY=()
}

546 547
_git_bisect ()
{
548 549
	__git_has_doubledash && return

550
	local subcommands="start bad good skip reset visualize replay log run"
551 552 553
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
		__gitcomp "$subcommands"
554 555 556
		return
	fi

557
	case "$subcommand" in
558
	bad|good|reset|skip)
559 560 561 562 563 564 565 566
		__gitcomp "$(__git_refs)"
		;;
	*)
		COMPREPLY=()
		;;
	esac
}

567 568
_git_branch ()
{
569 570 571 572 573 574 575 576 577 578 579
	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 已提交
580 581 582 583 584
	case "${COMP_WORDS[COMP_CWORD]}" in
	--*=*)	COMPREPLY=() ;;
	--*)
		__gitcomp "
			--color --no-color --verbose --abbrev= --no-abbrev
585
			--track --no-track --contains --merged --no-merged
S
SZEDER Gábor 已提交
586 587
			"
		;;
588 589 590 591 592 593 594
	*)
		if [ $only_local_ref = "y" -a $has_r = "n" ]; then
			__gitcomp "$(__git_heads)"
		else
			__gitcomp "$(__git_refs)"
		fi
		;;
S
SZEDER Gábor 已提交
595
	esac
596 597
}

598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
_git_bundle ()
{
	local mycword="$COMP_CWORD"
	case "${COMP_WORDS[0]}" in
	git)
		local cmd="${COMP_WORDS[2]}"
		mycword="$((mycword-1))"
		;;
	git-bundle*)
		local cmd="${COMP_WORDS[1]}"
		;;
	esac
	case "$mycword" in
	1)
		__gitcomp "create list-heads verify unbundle"
		;;
	2)
		# looking for a file
		;;
	*)
		case "$cmd" in
			create)
				__git_complete_revlist
			;;
		esac
		;;
	esac
}

627 628
_git_checkout ()
{
629 630
	__git_has_doubledash && return

631
	__gitcomp "$(__git_refs)"
632 633
}

634 635 636 637 638
_git_cherry ()
{
	__gitcomp "$(__git_refs)"
}

639 640 641 642 643
_git_cherry_pick ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
644
		__gitcomp "--edit --no-commit"
645 646
		;;
	*)
647
		__gitcomp "$(__git_refs)"
648 649 650 651
		;;
	esac
}

652 653
_git_commit ()
{
654 655
	__git_has_doubledash && return

656 657 658
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
659
		__gitcomp "
660 661
			--all --author= --signoff --verify --no-verify
			--edit --amend --include --only
662
			"
663 664 665 666 667
		return
	esac
	COMPREPLY=()
}

668 669 670 671 672
_git_describe ()
{
	__gitcomp "$(__git_refs)"
}

673 674
_git_diff ()
{
675 676
	__git_has_doubledash && return

677 678 679 680 681 682 683 684 685 686
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--cached --stat --numstat --shortstat --summary
			--patch-with-stat --name-only --name-status --color
			--no-color --color-words --no-renames --check
			--full-index --binary --abbrev --diff-filter
			--find-copies-harder --pickaxe-all --pickaxe-regex
			--text --ignore-space-at-eol --ignore-space-change
			--ignore-all-space --exit-code --quiet --ext-diff
687 688
			--no-ext-diff
			--no-prefix --src-prefix= --dst-prefix=
689
			--base --ours --theirs
690
			"
691 692 693
		return
		;;
	esac
694 695 696 697 698
	__git_complete_file
}

_git_diff_tree ()
{
699
	__gitcomp "$(__git_refs)"
700 701 702 703 704 705 706 707
}

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

	case "${COMP_WORDS[0]},$COMP_CWORD" in
	git-fetch*,1)
708
		__gitcomp "$(__git_remotes)"
709 710
		;;
	git,2)
711
		__gitcomp "$(__git_remotes)"
712 713 714 715
		;;
	*)
		case "$cur" in
		*:*)
716 717 718 719 720 721
			local pfx=""
			case "$COMP_WORDBREAKS" in
			*:*) : great ;;
			*)   pfx="${cur%%:*}:" ;;
			esac
			__gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
722 723 724 725 726 727 728
			;;
		*)
			local remote
			case "${COMP_WORDS[0]}" in
			git-fetch) remote="${COMP_WORDS[1]}" ;;
			git)       remote="${COMP_WORDS[2]}" ;;
			esac
729
			__gitcomp "$(__git_refs2 "$remote")"
730 731 732 733 734 735
			;;
		esac
		;;
	esac
}

736 737 738 739 740
_git_format_patch ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
741
		__gitcomp "
742 743 744
			--stdout --attach --thread
			--output-directory
			--numbered --start-number
745
			--numbered-files
746 747 748 749
			--keep-subject
			--signoff
			--in-reply-to=
			--full-index --binary
750
			--not --all
751
			--cover-letter
752
			--no-prefix --src-prefix= --dst-prefix=
753
			"
754 755 756 757 758 759
		return
		;;
	esac
	__git_complete_revlist
}

760 761 762 763 764
_git_gc ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
765
		__gitcomp "--prune --aggressive"
766 767 768 769 770 771
		return
		;;
	esac
	COMPREPLY=()
}

772 773
_git_ls_remote ()
{
774
	__gitcomp "$(__git_remotes)"
775 776 777 778 779 780 781 782 783
}

_git_ls_tree ()
{
	__git_complete_file
}

_git_log ()
{
784 785
	__git_has_doubledash && return

786 787 788
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--pretty=*)
789
		__gitcomp "
790
			oneline short medium full fuller email raw
791
			" "" "${cur##--pretty=}"
792 793
		return
		;;
794 795 796 797 798 799
	--date=*)
		__gitcomp "
			relative iso8601 rfc2822 short local default
		" "" "${cur##--date=}"
		return
		;;
800
	--*)
801
		__gitcomp "
802 803
			--max-count= --max-age= --since= --after=
			--min-age= --before= --until=
804
			--root --topo-order --date-order --reverse
805
			--no-merges --follow
806
			--abbrev-commit --abbrev=
807
			--relative-date --date=
808 809
			--author= --committer= --grep=
			--all-match
810
			--pretty= --name-status --name-only --raw
811
			--not --all
812
			--left-right --cherry-pick
813
			--graph
814 815 816
			--stat --numstat --shortstat
			--decorate --diff-filter=
			--color-words --walk-reflogs
817
			"
818 819 820
		return
		;;
	esac
821
	__git_complete_revlist
822 823
}

824 825 826
_git_merge ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
827 828
	case "${COMP_WORDS[COMP_CWORD-1]}" in
	-s|--strategy)
829
		__gitcomp "$(__git_merge_strategies)"
830 831
		return
	esac
832
	case "$cur" in
833
	--strategy=*)
834
		__gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
835 836
		return
		;;
837
	--*)
838
		__gitcomp "
839
			--no-commit --no-stat --log --no-log --squash --strategy
840
			"
841 842
		return
	esac
843
	__gitcomp "$(__git_refs)"
844 845
}

846 847
_git_merge_base ()
{
848
	__gitcomp "$(__git_refs)"
849 850
}

851 852
_git_name_rev ()
{
853
	__gitcomp "--tags --all --stdin"
854 855
}

856 857 858 859 860 861
_git_pull ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"

	case "${COMP_WORDS[0]},$COMP_CWORD" in
	git-pull*,1)
862
		__gitcomp "$(__git_remotes)"
863 864
		;;
	git,2)
865
		__gitcomp "$(__git_remotes)"
866 867 868 869 870 871 872
		;;
	*)
		local remote
		case "${COMP_WORDS[0]}" in
		git-pull)  remote="${COMP_WORDS[1]}" ;;
		git)       remote="${COMP_WORDS[2]}" ;;
		esac
873
		__gitcomp "$(__git_refs "$remote")"
874 875 876 877 878 879 880 881 882 883
		;;
	esac
}

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

	case "${COMP_WORDS[0]},$COMP_CWORD" in
	git-push*,1)
884
		__gitcomp "$(__git_remotes)"
885 886
		;;
	git,2)
887
		__gitcomp "$(__git_remotes)"
888 889 890 891 892 893 894 895 896
		;;
	*)
		case "$cur" in
		*:*)
			local remote
			case "${COMP_WORDS[0]}" in
			git-push)  remote="${COMP_WORDS[1]}" ;;
			git)       remote="${COMP_WORDS[2]}" ;;
			esac
897 898 899 900 901 902 903 904

			local pfx=""
			case "$COMP_WORDBREAKS" in
			*:*) : great ;;
			*)   pfx="${cur%%:*}:" ;;
			esac

			__gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
905
			;;
906 907 908
		+*)
			__gitcomp "$(__git_refs)" + "${cur#+}"
			;;
909
		*)
910
			__gitcomp "$(__git_refs)"
911 912 913 914 915 916
			;;
		esac
		;;
	esac
}

917 918
_git_rebase ()
{
919
	local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
920
	if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
921
		__gitcomp "--continue --skip --abort"
922 923
		return
	fi
924 925
	case "${COMP_WORDS[COMP_CWORD-1]}" in
	-s|--strategy)
926
		__gitcomp "$(__git_merge_strategies)"
927 928
		return
	esac
929
	case "$cur" in
930
	--strategy=*)
931
		__gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
932 933
		return
		;;
934
	--*)
935
		__gitcomp "--onto --merge --strategy --interactive"
936 937
		return
	esac
938
	__gitcomp "$(__git_refs)"
939 940
}

941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
_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
			--suppress-cc --suppress-from --thread --to"
		return
		;;
	esac
	COMPREPLY=()
}

959
_git_config ()
960 961 962 963 964
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	local prv="${COMP_WORDS[COMP_CWORD-1]}"
	case "$prv" in
	branch.*.remote)
965
		__gitcomp "$(__git_remotes)"
966 967 968
		return
		;;
	branch.*.merge)
969
		__gitcomp "$(__git_refs)"
970 971 972 973 974
		return
		;;
	remote.*.fetch)
		local remote="${prv#remote.}"
		remote="${remote%.fetch}"
975
		__gitcomp "$(__git_refs_remotes "$remote")"
976 977 978 979 980
		return
		;;
	remote.*.push)
		local remote="${prv#remote.}"
		remote="${remote%.push}"
981
		__gitcomp "$(git --git-dir="$(__gitdir)" \
982
			for-each-ref --format='%(refname):%(refname)' \
983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998
			refs/heads)"
		return
		;;
	pull.twohead|pull.octopus)
		__gitcomp "$(__git_merge_strategies)"
		return
		;;
	color.branch|color.diff|color.status)
		__gitcomp "always never auto"
		return
		;;
	color.*.*)
		__gitcomp "
			black red green yellow blue magenta cyan white
			bold dim ul blink reverse
			"
999 1000 1001 1002 1003 1004 1005 1006 1007
		return
		;;
	*.*)
		COMPREPLY=()
		return
		;;
	esac
	case "$cur" in
	--*)
1008
		__gitcomp "
1009
			--global --system --file=
1010
			--list --replace-all
1011
			--get --get-all --get-regexp
1012
			--add --unset --unset-all
1013
			--remove-section --rename-section
1014
			"
1015 1016 1017 1018 1019
		return
		;;
	branch.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1020
		__gitcomp "remote merge" "$pfx" "$cur"
1021 1022 1023 1024 1025
		return
		;;
	branch.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
1026
		__gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1027 1028 1029 1030 1031
		return
		;;
	remote.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1032 1033 1034 1035
		__gitcomp "
			url fetch push skipDefaultUpdate
			receivepack uploadpack tagopt
			" "$pfx" "$cur"
1036 1037 1038 1039 1040
		return
		;;
	remote.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
1041
		__gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1042 1043 1044
		return
		;;
	esac
1045
	__gitcomp "
1046 1047 1048 1049 1050 1051
		apply.whitespace
		core.fileMode
		core.gitProxy
		core.ignoreStat
		core.preferSymlinkRefs
		core.logAllRefUpdates
1052
		core.loosecompression
1053 1054 1055 1056
		core.repositoryFormatVersion
		core.sharedRepository
		core.warnAmbiguousRefs
		core.compression
1057 1058
		core.packedGitWindowSize
		core.packedGitLimit
1059
		clean.requireForce
1060 1061 1062 1063 1064
		color.branch
		color.branch.current
		color.branch.local
		color.branch.remote
		color.branch.plain
1065
		color.diff
1066 1067 1068 1069 1070 1071 1072
		color.diff.plain
		color.diff.meta
		color.diff.frag
		color.diff.old
		color.diff.new
		color.diff.commit
		color.diff.whitespace
1073 1074
		color.pager
		color.status
1075 1076 1077 1078 1079 1080 1081 1082
		color.status.header
		color.status.added
		color.status.changed
		color.status.untracked
		diff.renameLimit
		diff.renames
		fetch.unpackLimit
		format.headers
1083
		format.subjectprefix
1084 1085
		gitcvs.enabled
		gitcvs.logfile
1086
		gitcvs.allbinary
1087 1088
		gitcvs.dbname gitcvs.dbdriver gitcvs.dbuser gitcvs.dbpass
		gitcvs.dbtablenameprefix
1089
		gc.packrefs
1090 1091 1092 1093
		gc.reflogexpire
		gc.reflogexpireunreachable
		gc.rerereresolved
		gc.rerereunresolved
1094 1095 1096 1097 1098 1099
		http.sslVerify
		http.sslCert
		http.sslKey
		http.sslCAInfo
		http.sslCAPath
		http.maxRequests
1100 1101
		http.lowSpeedLimit
		http.lowSpeedTime
1102
		http.noEPSV
1103 1104 1105
		i18n.commitEncoding
		i18n.logOutputEncoding
		log.showroot
1106
		merge.tool
1107 1108
		merge.summary
		merge.verbosity
1109
		pack.window
1110
		pack.depth
1111 1112 1113 1114
		pack.windowMemory
		pack.compression
		pack.deltaCacheSize
		pack.deltaCacheLimit
1115 1116
		pull.octopus
		pull.twohead
1117
		repack.useDeltaBaseOffset
1118 1119 1120
		showbranch.default
		tar.umask
		transfer.unpackLimit
1121 1122
		receive.unpackLimit
		receive.denyNonFastForwards
1123 1124 1125
		user.name
		user.email
		user.signingkey
1126
		branch. remote.
1127
	"
1128 1129
}

1130 1131
_git_remote ()
{
1132 1133 1134
	local subcommands="add rm show prune update"
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
1135
		__gitcomp "$subcommands"
1136 1137 1138
		return
	fi

1139
	case "$subcommand" in
1140
	rm|show|prune)
1141 1142
		__gitcomp "$(__git_remotes)"
		;;
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
	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"
		;;
1155 1156 1157 1158 1159 1160
	*)
		COMPREPLY=()
		;;
	esac
}

1161 1162
_git_reset ()
{
1163 1164
	__git_has_doubledash && return

1165
	local cur="${COMP_WORDS[COMP_CWORD]}"
1166 1167 1168 1169 1170 1171 1172
	case "$cur" in
	--*)
		__gitcomp "--mixed --hard --soft"
		return
		;;
	esac
	__gitcomp "$(__git_refs)"
1173 1174
}

1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
_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=()
}

1189 1190
_git_shortlog ()
{
1191 1192
	__git_has_doubledash && return

1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210
	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
}

1211 1212 1213 1214 1215
_git_show ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--pretty=*)
1216
		__gitcomp "
1217
			oneline short medium full fuller email raw
1218
			" "" "${cur##--pretty=}"
1219 1220 1221
		return
		;;
	--*)
1222
		__gitcomp "--pretty="
1223 1224 1225 1226 1227 1228
		return
		;;
	esac
	__git_complete_file
}

1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244
_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 已提交
1245 1246
_git_stash ()
{
1247
	local subcommands='save list show apply clear drop pop create'
1248 1249
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
1250
		__gitcomp "$subcommands"
1251 1252 1253 1254 1255 1256 1257 1258 1259 1260
	else
		local cur="${COMP_WORDS[COMP_CWORD]}"
		case "$subcommand,$cur" in
		save,--*)
			__gitcomp "--keep-index"
			;;
		*)
			COMPREPLY=()
			;;
		esac
1261
	fi
J
Junio C Hamano 已提交
1262 1263
}

1264 1265
_git_submodule ()
{
1266 1267
	__git_has_doubledash && return

1268 1269
	local subcommands="add status init update"
	if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1270 1271 1272 1273 1274 1275
		local cur="${COMP_WORDS[COMP_CWORD]}"
		case "$cur" in
		--*)
			__gitcomp "--quiet --cached"
			;;
		*)
1276
			__gitcomp "$subcommands"
1277 1278 1279 1280 1281 1282
			;;
		esac
		return
	fi
}

1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360
_git_svn ()
{
	local subcommands="
		init fetch clone rebase dcommit log find-rev
		set-tree commit-diff info create-ignore propget
		proplist show-ignore show-externals
		"
	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
			--repack-flags --user-log-author $remote_opts
			"
		local init_opts="
			--template= --shared= --trunk= --tags=
			--branches= --stdlayout --minimize-url
			--no-metadata --use-svm-props --use-svnsync-props
			--rewrite-root= $remote_opts
			"
		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
				--fetch-all --no-rebase $cmt_opts $fc_opts
				"
			;;
		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
				--authors-file=
				"
			;;
		rebase,--*)
			__gitcomp "
				--merge --verbose --strategy= --local
				--fetch-all $fc_opts
				"
			;;
		commit-diff,--*)
			__gitcomp "--message= --file= --revision= $cmt_opts"
			;;
		info,--*)
			__gitcomp "--url"
			;;
		*)
			COMPREPLY=()
			;;
		esac
	fi
}

1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
_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=()
		;;
	-*|tag|git-tag)
		if [ $f = 1 ]; then
			__gitcomp "$(__git_tags)"
		else
			COMPREPLY=()
		fi
		;;
	*)
		__gitcomp "$(__git_refs)"
		;;
	esac
}

1395 1396
_git ()
{
1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409
	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="." ;;
		--version|--help|-p|--paginate) ;;
		*) command="$i"; break ;;
		esac
		c=$((++c))
	done

1410
	if [ -z "$command" ]; then
1411 1412
		case "${COMP_WORDS[COMP_CWORD]}" in
		--*=*) COMPREPLY=() ;;
1413
		--*)   __gitcomp "
1414
			--paginate
1415 1416 1417 1418 1419
			--no-pager
			--git-dir=
			--bare
			--version
			--exec-path
1420 1421
			--work-tree=
			--help
1422 1423
			"
			;;
1424 1425 1426
		*)     __gitcomp "$(__git_commands) $(__git_aliases)" ;;
		esac
		return
1427
	fi
1428

1429 1430
	local expansion=$(__git_aliased_command "$command")
	[ "$expansion" ] && command="$expansion"
1431

1432
	case "$command" in
1433
	am)          _git_am ;;
1434
	add)         _git_add ;;
1435
	apply)       _git_apply ;;
1436
	bisect)      _git_bisect ;;
1437
	bundle)      _git_bundle ;;
1438 1439
	branch)      _git_branch ;;
	checkout)    _git_checkout ;;
1440
	cherry)      _git_cherry ;;
1441
	cherry-pick) _git_cherry_pick ;;
1442
	commit)      _git_commit ;;
1443
	config)      _git_config ;;
1444
	describe)    _git_describe ;;
1445 1446
	diff)        _git_diff ;;
	fetch)       _git_fetch ;;
1447
	format-patch) _git_format_patch ;;
1448
	gc)          _git_gc ;;
1449 1450 1451
	log)         _git_log ;;
	ls-remote)   _git_ls_remote ;;
	ls-tree)     _git_ls_tree ;;
1452
	merge)       _git_merge;;
1453
	merge-base)  _git_merge_base ;;
1454
	name-rev)    _git_name_rev ;;
1455 1456
	pull)        _git_pull ;;
	push)        _git_push ;;
1457
	rebase)      _git_rebase ;;
1458
	remote)      _git_remote ;;
1459
	reset)       _git_reset ;;
1460
	rm)          _git_rm ;;
1461
	send-email)  _git_send_email ;;
1462
	shortlog)    _git_shortlog ;;
1463
	show)        _git_show ;;
1464
	show-branch) _git_show_branch ;;
J
Junio C Hamano 已提交
1465
	stash)       _git_stash ;;
1466
	submodule)   _git_submodule ;;
1467
	svn)         _git_svn ;;
1468
	tag)         _git_tag ;;
1469 1470 1471
	whatchanged) _git_log ;;
	*)           COMPREPLY=() ;;
	esac
1472 1473 1474 1475
}

_gitk ()
{
1476 1477
	__git_has_doubledash && return

1478
	local cur="${COMP_WORDS[COMP_CWORD]}"
1479 1480 1481 1482 1483
	local g="$(git rev-parse --git-dir 2>/dev/null)"
	local merge=""
	if [ -f $g/MERGE_HEAD ]; then
		merge="--merge"
	fi
1484 1485
	case "$cur" in
	--*)
1486
		__gitcomp "--not --all $merge"
1487 1488 1489
		return
		;;
	esac
1490
	__git_complete_revlist
1491 1492 1493
}

complete -o default -o nospace -F _git git
1494
complete -o default -o nospace -F _gitk gitk
1495 1496 1497 1498 1499

# 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.
#
1500
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1501
complete -o default -o nospace -F _git git.exe
1502
fi