git-completion.bash 38.0 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
		if [ -n "${__git_dir-}" ]; then
66 67 68 69 70 71 72 73 74 75 76
			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
	local g="$(__gitdir)"
84 85 86
	if [ -n "$g" ]; then
		local r
		local b
87 88
		if [ -d "$g/rebase-apply" ]; then
			if [ -f "$g/rebase-apply/rebasing" ]; then
J
Junio C Hamano 已提交
89
				r="|REBASE"
90
		elif [ -f "$g/rebase-apply/applying" ]; then
J
Junio C Hamano 已提交
91 92 93 94
				r="|AM"
			else
				r="|AM/REBASE"
			fi
95
			b="$(git symbolic-ref HEAD 2>/dev/null)"
96
		elif [ -f "$g/rebase-merge/interactive" ]; then
97
			r="|REBASE-i"
98
			b="$(cat "$g/rebase-merge/head-name")"
99
		elif [ -d "$g/rebase-merge" ]; then
100
			r="|REBASE-m"
101
			b="$(cat "$g/rebase-merge/head-name")"
102
		elif [ -f "$g/MERGE_HEAD" ]; then
103 104 105
			r="|MERGING"
			b="$(git symbolic-ref HEAD 2>/dev/null)"
		else
106
			if [ -f "$g/BISECT_LOG" ]; then
107 108
				r="|BISECTING"
			fi
109 110
			if ! b="$(git symbolic-ref HEAD 2>/dev/null)"; then
				if ! b="$(git describe --exact-match HEAD 2>/dev/null)"; then
111 112 113
					if [ -r "$g/HEAD" ]; then
						b="$(cut -c1-7 "$g/HEAD")..."
					fi
114
				fi
115 116 117
			fi
		fi

118 119
		local w
		local i
120
		local c
121

122
		if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
123 124 125 126 127
			if [ "true" = "$(git config --bool core.bare 2>/dev/null)" ]; then
				c="BARE:"
			else
				b="GIT_DIR!"
			fi
128 129 130 131 132 133 134 135 136 137 138
		elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
			if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
				if [ "$(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
139 140 141 142
				fi
			fi
		fi

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

153
# __gitcomp_1 requires 2 arguments
154 155 156 157 158 159 160 161 162 163 164 165
__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
}

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

187
# __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
188 189
__git_heads ()
{
190
	local cmd i is_hash=y dir="$(__gitdir "${1-}")"
191
	if [ -d "$dir" ]; then
192 193
		git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
			refs/heads
194 195
		return
	fi
196
	for i in $(git ls-remote "${1-}" 2>/dev/null); do
197 198 199 200 201 202 203 204 205
		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
}

206
# __git_tags accepts 0 or 1 arguments (to pass to __gitdir)
207 208
__git_tags ()
{
209
	local cmd i is_hash=y dir="$(__gitdir "${1-}")"
210
	if [ -d "$dir" ]; then
211 212
		git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
			refs/tags
213 214
		return
	fi
215
	for i in $(git ls-remote "${1-}" 2>/dev/null); do
216 217 218 219 220 221 222 223 224
		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
}

225
# __git_refs accepts 0 or 1 arguments (to pass to __gitdir)
226 227
__git_refs ()
{
228
	local i is_hash=y dir="$(__gitdir "${1-}")"
S
SZEDER Gábor 已提交
229
	local cur="${COMP_WORDS[COMP_CWORD]}" format refs
230
	if [ -d "$dir" ]; then
S
SZEDER Gábor 已提交
231 232 233 234 235 236 237 238 239 240 241 242 243
		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
244
		return
245
	fi
246
	for i in $(git ls-remote "$dir" 2>/dev/null); do
247 248 249 250 251
		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/}" ;;
252
		n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
253 254 255 256 257
		n,*) is_hash=y; echo "$i" ;;
		esac
	done
}

258
# __git_refs2 requires 1 argument (to pass to __git_refs)
259 260
__git_refs2 ()
{
261 262 263
	local i
	for i in $(__git_refs "$1"); do
		echo "$i:$i"
264 265 266
	done
}

267
# __git_refs_remotes requires 1 argument (to pass to ls-remote)
268 269 270
__git_refs_remotes ()
{
	local cmd i is_hash=y
271
	for i in $(git ls-remote "$1" 2>/dev/null); do
272 273 274 275 276 277 278 279 280 281 282 283 284
		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
}

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

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

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

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

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

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

390 391 392 393
__git_complete_remote_or_refspec ()
{
	local cmd="${COMP_WORDS[1]}"
	local cur="${COMP_WORDS[COMP_CWORD]}"
394
	local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
395 396 397
	while [ $c -lt $COMP_CWORD ]; do
		i="${COMP_WORDS[c]}"
		case "$i" in
398
		--all|--mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
399 400 401 402 403 404 405 406 407
		-*) ;;
		*) remote="$i"; break ;;
		esac
		c=$((++c))
	done
	if [ -z "$remote" ]; then
		__gitcomp "$(__git_remotes)"
		return
	fi
408 409 410 411
	if [ $no_complete_refspec = 1 ]; then
		COMPREPLY=()
		return
	fi
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
	[ "$remote" = "." ] && remote=
	case "$cur" in
	*:*)
		case "$COMP_WORDBREAKS" in
		*:*) : great ;;
		*)   pfx="${cur%%:*}:" ;;
		esac
		cur="${cur#*:}"
		lhs=0
		;;
	+*)
		pfx="+"
		cur="${cur#+}"
		;;
	esac
	case "$cmd" in
	fetch)
		if [ $lhs = 1 ]; then
			__gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur"
		else
			__gitcomp "$(__git_refs)" "$pfx" "$cur"
		fi
		;;
	pull)
		if [ $lhs = 1 ]; then
			__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
		else
			__gitcomp "$(__git_refs)" "$pfx" "$cur"
		fi
		;;
	push)
		if [ $lhs = 1 ]; then
			__gitcomp "$(__git_refs)" "$pfx" "$cur"
		else
			__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
		fi
		;;
	esac
}

452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
__git_complete_strategy ()
{
	case "${COMP_WORDS[COMP_CWORD-1]}" in
	-s|--strategy)
		__gitcomp "$(__git_merge_strategies)"
		return 0
	esac
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--strategy=*)
		__gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
		return 0
		;;
	esac
	return 1
}

469
__git_all_commands ()
470
{
471
	if [ -n "${__git_all_commandlist-}" ]; then
472
		echo "$__git_all_commandlist"
473 474
		return
	fi
475 476
	local i IFS=" "$'\n'
	for i in $(git help -a|egrep '^ ')
477 478 479 480 481 482 483 484 485 486 487 488
	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 ()
{
489
	if [ -n "${__git_porcelain_commandlist-}" ]; then
490 491 492 493 494
		echo "$__git_porcelain_commandlist"
		return
	fi
	local i IFS=" "$'\n'
	for i in "help" $(__git_all_commands)
495 496
	do
		case $i in
497
		*--*)             : helper pattern;;
498 499 500
		applymbox)        : ask gittus;;
		applypatch)       : ask gittus;;
		archimport)       : import;;
501
		cat-file)         : plumbing;;
502
		check-attr)       : plumbing;;
503
		check-ref-format) : plumbing;;
504
		checkout-index)   : plumbing;;
505
		commit-tree)      : plumbing;;
506
		count-objects)    : infrequent;;
507 508
		cvsexportcommit)  : export;;
		cvsimport)        : import;;
509 510
		cvsserver)        : daemon;;
		daemon)           : daemon;;
511 512 513
		diff-files)       : plumbing;;
		diff-index)       : plumbing;;
		diff-tree)        : plumbing;;
S
Shawn O. Pearce 已提交
514
		fast-import)      : import;;
515
		fast-export)      : export;;
516
		fsck-objects)     : plumbing;;
517
		fetch-pack)       : plumbing;;
518
		fmt-merge-msg)    : plumbing;;
519
		for-each-ref)     : plumbing;;
520 521 522
		hash-object)      : plumbing;;
		http-*)           : transport;;
		index-pack)       : plumbing;;
523
		init-db)          : deprecated;;
524
		local-fetch)      : plumbing;;
525 526 527 528
		lost-found)       : infrequent;;
		ls-files)         : plumbing;;
		ls-remote)        : plumbing;;
		ls-tree)          : plumbing;;
529 530 531 532 533 534 535 536 537 538 539
		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;;
540 541 542
		prune)            : plumbing;;
		prune-packed)     : plumbing;;
		quiltimport)      : import;;
543 544
		read-tree)        : plumbing;;
		receive-pack)     : plumbing;;
545
		reflog)           : plumbing;;
546
		repo-config)      : deprecated;;
547 548 549 550 551 552
		rerere)           : plumbing;;
		rev-list)         : plumbing;;
		rev-parse)        : plumbing;;
		runstatus)        : plumbing;;
		sh-setup)         : internal;;
		shell)            : daemon;;
553
		show-ref)         : plumbing;;
554 555 556 557 558
		send-pack)        : plumbing;;
		show-index)       : plumbing;;
		ssh-*)            : transport;;
		stripspace)       : plumbing;;
		symbolic-ref)     : plumbing;;
559
		tar-tree)         : deprecated;;
560 561
		unpack-file)      : plumbing;;
		unpack-objects)   : plumbing;;
562
		update-index)     : plumbing;;
563 564 565 566 567
		update-ref)       : plumbing;;
		update-server-info) : daemon;;
		upload-archive)   : plumbing;;
		upload-pack)      : plumbing;;
		write-tree)       : plumbing;;
568 569
		var)              : infrequent;;
		verify-pack)      : infrequent;;
570
		verify-tag)       : plumbing;;
571 572 573 574
		*) echo $i;;
		esac
	done
}
575 576
__git_porcelain_commandlist=
__git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)"
577

578 579
__git_aliases ()
{
580
	local i IFS=$'\n'
581
	for i in $(git --git-dir="$(__gitdir)" config --list); do
582 583 584 585 586 587 588
		case "$i" in
		alias.*)
			i="${i#alias.}"
			echo "${i/=*/}"
			;;
		esac
	done
589 590
}

591
# __git_aliased_command requires 1 argument
592 593
__git_aliased_command ()
{
594
	local word cmdline=$(git --git-dir="$(__gitdir)" \
595
		config --get "alias.$1")
596 597 598 599 600 601 602 603
	for word in $cmdline; do
		if [ "${word##-*}" ]; then
			echo $word
			return
		fi
	done
}

604
# __git_find_subcommand requires 1 argument
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
__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
}

621 622 623 624 625 626 627 628 629 630 631 632
__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
}

633
__git_whitespacelist="nowarn warn error error-all fix"
634 635 636

_git_am ()
{
637
	local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
638
	if [ -d "$dir"/rebase-apply ]; then
639
		__gitcomp "--skip --resolved --abort"
640 641 642 643
		return
	fi
	case "$cur" in
	--whitespace=*)
644
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
645 646 647
		return
		;;
	--*)
648
		__gitcomp "
649 650
			--signoff --utf8 --binary --3way --interactive
			--whitespace=
651
			"
652 653 654 655 656 657 658 659 660 661
		return
	esac
	COMPREPLY=()
}

_git_apply ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--whitespace=*)
662
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
663 664 665
		return
		;;
	--*)
666
		__gitcomp "
667 668 669 670
			--stat --numstat --summary --check --index
			--cached --index-info --reverse --reject --unidiff-zero
			--apply --no-add --exclude=
			--whitespace= --inaccurate-eof --verbose
671
			"
672 673 674 675 676
		return
	esac
	COMPREPLY=()
}

677 678
_git_add ()
{
679 680
	__git_has_doubledash && return

681 682 683
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
684 685
		__gitcomp "
			--interactive --refresh --patch --update --dry-run
686
			--ignore-errors --intent-to-add
687
			"
688 689 690 691 692
		return
	esac
	COMPREPLY=()
}

693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
_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
}

716 717
_git_bisect ()
{
718 719
	__git_has_doubledash && return

720
	local subcommands="start bad good skip reset visualize replay log run"
721 722 723
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
		__gitcomp "$subcommands"
724 725 726
		return
	fi

727
	case "$subcommand" in
728
	bad|good|reset|skip)
729 730 731 732 733 734 735 736
		__gitcomp "$(__git_refs)"
		;;
	*)
		COMPREPLY=()
		;;
	esac
}

737 738
_git_branch ()
{
739 740 741 742 743 744 745 746 747 748 749
	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 已提交
750 751 752 753
	case "${COMP_WORDS[COMP_CWORD]}" in
	--*)
		__gitcomp "
			--color --no-color --verbose --abbrev= --no-abbrev
754
			--track --no-track --contains --merged --no-merged
S
SZEDER Gábor 已提交
755 756
			"
		;;
757 758 759 760 761 762 763
	*)
		if [ $only_local_ref = "y" -a $has_r = "n" ]; then
			__gitcomp "$(__git_heads)"
		else
			__gitcomp "$(__git_refs)"
		fi
		;;
S
SZEDER Gábor 已提交
764
	esac
765 766
}

767 768
_git_bundle ()
{
769 770 771
	local cmd="${COMP_WORDS[2]}"
	case "$COMP_CWORD" in
	2)
772 773
		__gitcomp "create list-heads verify unbundle"
		;;
774
	3)
775 776 777 778 779 780 781 782 783 784 785 786
		# looking for a file
		;;
	*)
		case "$cmd" in
			create)
				__git_complete_revlist
			;;
		esac
		;;
	esac
}

787 788
_git_checkout ()
{
789 790
	__git_has_doubledash && return

791
	__gitcomp "$(__git_refs)"
792 793
}

794 795 796 797 798
_git_cherry ()
{
	__gitcomp "$(__git_refs)"
}

799 800 801 802 803
_git_cherry_pick ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
804
		__gitcomp "--edit --no-commit"
805 806
		;;
	*)
807
		__gitcomp "$(__git_refs)"
808 809 810 811
		;;
	esac
}

812 813 814 815 816 817 818 819 820 821 822 823 824 825
_git_clean ()
{
	__git_has_doubledash && return

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

826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
_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=()
}

851 852
_git_commit ()
{
853 854
	__git_has_doubledash && return

855 856 857
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
858
		__gitcomp "
859
			--all --author= --signoff --verify --no-verify
860
			--edit --amend --include --only --interactive
861
			"
862 863 864 865 866
		return
	esac
	COMPREPLY=()
}

867 868
_git_describe ()
{
869 870 871 872 873 874 875 876 877
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--all --tags --contains --abbrev= --candidates=
			--exact-match --debug --long --match --always
			"
		return
	esac
878 879 880
	__gitcomp "$(__git_refs)"
}

881
__git_diff_common_options="--stat --numstat --shortstat --summary
882 883
			--patch-with-stat --name-only --name-status --color
			--no-color --color-words --no-renames --check
884
			--full-index --binary --abbrev --diff-filter=
885
			--find-copies-harder
886 887
			--text --ignore-space-at-eol --ignore-space-change
			--ignore-all-space --exit-code --quiet --ext-diff
888 889
			--no-ext-diff
			--no-prefix --src-prefix= --dst-prefix=
890
			--inter-hunk-context=
891
			--patience
892 893 894 895 896 897 898 899 900 901 902 903 904
			--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
905
			"
906 907 908
		return
		;;
	esac
909 910 911
	__git_complete_file
}

912 913 914 915 916
__git_fetch_options="
	--quiet --verbose --append --upload-pack --force --keep --depth=
	--tags --no-tags
"

917 918
_git_fetch ()
{
919 920 921 922 923 924 925
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "$__git_fetch_options"
		return
		;;
	esac
926
	__git_complete_remote_or_refspec
927 928
}

929 930 931 932 933
_git_format_patch ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
934
		__gitcomp "
935 936 937
			--stdout --attach --thread
			--output-directory
			--numbered --start-number
938
			--numbered-files
939 940 941 942
			--keep-subject
			--signoff
			--in-reply-to=
			--full-index --binary
943
			--not --all
944
			--cover-letter
945
			--no-prefix --src-prefix= --dst-prefix=
946 947
			--inline --suffix= --ignore-if-in-upstream
			--subject-prefix=
948
			"
949 950 951 952 953 954
		return
		;;
	esac
	__git_complete_revlist
}

955 956 957 958 959
_git_gc ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
960
		__gitcomp "--prune --aggressive"
961 962 963 964 965 966
		return
		;;
	esac
	COMPREPLY=()
}

967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989
_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=()
}

990 991 992 993 994 995 996 997 998
_git_help ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--all --info --man --web"
		return
		;;
	esac
999 1000 1001 1002
	__gitcomp "$(__git_all_commands)
		attributes cli core-tutorial cvs-migration
		diffcore gitk glossary hooks ignore modules
		repository-layout tutorial tutorial-2
1003
		workflows
1004
		"
1005 1006
}

1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
_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=()
}

1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
_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=()
}

1045 1046
_git_ls_remote ()
{
1047
	__gitcomp "$(__git_remotes)"
1048 1049 1050 1051 1052 1053 1054
}

_git_ls_tree ()
{
	__git_complete_file
}

1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
# Options that go well for log, shortlog and gitk
__git_log_common_options="
	--not --all
	--branches --tags --remotes
	--first-parent --no-merges
	--max-count=
	--max-age= --since= --after=
	--min-age= --until= --before=
"
# Options that go well for log and gitk (not shortlog)
__git_log_gitk_options="
	--dense --sparse --full-history
	--simplify-merges --simplify-by-decoration
	--left-right
"
# Options that go well for log and shortlog (not gitk)
__git_log_shortlog_options="
	--author= --committer= --grep=
	--all-match
"

1076 1077
__git_log_pretty_formats="oneline short medium full fuller email raw format:"

1078 1079
_git_log ()
{
1080 1081
	__git_has_doubledash && return

1082
	local cur="${COMP_WORDS[COMP_CWORD]}"
1083 1084 1085 1086 1087
	local g="$(git rev-parse --git-dir 2>/dev/null)"
	local merge=""
	if [ -f $g/MERGE_HEAD ]; then
		merge="--merge"
	fi
1088 1089
	case "$cur" in
	--pretty=*)
1090
		__gitcomp "$__git_log_pretty_formats
1091
			" "" "${cur##--pretty=}"
1092 1093
		return
		;;
1094 1095 1096 1097 1098
	--format=*)
		__gitcomp "$__git_log_pretty_formats
			" "" "${cur##--format=}"
		return
		;;
1099 1100 1101 1102 1103 1104
	--date=*)
		__gitcomp "
			relative iso8601 rfc2822 short local default
		" "" "${cur##--date=}"
		return
		;;
1105
	--*)
1106
		__gitcomp "
1107 1108 1109
			$__git_log_common_options
			$__git_log_shortlog_options
			$__git_log_gitk_options
1110
			--root --topo-order --date-order --reverse
1111
			--follow
1112
			--abbrev-commit --abbrev=
1113
			--relative-date --date=
1114
			--pretty= --format= --oneline
1115
			--cherry-pick
1116
			--graph
1117 1118
			--decorate
			--walk-reflogs
1119
			--parents --children
1120
			$merge
1121
			$__git_diff_common_options
1122
			--pickaxe-all --pickaxe-regex
1123
			"
1124 1125 1126
		return
		;;
	esac
1127
	__git_complete_revlist
1128 1129
}

1130 1131 1132 1133 1134
__git_merge_options="
	--no-commit --no-stat --log --no-log --squash --strategy
	--commit --stat --no-squash --ff --no-ff
"

1135 1136
_git_merge ()
{
1137 1138
	__git_complete_strategy && return

1139 1140 1141
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
1142
		__gitcomp "$__git_merge_options"
1143 1144
		return
	esac
1145
	__gitcomp "$(__git_refs)"
1146 1147
}

1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
_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=()
}

1167 1168
_git_merge_base ()
{
1169
	__gitcomp "$(__git_refs)"
1170 1171
}

1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183
_git_mv ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--dry-run"
		return
		;;
	esac
	COMPREPLY=()
}

1184 1185
_git_name_rev ()
{
1186
	__gitcomp "--tags --all --stdin"
1187 1188
}

1189 1190
_git_pull ()
{
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
	__git_complete_strategy && return

	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--rebase --no-rebase
			$__git_merge_options
			$__git_fetch_options
		"
		return
		;;
	esac
1204
	__git_complete_remote_or_refspec
1205 1206 1207 1208
}

_git_push ()
{
1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "${COMP_WORDS[COMP_CWORD-1]}" in
	--repo)
		__gitcomp "$(__git_remotes)"
		return
	esac
	case "$cur" in
	--repo=*)
		__gitcomp "$(__git_remotes)" "" "${cur##--repo=}"
		return
		;;
	--*)
		__gitcomp "
			--all --mirror --tags --dry-run --force --verbose
			--receive-pack= --repo=
		"
		return
		;;
	esac
1228
	__git_complete_remote_or_refspec
1229 1230
}

1231 1232
_git_rebase ()
{
1233
	local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
1234
	if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1235
		__gitcomp "--continue --skip --abort"
1236 1237
		return
	fi
1238
	__git_complete_strategy && return
1239 1240
	case "$cur" in
	--*)
1241
		__gitcomp "--onto --merge --strategy --interactive"
1242 1243
		return
	esac
1244
	__gitcomp "$(__git_refs)"
1245 1246
}

1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257
_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
1258 1259
			--suppress-cc --suppress-from --thread --to
			--validate --no-validate"
1260 1261 1262 1263 1264 1265
		return
		;;
	esac
	COMPREPLY=()
}

1266
_git_config ()
1267 1268 1269 1270 1271
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	local prv="${COMP_WORDS[COMP_CWORD-1]}"
	case "$prv" in
	branch.*.remote)
1272
		__gitcomp "$(__git_remotes)"
1273 1274 1275
		return
		;;
	branch.*.merge)
1276
		__gitcomp "$(__git_refs)"
1277 1278 1279 1280 1281
		return
		;;
	remote.*.fetch)
		local remote="${prv#remote.}"
		remote="${remote%.fetch}"
1282
		__gitcomp "$(__git_refs_remotes "$remote")"
1283 1284 1285 1286 1287
		return
		;;
	remote.*.push)
		local remote="${prv#remote.}"
		remote="${remote%.push}"
1288
		__gitcomp "$(git --git-dir="$(__gitdir)" \
1289
			for-each-ref --format='%(refname):%(refname)' \
1290 1291 1292 1293 1294 1295 1296
			refs/heads)"
		return
		;;
	pull.twohead|pull.octopus)
		__gitcomp "$(__git_merge_strategies)"
		return
		;;
1297
	color.branch|color.diff|color.interactive|color.status|color.ui)
1298 1299 1300
		__gitcomp "always never auto"
		return
		;;
1301 1302 1303 1304
	color.pager)
		__gitcomp "false true"
		return
		;;
1305 1306
	color.*.*)
		__gitcomp "
1307
			normal black red green yellow blue magenta cyan white
1308 1309
			bold dim ul blink reverse
			"
1310 1311 1312 1313 1314 1315 1316 1317 1318
		return
		;;
	*.*)
		COMPREPLY=()
		return
		;;
	esac
	case "$cur" in
	--*)
1319
		__gitcomp "
1320
			--global --system --file=
1321
			--list --replace-all
1322
			--get --get-all --get-regexp
1323
			--add --unset --unset-all
1324
			--remove-section --rename-section
1325
			"
1326 1327 1328 1329 1330
		return
		;;
	branch.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1331
		__gitcomp "remote merge mergeoptions" "$pfx" "$cur"
1332 1333 1334 1335 1336
		return
		;;
	branch.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
1337
		__gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1338 1339 1340 1341 1342
		return
		;;
	remote.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1343
		__gitcomp "
1344
			url proxy fetch push mirror skipDefaultUpdate
1345 1346
			receivepack uploadpack tagopt
			" "$pfx" "$cur"
1347 1348 1349 1350 1351
		return
		;;
	remote.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
1352
		__gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1353 1354 1355
		return
		;;
	esac
1356
	__gitcomp "
1357
		apply.whitespace
1358 1359
		branch.autosetupmerge
		branch.autosetuprebase
1360
		clean.requireForce
1361 1362 1363 1364
		color.branch
		color.branch.current
		color.branch.local
		color.branch.plain
1365
		color.branch.remote
1366
		color.diff
1367
		color.diff.commit
1368
		color.diff.frag
1369
		color.diff.meta
1370
		color.diff.new
1371 1372
		color.diff.old
		color.diff.plain
1373
		color.diff.whitespace
1374 1375 1376 1377
		color.interactive
		color.interactive.header
		color.interactive.help
		color.interactive.prompt
1378 1379
		color.pager
		color.status
1380 1381
		color.status.added
		color.status.changed
1382
		color.status.header
1383
		color.status.nobranch
1384
		color.status.untracked
1385 1386 1387 1388 1389
		color.status.updated
		color.ui
		commit.template
		core.autocrlf
		core.bare
1390
		core.compression
1391 1392 1393
		core.deltaBaseCacheLimit
		core.editor
		core.excludesfile
1394
		core.fileMode
1395
		core.fsyncobjectfiles
1396
		core.gitProxy
1397
		core.ignoreCygwinFSTricks
1398 1399 1400 1401 1402
		core.ignoreStat
		core.logAllRefUpdates
		core.loosecompression
		core.packedGitLimit
		core.packedGitWindowSize
1403
		core.pager
1404
		core.preferSymlinkRefs
1405 1406
		core.preloadindex
		core.quotepath
1407
		core.repositoryFormatVersion
1408
		core.safecrlf
1409
		core.sharedRepository
1410 1411
		core.symlinks
		core.trustctime
1412
		core.warnAmbiguousRefs
1413 1414 1415 1416 1417
		core.whitespace
		core.worktree
		diff.autorefreshindex
		diff.external
		diff.mnemonicprefix
1418
		diff.renameLimit
1419
		diff.renameLimit.
1420 1421 1422
		diff.renames
		fetch.unpackLimit
		format.headers
1423 1424 1425 1426 1427 1428
		format.numbered
		format.pretty
		format.suffix
		gc.aggressiveWindow
		gc.auto
		gc.autopacklimit
1429
		gc.packrefs
1430
		gc.pruneexpire
1431 1432 1433 1434
		gc.reflogexpire
		gc.reflogexpireunreachable
		gc.rerereresolved
		gc.rerereunresolved
1435
		gitcvs.allbinary
1436
		gitcvs.dbTableNamePrefix
1437 1438 1439 1440 1441 1442
		gitcvs.dbdriver
		gitcvs.dbname
		gitcvs.dbpass
		gitcvs.dbuser
		gitcvs.enabled
		gitcvs.logfile
1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457
		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
1458 1459
		http.lowSpeedLimit
		http.lowSpeedTime
1460
		http.maxRequests
1461
		http.noEPSV
1462
		http.proxy
1463 1464 1465 1466 1467
		http.sslCAInfo
		http.sslCAPath
		http.sslCert
		http.sslKey
		http.sslVerify
1468 1469
		i18n.commitEncoding
		i18n.logOutputEncoding
1470 1471 1472 1473 1474 1475
		instaweb.browser
		instaweb.httpd
		instaweb.local
		instaweb.modulepath
		instaweb.port
		log.date
1476
		log.showroot
1477 1478 1479 1480 1481
		man.viewer
		merge.conflictstyle
		merge.log
		merge.renameLimit
		merge.stat
1482
		merge.tool
1483
		merge.verbosity
1484
		mergetool.keepBackup
1485 1486
		pack.compression
		pack.deltaCacheLimit
1487 1488
		pack.deltaCacheSize
		pack.depth
1489 1490 1491
		pack.indexVersion
		pack.packSizeLimit
		pack.threads
1492 1493
		pack.window
		pack.windowMemory
1494 1495
		pull.octopus
		pull.twohead
1496 1497
		receive.denyCurrentBranch
		receive.denyDeletes
1498
		receive.denyNonFastForwards
1499
		receive.fsckObjects
1500
		receive.unpackLimit
1501 1502 1503
		repack.usedeltabaseoffset
		rerere.autoupdate
		rerere.enabled
1504
		showbranch.default
1505 1506
		status.relativePaths
		status.showUntrackedFiles
1507 1508 1509
		tar.umask
		transfer.unpackLimit
		user.email
1510
		user.name
1511
		user.signingkey
1512
		web.browser
1513
		branch. remote.
1514
	"
1515 1516
}

1517 1518
_git_remote ()
{
1519
	local subcommands="add rename rm show prune update set-head"
1520 1521
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
1522
		__gitcomp "$subcommands"
1523 1524 1525
		return
	fi

1526
	case "$subcommand" in
1527
	rename|rm|show|prune)
1528 1529
		__gitcomp "$(__git_remotes)"
		;;
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541
	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"
		;;
1542 1543 1544 1545 1546 1547
	*)
		COMPREPLY=()
		;;
	esac
}

1548 1549
_git_reset ()
{
1550 1551
	__git_has_doubledash && return

1552
	local cur="${COMP_WORDS[COMP_CWORD]}"
1553 1554
	case "$cur" in
	--*)
1555
		__gitcomp "--merge --mixed --hard --soft"
1556 1557 1558 1559
		return
		;;
	esac
	__gitcomp "$(__git_refs)"
1560 1561
}

1562 1563 1564 1565 1566 1567 1568 1569 1570
_git_revert ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--edit --mainline --no-edit --no-commit --signoff"
		return
		;;
	esac
1571
	__gitcomp "$(__git_refs)"
1572 1573
}

1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587
_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=()
}

1588 1589
_git_shortlog ()
{
1590 1591
	__git_has_doubledash && return

1592 1593 1594 1595
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
1596 1597
			$__git_log_common_options
			$__git_log_shortlog_options
1598 1599 1600 1601 1602 1603 1604 1605
			--numbered --summary
			"
		return
		;;
	esac
	__git_complete_revlist
}

1606 1607
_git_show ()
{
1608 1609
	__git_has_doubledash && return

1610 1611 1612
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--pretty=*)
1613
		__gitcomp "$__git_log_pretty_formats
1614
			" "" "${cur##--pretty=}"
1615 1616
		return
		;;
1617 1618 1619 1620 1621
	--format=*)
		__gitcomp "$__git_log_pretty_formats
			" "" "${cur##--format=}"
		return
		;;
1622
	--*)
1623
		__gitcomp "--pretty= --format=
1624 1625
			$__git_diff_common_options
			"
1626 1627 1628 1629 1630 1631
		return
		;;
	esac
	__git_complete_file
}

1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647
_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 已提交
1648 1649
_git_stash ()
{
1650
	local subcommands='save list show apply clear drop pop create branch'
1651 1652
	local subcommand="$(__git_find_subcommand "$subcommands")"
	if [ -z "$subcommand" ]; then
1653
		__gitcomp "$subcommands"
1654 1655 1656 1657 1658 1659
	else
		local cur="${COMP_WORDS[COMP_CWORD]}"
		case "$subcommand,$cur" in
		save,--*)
			__gitcomp "--keep-index"
			;;
1660 1661 1662
		apply,--*)
			__gitcomp "--index"
			;;
1663
		show,--*|drop,--*|pop,--*|branch,--*)
1664 1665 1666 1667 1668 1669
			COMPREPLY=()
			;;
		show,*|apply,*|drop,*|pop,*|branch,*)
			__gitcomp "$(git --git-dir="$(__gitdir)" stash list \
					| sed -n -e 's/:.*//p')"
			;;
1670 1671 1672 1673
		*)
			COMPREPLY=()
			;;
		esac
1674
	fi
J
Junio C Hamano 已提交
1675 1676
}

1677 1678
_git_submodule ()
{
1679 1680
	__git_has_doubledash && return

1681
	local subcommands="add status init update summary foreach sync"
1682
	if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1683 1684 1685 1686 1687 1688
		local cur="${COMP_WORDS[COMP_CWORD]}"
		case "$cur" in
		--*)
			__gitcomp "--quiet --cached"
			;;
		*)
1689
			__gitcomp "$subcommands"
1690 1691 1692 1693 1694 1695
			;;
		esac
		return
	fi
}

1696 1697 1698 1699 1700
_git_svn ()
{
	local subcommands="
		init fetch clone rebase dcommit log find-rev
		set-tree commit-diff info create-ignore propget
S
SZEDER Gábor 已提交
1701 1702
		proplist show-ignore show-externals branch tag blame
		migrate
1703 1704 1705 1706 1707 1708 1709 1710 1711 1712
		"
	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 已提交
1713 1714
			--repack-flags --use-log-author --localtime
			--ignore-paths= $remote_opts
1715 1716 1717 1718 1719
			"
		local init_opts="
			--template= --shared= --trunk= --tags=
			--branches= --stdlayout --minimize-url
			--no-metadata --use-svm-props --use-svnsync-props
S
SZEDER Gábor 已提交
1720 1721
			--rewrite-root= --prefix= --use-log-author
			--add-author-from $remote_opts
1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740
			"
		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 已提交
1741 1742
				--fetch-all --no-rebase --commit-url
				--revision $cmt_opts $fc_opts
1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
				"
			;;
		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 已提交
1756
				--authors-file= --color
1757 1758 1759 1760 1761
				"
			;;
		rebase,--*)
			__gitcomp "
				--merge --verbose --strategy= --local
S
SZEDER Gábor 已提交
1762
				--fetch-all --dry-run $fc_opts
1763 1764 1765 1766 1767 1768 1769 1770
				"
			;;
		commit-diff,--*)
			__gitcomp "--message= --file= --revision= $cmt_opts"
			;;
		info,--*)
			__gitcomp "--url"
			;;
S
SZEDER Gábor 已提交
1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785
		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=
				"
			;;
1786 1787 1788 1789 1790 1791 1792
		*)
			COMPREPLY=()
			;;
		esac
	fi
}

1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813
_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=()
		;;
1814
	-*|tag)
1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826
		if [ $f = 1 ]; then
			__gitcomp "$(__git_tags)"
		else
			COMPREPLY=()
		fi
		;;
	*)
		__gitcomp "$(__git_refs)"
		;;
	esac
}

1827 1828
_git ()
{
1829 1830 1831 1832 1833 1834 1835
	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="." ;;
1836 1837
		--version|-p|--paginate) ;;
		--help) command="help"; break ;;
1838 1839 1840 1841 1842
		*) command="$i"; break ;;
		esac
		c=$((++c))
	done

1843
	if [ -z "$command" ]; then
1844
		case "${COMP_WORDS[COMP_CWORD]}" in
1845
		--*)   __gitcomp "
1846
			--paginate
1847 1848 1849 1850 1851
			--no-pager
			--git-dir=
			--bare
			--version
			--exec-path
1852 1853
			--work-tree=
			--help
1854 1855
			"
			;;
1856
		*)     __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
1857 1858
		esac
		return
1859
	fi
1860

1861 1862
	local expansion=$(__git_aliased_command "$command")
	[ "$expansion" ] && command="$expansion"
1863

1864
	case "$command" in
1865
	am)          _git_am ;;
1866
	add)         _git_add ;;
1867
	apply)       _git_apply ;;
1868
	archive)     _git_archive ;;
1869
	bisect)      _git_bisect ;;
1870
	bundle)      _git_bundle ;;
1871 1872
	branch)      _git_branch ;;
	checkout)    _git_checkout ;;
1873
	cherry)      _git_cherry ;;
1874
	cherry-pick) _git_cherry_pick ;;
1875
	clean)       _git_clean ;;
1876
	clone)       _git_clone ;;
1877
	commit)      _git_commit ;;
1878
	config)      _git_config ;;
1879
	describe)    _git_describe ;;
1880 1881
	diff)        _git_diff ;;
	fetch)       _git_fetch ;;
1882
	format-patch) _git_format_patch ;;
1883
	gc)          _git_gc ;;
1884
	grep)        _git_grep ;;
1885
	help)        _git_help ;;
1886
	init)        _git_init ;;
1887
	log)         _git_log ;;
1888
	ls-files)    _git_ls_files ;;
1889 1890
	ls-remote)   _git_ls_remote ;;
	ls-tree)     _git_ls_tree ;;
1891
	merge)       _git_merge;;
1892
	mergetool)   _git_mergetool;;
1893
	merge-base)  _git_merge_base ;;
1894
	mv)          _git_mv ;;
1895
	name-rev)    _git_name_rev ;;
1896 1897
	pull)        _git_pull ;;
	push)        _git_push ;;
1898
	rebase)      _git_rebase ;;
1899
	remote)      _git_remote ;;
1900
	reset)       _git_reset ;;
1901
	revert)      _git_revert ;;
1902
	rm)          _git_rm ;;
1903
	send-email)  _git_send_email ;;
1904
	shortlog)    _git_shortlog ;;
1905
	show)        _git_show ;;
1906
	show-branch) _git_show_branch ;;
J
Junio C Hamano 已提交
1907
	stash)       _git_stash ;;
1908
	stage)       _git_add ;;
1909
	submodule)   _git_submodule ;;
1910
	svn)         _git_svn ;;
1911
	tag)         _git_tag ;;
1912 1913 1914
	whatchanged) _git_log ;;
	*)           COMPREPLY=() ;;
	esac
1915 1916 1917 1918
}

_gitk ()
{
1919 1920
	__git_has_doubledash && return

1921
	local cur="${COMP_WORDS[COMP_CWORD]}"
1922
	local g="$(__gitdir)"
1923 1924 1925 1926
	local merge=""
	if [ -f $g/MERGE_HEAD ]; then
		merge="--merge"
	fi
1927 1928
	case "$cur" in
	--*)
1929 1930 1931 1932 1933
		__gitcomp "
			$__git_log_common_options
			$__git_log_gitk_options
			$merge
			"
1934 1935 1936
		return
		;;
	esac
1937
	__git_complete_revlist
1938 1939
}

1940 1941 1942 1943
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
1944 1945 1946 1947 1948

# 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.
#
1949
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1950 1951
complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
	|| complete -o default -o nospace -F _git git.exe
1952
fi