git-completion.bash 48.2 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
#
J
Jonathan Nieder 已提交
24
#    3) Consider changing your PS1 to also show the current branch:
25 26 27 28 29 30
#        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.
#
31 32 33 34 35
#       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.
36
#
37 38 39 40
#       You can also see if currently something is stashed, by setting
#       GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
#       then a '$' will be shown next to the branch name.
#
41 42 43 44
#       If you would like to see if there're untracked files, then you can
#       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
#       untracked files, then a '%' will be shown next to the branch name.
#
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
#       If you would like to see the difference between HEAD and its
#       upstream, set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates
#       you are behind, ">" indicates you are ahead, and "<>"
#       indicates you have diverged.  You can further control
#       behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated
#       list of values:
#           verbose       show number of commits ahead/behind (+/-) upstream
#           legacy        don't use the '--count' option available in recent
#                         versions of git-rev-list
#           git           always compare HEAD to @{upstream}
#           svn           always compare HEAD to your SVN upstream
#       By default, __git_ps1 will compare HEAD to your SVN upstream
#       if it can find one, or @{upstream} otherwise.  Once you have
#       set GIT_PS1_SHOWUPSTREAM, you can override it on a
#       per-repository basis by setting the bash.showUpstream config
#       variable.
#
#
63 64 65 66 67 68 69 70 71 72 73
# 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
#
74

75 76 77 78 79
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
esac

80 81
# __gitdir accepts 0 or 1 arguments (i.e., location)
# returns location of .git repo
82 83
__gitdir ()
{
84
	if [ -z "${1-}" ]; then
85
		if [ -n "${__git_dir-}" ]; then
86 87 88 89 90 91 92 93 94 95 96
			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
97 98
}

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
# stores the divergence from upstream in $p
# used by GIT_PS1_SHOWUPSTREAM
__git_ps1_show_upstream ()
{
	local key value
	local svn_remote=() svn_url_pattern count n
	local upstream=git legacy="" verbose=""

	# get some config options from git-config
	while read key value; do
		case "$key" in
		bash.showupstream)
			GIT_PS1_SHOWUPSTREAM="$value"
			if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
				p=""
				return
			fi
			;;
		svn-remote.*.url)
			svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
			svn_url_pattern+="\\|$value"
			upstream=svn+git # default upstream is SVN if available, else git
			;;
		esac
	done < <(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')

	# parse configuration values
	for option in ${GIT_PS1_SHOWUPSTREAM}; do
		case "$option" in
		git|svn) upstream="$option" ;;
		verbose) verbose=1 ;;
		legacy)  legacy=1  ;;
		esac
	done

	# Find our upstream
	case "$upstream" in
	git)    upstream="@{upstream}" ;;
	svn*)
		# get the upstream from the "git-svn-id: ..." in a commit message
		# (git-svn uses essentially the same procedure internally)
		local svn_upstream=($(git log --first-parent -1 \
					--grep="^git-svn-id: \(${svn_url_pattern:2}\)" 2>/dev/null))
		if [[ 0 -ne ${#svn_upstream[@]} ]]; then
			svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
			svn_upstream=${svn_upstream%@*}
			for ((n=1; "$n" <= "${#svn_remote[@]}"; ++n)); do
				svn_upstream=${svn_upstream#${svn_remote[$n]}}
			done

			if [[ -z "$svn_upstream" ]]; then
				# default branch name for checkouts with no layout:
				upstream=${GIT_SVN_ID:-git-svn}
			else
				upstream=${svn_upstream#/}
			fi
		elif [[ "svn+git" = "$upstream" ]]; then
			upstream="@{upstream}"
		fi
		;;
	esac

	# Find how many commits we are ahead/behind our upstream
	if [[ -z "$legacy" ]]; then
		count="$(git rev-list --count --left-right \
				"$upstream"...HEAD 2>/dev/null)"
	else
		# produce equivalent output to --count for older versions of git
		local commits
		if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
		then
			local commit behind=0 ahead=0
			for commit in $commits
			do
				case "$commit" in
				"<"*) let ++behind
					;;
				*)    let ++ahead
					;;
				esac
			done
			count="$behind	$ahead"
		else
			count=""
		fi
	fi

	# calculate the result
	if [[ -z "$verbose" ]]; then
		case "$count" in
		"") # no upstream
			p="" ;;
		"0	0") # equal to upstream
			p="=" ;;
		"0	"*) # ahead of upstream
			p=">" ;;
		*"	0") # behind upstream
			p="<" ;;
		*)	    # diverged from upstream
			p="<>" ;;
		esac
	else
		case "$count" in
		"") # no upstream
			p="" ;;
		"0	0") # equal to upstream
			p=" u=" ;;
		"0	"*) # ahead of upstream
			p=" u+${count#0	}" ;;
		*"	0") # behind upstream
			p=" u-${count%	0}" ;;
		*)	    # diverged from upstream
			p=" u+${count#*	}-${count%	*}" ;;
		esac
	fi

}


218 219
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
# returns text to add to bash PS1 prompt (includes branch name)
220 221
__git_ps1 ()
{
222
	local g="$(__gitdir)"
223
	if [ -n "$g" ]; then
224 225
		local r=""
		local b=""
226
		if [ -f "$g/rebase-merge/interactive" ]; then
227
			r="|REBASE-i"
228
			b="$(cat "$g/rebase-merge/head-name")"
229
		elif [ -d "$g/rebase-merge" ]; then
230
			r="|REBASE-m"
231
			b="$(cat "$g/rebase-merge/head-name")"
232
		else
233 234 235 236 237 238 239 240 241
			if [ -d "$g/rebase-apply" ]; then
				if [ -f "$g/rebase-apply/rebasing" ]; then
					r="|REBASE"
				elif [ -f "$g/rebase-apply/applying" ]; then
					r="|AM"
				else
					r="|AM/REBASE"
				fi
			elif [ -f "$g/MERGE_HEAD" ]; then
242
				r="|MERGING"
243
			elif [ -f "$g/BISECT_LOG" ]; then
244 245
				r="|BISECTING"
			fi
246 247

			b="$(git symbolic-ref HEAD 2>/dev/null)" || {
248 249 250 251 252 253 254 255 256 257

				b="$(
				case "${GIT_PS1_DESCRIBE_STYLE-}" in
				(contains)
					git describe --contains HEAD ;;
				(branch)
					git describe --contains --all HEAD ;;
				(describe)
					git describe HEAD ;;
				(* | default)
K
knittl 已提交
258
					git describe --tags --exact-match HEAD ;;
259 260
				esac 2>/dev/null)" ||

261 262 263 264
				b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
				b="unknown"
				b="($b)"
			}
265 266
		fi

267 268 269 270 271
		local w=""
		local i=""
		local s=""
		local u=""
		local c=""
272
		local p=""
273

274
		if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
275
			if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
276 277 278 279
				c="BARE:"
			else
				b="GIT_DIR!"
			fi
280 281 282
		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
283
					git diff --no-ext-diff --quiet --exit-code || w="*"
284
					if git rev-parse --quiet --verify HEAD >/dev/null; then
285
						git diff-index --cached --quiet HEAD -- || i="+"
286 287 288
					else
						i="#"
					fi
289 290
				fi
			fi
291 292 293
			if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
			        git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
			fi
294 295 296 297 298 299

			if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
			   if [ -n "$(git ls-files --others --exclude-standard)" ]; then
			      u="%"
			   fi
			fi
300 301 302 303

			if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
				__git_ps1_show_upstream
			fi
304 305
		fi

306
		local f="$w$i$s$u"
307
		printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
308 309 310
	fi
}

311
# __gitcomp_1 requires 2 arguments
312 313 314 315 316 317 318 319 320 321 322 323
__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
}

324 325
# __gitcomp accepts 1, 2, 3, or 4 arguments
# generates completion reply with compgen
326 327
__gitcomp ()
{
328
	local cur="${COMP_WORDS[COMP_CWORD]}"
329
	if [ $# -gt 2 ]; then
330 331
		cur="$3"
	fi
332 333 334 335 336
	case "$cur" in
	--*=)
		COMPREPLY=()
		;;
	*)
337
		local IFS=$'\n'
338 339
		COMPREPLY=($(compgen -P "${2-}" \
			-W "$(__gitcomp_1 "${1-}" "${4-}")" \
340
			-- "$cur"))
341 342
		;;
	esac
343 344
}

345
# __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
346 347
__git_heads ()
{
348
	local cmd i is_hash=y dir="$(__gitdir "${1-}")"
349
	if [ -d "$dir" ]; then
350 351
		git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
			refs/heads
352 353
		return
	fi
354
	for i in $(git ls-remote "${1-}" 2>/dev/null); do
355 356 357 358 359 360 361 362 363
		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
}

364
# __git_tags accepts 0 or 1 arguments (to pass to __gitdir)
365 366
__git_tags ()
{
367
	local cmd i is_hash=y dir="$(__gitdir "${1-}")"
368
	if [ -d "$dir" ]; then
369 370
		git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
			refs/tags
371 372
		return
	fi
373
	for i in $(git ls-remote "${1-}" 2>/dev/null); do
374 375 376 377 378 379 380 381 382
		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
}

383
# __git_refs accepts 0 or 1 arguments (to pass to __gitdir)
384 385
__git_refs ()
{
386
	local i is_hash=y dir="$(__gitdir "${1-}")"
S
SZEDER Gábor 已提交
387
	local cur="${COMP_WORDS[COMP_CWORD]}" format refs
388
	if [ -d "$dir" ]; then
S
SZEDER Gábor 已提交
389 390 391 392 393 394
		case "$cur" in
		refs|refs/*)
			format="refname"
			refs="${cur%/*}"
			;;
		*)
395 396 397
			for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
				if [ -e "$dir/$i" ]; then echo $i; fi
			done
S
SZEDER Gábor 已提交
398 399 400 401 402 403
			format="refname:short"
			refs="refs/tags refs/heads refs/remotes"
			;;
		esac
		git --git-dir="$dir" for-each-ref --format="%($format)" \
			$refs
404
		return
405
	fi
406
	for i in $(git ls-remote "$dir" 2>/dev/null); do
407 408 409 410 411
		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/}" ;;
412
		n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
413 414 415 416 417
		n,*) is_hash=y; echo "$i" ;;
		esac
	done
}

418
# __git_refs2 requires 1 argument (to pass to __git_refs)
419 420
__git_refs2 ()
{
421 422 423
	local i
	for i in $(__git_refs "$1"); do
		echo "$i:$i"
424 425 426
	done
}

427
# __git_refs_remotes requires 1 argument (to pass to ls-remote)
428 429 430
__git_refs_remotes ()
{
	local cmd i is_hash=y
431
	for i in $(git ls-remote "$1" 2>/dev/null); do
432 433 434 435 436 437 438 439 440 441 442 443 444
		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
}

445 446
__git_remotes ()
{
447
	local i ngoff IFS=$'\n' d="$(__gitdir)"
448
	shopt -q nullglob || ngoff=1
449
	shopt -s nullglob
450 451
	for i in "$d/remotes"/*; do
		echo ${i#$d/remotes/}
452
	done
453
	[ "$ngoff" ] && shopt -u nullglob
454 455 456
	for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
		i="${i#remote.}"
		echo "${i/.url*/}"
457
	done
458 459
}

J
Jonathan Nieder 已提交
460
__git_list_merge_strategies ()
461
{
462 463 464 465 466 467
	git merge -s help 2>&1 |
	sed -n -e '/[Aa]vailable strategies are: /,/^$/{
		s/\.$//
		s/.*://
		s/^[ 	]*//
		s/[ 	]*$//
468
		p
469
	}'
470
}
J
Jonathan Nieder 已提交
471 472 473 474 475 476 477 478 479 480 481

__git_merge_strategies=
# 'git merge -s help' (and thus detection of the merge strategy
# list) fails, unfortunately, if run outside of any git working
# tree.  __git_merge_strategies is set to the empty string in
# that case, and the detection will be repeated the next time it
# is needed.
__git_compute_merge_strategies ()
{
	: ${__git_merge_strategies:=$(__git_list_merge_strategies)}
}
482

483 484
__git_complete_file ()
{
485
	local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
486 487
	case "$cur" in
	?*:*)
488 489
		ref="${cur%%:*}"
		cur="${cur#*:}"
490 491
		case "$cur" in
		?*/*)
492 493
			pfx="${cur%/*}"
			cur="${cur##*/}"
494 495 496 497 498 499 500
			ls="$ref:$pfx"
			pfx="$pfx/"
			;;
		*)
			ls="$ref"
			;;
	    esac
501 502 503 504 505 506

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

507
		local IFS=$'\n'
508
		COMPREPLY=($(compgen -P "$pfx" \
509
			-W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
510 511 512 513 514 515 516 517
				| sed '/^100... blob /{
				           s,^.*	,,
				           s,$, ,
				       }
				       /^120000 blob /{
				           s,^.*	,,
				           s,$, ,
				       }
518 519 520 521 522 523 524 525
				       /^040000 tree /{
				           s,^.*	,,
				           s,$,/,
				       }
				       s/^.*	//')" \
			-- "$cur"))
		;;
	*)
526
		__gitcomp "$(__git_refs)"
527 528 529 530
		;;
	esac
}

531 532 533 534 535 536 537
__git_complete_revlist ()
{
	local pfx cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	*...*)
		pfx="${cur%...*}..."
		cur="${cur#*...}"
538
		__gitcomp "$(__git_refs)" "$pfx" "$cur"
539 540 541 542
		;;
	*..*)
		pfx="${cur%..*}.."
		cur="${cur#*..}"
543 544
		__gitcomp "$(__git_refs)" "$pfx" "$cur"
		;;
545
	*)
546
		__gitcomp "$(__git_refs)"
547 548 549 550
		;;
	esac
}

551 552 553 554
__git_complete_remote_or_refspec ()
{
	local cmd="${COMP_WORDS[1]}"
	local cur="${COMP_WORDS[COMP_CWORD]}"
555
	local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
556 557 558
	while [ $c -lt $COMP_CWORD ]; do
		i="${COMP_WORDS[c]}"
		case "$i" in
559 560 561 562 563 564 565 566 567 568 569
		--mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
		--all)
			case "$cmd" in
			push) no_complete_refspec=1 ;;
			fetch)
				COMPREPLY=()
				return
				;;
			*) ;;
			esac
			;;
570 571 572 573 574 575 576 577 578
		-*) ;;
		*) remote="$i"; break ;;
		esac
		c=$((++c))
	done
	if [ -z "$remote" ]; then
		__gitcomp "$(__git_remotes)"
		return
	fi
579 580 581 582
	if [ $no_complete_refspec = 1 ]; then
		COMPREPLY=()
		return
	fi
583 584 585 586 587 588 589 590 591 592 593 594 595 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
	[ "$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
}

623 624
__git_complete_strategy ()
{
J
Jonathan Nieder 已提交
625
	__git_compute_merge_strategies
626 627
	case "${COMP_WORDS[COMP_CWORD-1]}" in
	-s|--strategy)
J
Jonathan Nieder 已提交
628
		__gitcomp "$__git_merge_strategies"
629 630 631 632 633
		return 0
	esac
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--strategy=*)
J
Jonathan Nieder 已提交
634
		__gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
635 636 637 638 639 640
		return 0
		;;
	esac
	return 1
}

J
Jonathan Nieder 已提交
641
__git_list_all_commands ()
642 643
{
	local i IFS=" "$'\n'
644
	for i in $(git help -a|egrep '^  [a-zA-Z0-9]')
645 646 647 648 649 650 651 652
	do
		case $i in
		*--*)             : helper pattern;;
		*) echo $i;;
		esac
	done
}

J
Jonathan Nieder 已提交
653 654 655 656 657 658 659
__git_all_commands=
__git_compute_all_commands ()
{
	: ${__git_all_commands:=$(__git_list_all_commands)}
}

__git_list_porcelain_commands ()
660 661
{
	local i IFS=" "$'\n'
J
Jonathan Nieder 已提交
662 663
	__git_compute_all_commands
	for i in "help" $__git_all_commands
664 665
	do
		case $i in
666
		*--*)             : helper pattern;;
667 668 669
		applymbox)        : ask gittus;;
		applypatch)       : ask gittus;;
		archimport)       : import;;
670
		cat-file)         : plumbing;;
671
		check-attr)       : plumbing;;
672
		check-ref-format) : plumbing;;
673
		checkout-index)   : plumbing;;
674
		commit-tree)      : plumbing;;
675
		count-objects)    : infrequent;;
676 677
		cvsexportcommit)  : export;;
		cvsimport)        : import;;
678 679
		cvsserver)        : daemon;;
		daemon)           : daemon;;
680 681 682
		diff-files)       : plumbing;;
		diff-index)       : plumbing;;
		diff-tree)        : plumbing;;
S
Shawn O. Pearce 已提交
683
		fast-import)      : import;;
684
		fast-export)      : export;;
685
		fsck-objects)     : plumbing;;
686
		fetch-pack)       : plumbing;;
687
		fmt-merge-msg)    : plumbing;;
688
		for-each-ref)     : plumbing;;
689 690 691
		hash-object)      : plumbing;;
		http-*)           : transport;;
		index-pack)       : plumbing;;
692
		init-db)          : deprecated;;
693
		local-fetch)      : plumbing;;
694 695 696 697
		lost-found)       : infrequent;;
		ls-files)         : plumbing;;
		ls-remote)        : plumbing;;
		ls-tree)          : plumbing;;
698 699 700 701 702 703 704 705 706 707 708
		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;;
709 710 711
		prune)            : plumbing;;
		prune-packed)     : plumbing;;
		quiltimport)      : import;;
712 713
		read-tree)        : plumbing;;
		receive-pack)     : plumbing;;
714
		reflog)           : plumbing;;
715
		remote-*)         : transport;;
716
		repo-config)      : deprecated;;
717 718 719 720 721 722
		rerere)           : plumbing;;
		rev-list)         : plumbing;;
		rev-parse)        : plumbing;;
		runstatus)        : plumbing;;
		sh-setup)         : internal;;
		shell)            : daemon;;
723
		show-ref)         : plumbing;;
724 725 726 727 728
		send-pack)        : plumbing;;
		show-index)       : plumbing;;
		ssh-*)            : transport;;
		stripspace)       : plumbing;;
		symbolic-ref)     : plumbing;;
729
		tar-tree)         : deprecated;;
730 731
		unpack-file)      : plumbing;;
		unpack-objects)   : plumbing;;
732
		update-index)     : plumbing;;
733 734 735 736 737
		update-ref)       : plumbing;;
		update-server-info) : daemon;;
		upload-archive)   : plumbing;;
		upload-pack)      : plumbing;;
		write-tree)       : plumbing;;
738 739
		var)              : infrequent;;
		verify-pack)      : infrequent;;
740
		verify-tag)       : plumbing;;
741 742 743 744
		*) echo $i;;
		esac
	done
}
J
Jonathan Nieder 已提交
745 746 747 748 749 750 751

__git_porcelain_commands=
__git_compute_porcelain_commands ()
{
	__git_compute_all_commands
	: ${__git_porcelain_commands:=$(__git_list_porcelain_commands)}
}
752

753 754
__git_aliases ()
{
755
	local i IFS=$'\n'
756
	for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
757 758 759 760 761 762
		case "$i" in
		alias.*)
			i="${i#alias.}"
			echo "${i/ */}"
			;;
		esac
763
	done
764 765
}

766
# __git_aliased_command requires 1 argument
767 768
__git_aliased_command ()
{
769
	local word cmdline=$(git --git-dir="$(__gitdir)" \
770
		config --get "alias.$1")
771
	for word in $cmdline; do
772
		case "$word" in
773 774
		\!gitk|gitk)
			echo "gitk"
775
			return
776
			;;
777 778 779 780 781 782
		\!*)	: shell command alias ;;
		-*)	: option ;;
		*=*)	: setting env ;;
		git)	: git itself ;;
		*)
			echo "$word"
783
			return
784
		esac
785 786 787
	done
}

788 789
# __git_find_on_cmdline requires 1 argument
__git_find_on_cmdline ()
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
{
	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
}

805 806 807 808 809 810 811 812 813 814 815 816
__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
}

817
__git_whitespacelist="nowarn warn error error-all fix"
818 819 820

_git_am ()
{
821
	local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
822
	if [ -d "$dir"/rebase-apply ]; then
823
		__gitcomp "--skip --continue --resolved --abort"
824 825 826 827
		return
	fi
	case "$cur" in
	--whitespace=*)
828
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
829 830 831
		return
		;;
	--*)
832
		__gitcomp "
833
			--3way --committer-date-is-author-date --ignore-date
834
			--ignore-whitespace --ignore-space-change
835
			--interactive --keep --no-utf8 --signoff --utf8
836
			--whitespace= --scissors
837
			"
838 839 840 841 842 843 844 845 846 847
		return
	esac
	COMPREPLY=()
}

_git_apply ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--whitespace=*)
848
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
849 850 851
		return
		;;
	--*)
852
		__gitcomp "
853 854 855
			--stat --numstat --summary --check --index
			--cached --index-info --reverse --reject --unidiff-zero
			--apply --no-add --exclude=
856
			--ignore-whitespace --ignore-space-change
857
			--whitespace= --inaccurate-eof --verbose
858
			"
859 860 861 862 863
		return
	esac
	COMPREPLY=()
}

864 865
_git_add ()
{
866 867
	__git_has_doubledash && return

868 869 870
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
871 872
		__gitcomp "
			--interactive --refresh --patch --update --dry-run
873
			--ignore-errors --intent-to-add
874
			"
875 876 877 878 879
		return
	esac
	COMPREPLY=()
}

880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
_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
}

903 904
_git_bisect ()
{
905 906
	__git_has_doubledash && return

907
	local subcommands="start bad good skip reset visualize replay log run"
908
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
909 910
	if [ -z "$subcommand" ]; then
		__gitcomp "$subcommands"
911 912 913
		return
	fi

914
	case "$subcommand" in
915
	bad|good|reset|skip)
916 917 918 919 920 921 922 923
		__gitcomp "$(__git_refs)"
		;;
	*)
		COMPREPLY=()
		;;
	esac
}

924 925
_git_branch ()
{
926 927 928 929 930 931 932 933 934 935 936
	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 已提交
937 938 939 940
	case "${COMP_WORDS[COMP_CWORD]}" in
	--*)
		__gitcomp "
			--color --no-color --verbose --abbrev= --no-abbrev
941
			--track --no-track --contains --merged --no-merged
942
			--set-upstream
S
SZEDER Gábor 已提交
943 944
			"
		;;
945 946 947 948 949 950 951
	*)
		if [ $only_local_ref = "y" -a $has_r = "n" ]; then
			__gitcomp "$(__git_heads)"
		else
			__gitcomp "$(__git_refs)"
		fi
		;;
S
SZEDER Gábor 已提交
952
	esac
953 954
}

955 956
_git_bundle ()
{
957 958 959
	local cmd="${COMP_WORDS[2]}"
	case "$COMP_CWORD" in
	2)
960 961
		__gitcomp "create list-heads verify unbundle"
		;;
962
	3)
963 964 965 966 967 968 969 970 971 972 973 974
		# looking for a file
		;;
	*)
		case "$cmd" in
			create)
				__git_complete_revlist
			;;
		esac
		;;
	esac
}

975 976
_git_checkout ()
{
977 978
	__git_has_doubledash && return

979 980 981 982 983 984 985 986
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--conflict=*)
		__gitcomp "diff3 merge" "" "${cur##--conflict=}"
		;;
	--*)
		__gitcomp "
			--quiet --ours --theirs --track --no-track --merge
987
			--conflict= --orphan --patch
988 989 990 991 992 993
			"
		;;
	*)
		__gitcomp "$(__git_refs)"
		;;
	esac
994 995
}

996 997 998 999 1000
_git_cherry ()
{
	__gitcomp "$(__git_refs)"
}

1001 1002 1003 1004 1005
_git_cherry_pick ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
1006
		__gitcomp "--edit --no-commit"
1007 1008
		;;
	*)
1009
		__gitcomp "$(__git_refs)"
1010 1011 1012 1013
		;;
	esac
}

1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
_git_clean ()
{
	__git_has_doubledash && return

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

1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
_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=()
}

1053 1054
_git_commit ()
{
1055 1056
	__git_has_doubledash && return

1057 1058
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
	--cleanup=*)
		__gitcomp "default strip verbatim whitespace
			" "" "${cur##--cleanup=}"
		return
		;;
	--reuse-message=*)
		__gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
		return
		;;
	--reedit-message=*)
		__gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
		return
		;;
	--untracked-files=*)
		__gitcomp "all no normal" "" "${cur##--untracked-files=}"
		return
		;;
1076
	--*)
1077
		__gitcomp "
1078
			--all --author= --signoff --verify --no-verify
1079
			--edit --amend --include --only --interactive
1080 1081 1082 1083
			--dry-run --reuse-message= --reedit-message=
			--reset-author --file= --message= --template=
			--cleanup= --untracked-files --untracked-files=
			--verbose --quiet
1084
			"
1085 1086 1087 1088 1089
		return
	esac
	COMPREPLY=()
}

1090 1091
_git_describe ()
{
1092 1093 1094 1095 1096 1097 1098 1099 1100
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--all --tags --contains --abbrev= --candidates=
			--exact-match --debug --long --match --always
			"
		return
	esac
1101 1102 1103
	__gitcomp "$(__git_refs)"
}

1104
__git_diff_common_options="--stat --numstat --shortstat --summary
1105 1106
			--patch-with-stat --name-only --name-status --color
			--no-color --color-words --no-renames --check
1107
			--full-index --binary --abbrev --diff-filter=
1108
			--find-copies-harder
1109 1110
			--text --ignore-space-at-eol --ignore-space-change
			--ignore-all-space --exit-code --quiet --ext-diff
1111 1112
			--no-ext-diff
			--no-prefix --src-prefix= --dst-prefix=
1113
			--inter-hunk-context=
1114
			--patience
1115
			--raw
1116 1117
			--dirstat --dirstat= --dirstat-by-file
			--dirstat-by-file= --cumulative
1118 1119 1120 1121 1122 1123 1124 1125 1126
"

_git_diff ()
{
	__git_has_doubledash && return

	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
1127
		__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1128 1129
			--base --ours --theirs
			$__git_diff_common_options
1130
			"
1131 1132 1133
		return
		;;
	esac
1134 1135 1136
	__git_complete_file
}

1137
__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
1138
			tkdiff vimdiff gvimdiff xxdiff araxis p4merge
1139 1140 1141 1142
"

_git_difftool ()
{
1143 1144
	__git_has_doubledash && return

1145 1146 1147 1148 1149 1150 1151
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--tool=*)
		__gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
		return
		;;
	--*)
1152 1153 1154 1155 1156
		__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
			--base --ours --theirs
			--no-renames --diff-filter= --find-copies-harder
			--relative --ignore-submodules
			--tool="
1157 1158 1159
		return
		;;
	esac
1160
	__git_complete_file
1161 1162
}

1163 1164
__git_fetch_options="
	--quiet --verbose --append --upload-pack --force --keep --depth=
1165
	--tags --no-tags --all --prune --dry-run
1166 1167
"

1168 1169
_git_fetch ()
{
1170 1171 1172 1173 1174 1175 1176
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "$__git_fetch_options"
		return
		;;
	esac
1177
	__git_complete_remote_or_refspec
1178 1179
}

1180 1181 1182 1183
_git_format_patch ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
1184 1185 1186 1187 1188 1189
	--thread=*)
		__gitcomp "
			deep shallow
			" "" "${cur##--thread=}"
		return
		;;
1190
	--*)
1191
		__gitcomp "
1192
			--stdout --attach --no-attach --thread --thread=
1193 1194
			--output-directory
			--numbered --start-number
1195
			--numbered-files
1196
			--keep-subject
1197
			--signoff --signature --no-signature
1198
			--in-reply-to= --cc=
1199
			--full-index --binary
1200
			--not --all
1201
			--cover-letter
1202
			--no-prefix --src-prefix= --dst-prefix=
1203 1204
			--inline --suffix= --ignore-if-in-upstream
			--subject-prefix=
1205
			"
1206 1207 1208 1209 1210 1211
		return
		;;
	esac
	__git_complete_revlist
}

1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
_git_fsck ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
			--tags --root --unreachable --cache --no-reflogs --full
			--strict --verbose --lost-found
			"
		return
		;;
	esac
	COMPREPLY=()
}

1227 1228 1229 1230 1231
_git_gc ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
1232
		__gitcomp "--prune --aggressive"
1233 1234 1235 1236 1237 1238
		return
		;;
	esac
	COMPREPLY=()
}

1239 1240 1241 1242 1243
_git_gitk ()
{
	_gitk
}

1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257
_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
1258
			--max-depth
1259 1260 1261 1262 1263 1264
			--count
			--and --or --not --all-match
			"
		return
		;;
	esac
1265 1266

	__gitcomp "$(__git_refs)"
1267 1268
}

1269 1270 1271 1272 1273 1274 1275 1276 1277
_git_help ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--all --info --man --web"
		return
		;;
	esac
J
Jonathan Nieder 已提交
1278 1279
	__git_compute_all_commands
	__gitcomp "$__git_all_commands
1280 1281 1282
		attributes cli core-tutorial cvs-migration
		diffcore gitk glossary hooks ignore modules
		repository-layout tutorial tutorial-2
1283
		workflows
1284
		"
1285 1286
}

1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304
_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=()
}

1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
_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=()
}

1325 1326
_git_ls_remote ()
{
1327
	__gitcomp "$(__git_remotes)"
1328 1329 1330 1331 1332 1333 1334
}

_git_ls_tree ()
{
	__git_complete_file
}

1335 1336 1337 1338
# Options that go well for log, shortlog and gitk
__git_log_common_options="
	--not --all
	--branches --tags --remotes
1339
	--first-parent --merges --no-merges
1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
	--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
"

1356
__git_log_pretty_formats="oneline short medium full fuller email raw format:"
1357
__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1358

1359 1360
_git_log ()
{
1361 1362
	__git_has_doubledash && return

1363
	local cur="${COMP_WORDS[COMP_CWORD]}"
1364 1365
	local g="$(git rev-parse --git-dir 2>/dev/null)"
	local merge=""
1366
	if [ -f "$g/MERGE_HEAD" ]; then
1367 1368
		merge="--merge"
	fi
1369 1370
	case "$cur" in
	--pretty=*)
1371
		__gitcomp "$__git_log_pretty_formats
1372
			" "" "${cur##--pretty=}"
1373 1374
		return
		;;
1375 1376 1377 1378 1379
	--format=*)
		__gitcomp "$__git_log_pretty_formats
			" "" "${cur##--format=}"
		return
		;;
1380
	--date=*)
1381
		__gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1382 1383
		return
		;;
1384 1385 1386 1387
	--decorate=*)
		__gitcomp "long short" "" "${cur##--decorate=}"
		return
		;;
1388
	--*)
1389
		__gitcomp "
1390 1391 1392
			$__git_log_common_options
			$__git_log_shortlog_options
			$__git_log_gitk_options
1393
			--root --topo-order --date-order --reverse
1394
			--follow --full-diff
1395
			--abbrev-commit --abbrev=
1396
			--relative-date --date=
1397
			--pretty= --format= --oneline
1398
			--cherry-pick
1399
			--graph
1400
			--decorate --decorate=
1401
			--walk-reflogs
1402
			--parents --children
1403
			$merge
1404
			$__git_diff_common_options
1405
			--pickaxe-all --pickaxe-regex
1406
			"
1407 1408 1409
		return
		;;
	esac
1410
	__git_complete_revlist
1411 1412
}

1413 1414
__git_merge_options="
	--no-commit --no-stat --log --no-log --squash --strategy
1415
	--commit --stat --no-squash --ff --no-ff --ff-only
1416 1417
"

1418 1419
_git_merge ()
{
1420 1421
	__git_complete_strategy && return

1422 1423 1424
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
1425
		__gitcomp "$__git_merge_options"
1426 1427
		return
	esac
1428
	__gitcomp "$(__git_refs)"
1429 1430
}

1431 1432 1433 1434 1435
_git_mergetool ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--tool=*)
1436
		__gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1437 1438 1439 1440 1441 1442 1443 1444 1445 1446
		return
		;;
	--*)
		__gitcomp "--tool="
		return
		;;
	esac
	COMPREPLY=()
}

1447 1448
_git_merge_base ()
{
1449
	__gitcomp "$(__git_refs)"
1450 1451
}

1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463
_git_mv ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--dry-run"
		return
		;;
	esac
	COMPREPLY=()
}

1464 1465
_git_name_rev ()
{
1466
	__gitcomp "--tags --all --stdin"
1467 1468
}

1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486
_git_notes ()
{
	local subcommands="edit show"
	if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
		__gitcomp "$subcommands"
		return
	fi

	case "${COMP_WORDS[COMP_CWORD-1]}" in
	-m|-F)
		COMPREPLY=()
		;;
	*)
		__gitcomp "$(__git_refs)"
		;;
	esac
}

1487 1488
_git_pull ()
{
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
	__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
1502
	__git_complete_remote_or_refspec
1503 1504 1505 1506
}

_git_push ()
{
1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525
	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
1526
	__git_complete_remote_or_refspec
1527 1528
}

1529 1530
_git_rebase ()
{
1531
	local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
1532
	if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1533
		__gitcomp "--continue --skip --abort"
1534 1535
		return
	fi
1536
	__git_complete_strategy && return
1537
	case "$cur" in
1538 1539 1540 1541
	--whitespace=*)
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
		return
		;;
1542
	--*)
1543 1544 1545 1546 1547
		__gitcomp "
			--onto --merge --strategy --interactive
			--preserve-merges --stat --no-stat
			--committer-date-is-author-date --ignore-date
			--ignore-whitespace --whitespace=
1548
			--autosquash
1549 1550
			"

1551 1552
		return
	esac
1553
	__gitcomp "$(__git_refs)"
1554 1555
}

1556
__git_send_email_confirm_options="always never auto cc compose"
1557
__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1558

1559 1560 1561 1562
_git_send_email ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
	--confirm=*)
		__gitcomp "
			$__git_send_email_confirm_options
			" "" "${cur##--confirm=}"
		return
		;;
	--suppress-cc=*)
		__gitcomp "
			$__git_send_email_suppresscc_options
			" "" "${cur##--suppress-cc=}"

		return
		;;
	--smtp-encryption=*)
		__gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
		return
		;;
1580
	--*)
1581
		__gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1582 1583
			--compose --confirm= --dry-run --envelope-sender
			--from --identity
1584 1585 1586
			--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
1587 1588
			--smtp-server-port --smtp-encryption= --smtp-user
			--subject --suppress-cc= --suppress-from --thread --to
1589
			--validate --no-validate"
1590 1591 1592 1593 1594 1595
		return
		;;
	esac
	COMPREPLY=()
}

1596 1597 1598 1599 1600
_git_stage ()
{
	_git_add
}

1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619
__git_config_get_set_variables ()
{
	local prevword word config_file= c=$COMP_CWORD
	while [ $c -gt 1 ]; do
		word="${COMP_WORDS[c]}"
		case "$word" in
		--global|--system|--file=*)
			config_file="$word"
			break
			;;
		-f|--file)
			config_file="$word $prevword"
			break
			;;
		esac
		prevword=$word
		c=$((--c))
	done

1620 1621 1622 1623 1624 1625
	git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
	while read line
	do
		case "$line" in
		*.*=*)
			echo "${line/=*/}"
1626 1627 1628 1629 1630
			;;
		esac
	done
}

1631
_git_config ()
1632 1633 1634 1635 1636
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	local prv="${COMP_WORDS[COMP_CWORD-1]}"
	case "$prv" in
	branch.*.remote)
1637
		__gitcomp "$(__git_remotes)"
1638 1639 1640
		return
		;;
	branch.*.merge)
1641
		__gitcomp "$(__git_refs)"
1642 1643 1644 1645 1646
		return
		;;
	remote.*.fetch)
		local remote="${prv#remote.}"
		remote="${remote%.fetch}"
1647
		__gitcomp "$(__git_refs_remotes "$remote")"
1648 1649 1650 1651 1652
		return
		;;
	remote.*.push)
		local remote="${prv#remote.}"
		remote="${remote%.push}"
1653
		__gitcomp "$(git --git-dir="$(__gitdir)" \
1654
			for-each-ref --format='%(refname):%(refname)' \
1655 1656 1657 1658
			refs/heads)"
		return
		;;
	pull.twohead|pull.octopus)
J
Jonathan Nieder 已提交
1659 1660
		__git_compute_merge_strategies
		__gitcomp "$__git_merge_strategies"
1661 1662
		return
		;;
1663 1664
	color.branch|color.diff|color.interactive|\
	color.showbranch|color.status|color.ui)
1665 1666 1667
		__gitcomp "always never auto"
		return
		;;
1668 1669 1670 1671
	color.pager)
		__gitcomp "false true"
		return
		;;
1672 1673
	color.*.*)
		__gitcomp "
1674
			normal black red green yellow blue magenta cyan white
1675 1676
			bold dim ul blink reverse
			"
1677 1678
		return
		;;
1679 1680 1681 1682
	help.format)
		__gitcomp "man info web html"
		return
		;;
1683 1684 1685 1686
	log.date)
		__gitcomp "$__git_log_date_formats"
		return
		;;
1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698
	sendemail.aliasesfiletype)
		__gitcomp "mutt mailrc pine elm gnus"
		return
		;;
	sendemail.confirm)
		__gitcomp "$__git_send_email_confirm_options"
		return
		;;
	sendemail.suppresscc)
		__gitcomp "$__git_send_email_suppresscc_options"
		return
		;;
1699 1700 1701 1702
	--get|--get-all|--unset|--unset-all)
		__gitcomp "$(__git_config_get_set_variables)"
		return
		;;
1703 1704 1705 1706 1707 1708 1709
	*.*)
		COMPREPLY=()
		return
		;;
	esac
	case "$cur" in
	--*)
1710
		__gitcomp "
1711
			--global --system --file=
1712
			--list --replace-all
1713
			--get --get-all --get-regexp
1714
			--add --unset --unset-all
1715
			--remove-section --rename-section
1716
			"
1717 1718 1719 1720 1721
		return
		;;
	branch.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1722
		__gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur"
1723 1724 1725 1726 1727
		return
		;;
	branch.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
1728
		__gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1729 1730
		return
		;;
1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760
	guitool.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
		__gitcomp "
			argprompt cmd confirm needsfile noconsole norescan
			prompt revprompt revunmerged title
			" "$pfx" "$cur"
		return
		;;
	difftool.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
		__gitcomp "cmd path" "$pfx" "$cur"
		return
		;;
	man.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
		__gitcomp "cmd path" "$pfx" "$cur"
		return
		;;
	mergetool.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
		__gitcomp "cmd path trustExitCode" "$pfx" "$cur"
		return
		;;
	pager.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
J
Jonathan Nieder 已提交
1761 1762
		__git_compute_all_commands
		__gitcomp "$__git_all_commands" "$pfx" "$cur"
1763 1764
		return
		;;
1765 1766 1767
	remote.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1768
		__gitcomp "
1769
			url proxy fetch push mirror skipDefaultUpdate
1770
			receivepack uploadpack tagopt pushurl
1771
			" "$pfx" "$cur"
1772 1773 1774 1775 1776
		return
		;;
	remote.*)
		local pfx="${cur%.*}."
		cur="${cur#*.}"
1777
		__gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1778 1779
		return
		;;
1780 1781 1782
	url.*.*)
		local pfx="${cur%.*}."
		cur="${cur##*.}"
1783
		__gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur"
1784 1785
		return
		;;
1786
	esac
1787
	__gitcomp "
1788
		add.ignore-errors
1789
		alias.
1790
		apply.ignorewhitespace
1791
		apply.whitespace
1792 1793
		branch.autosetupmerge
		branch.autosetuprebase
1794
		clean.requireForce
1795 1796 1797 1798
		color.branch
		color.branch.current
		color.branch.local
		color.branch.plain
1799
		color.branch.remote
1800
		color.diff
1801
		color.diff.commit
1802
		color.diff.frag
1803
		color.diff.meta
1804
		color.diff.new
1805 1806
		color.diff.old
		color.diff.plain
1807
		color.diff.whitespace
1808 1809 1810
		color.grep
		color.grep.external
		color.grep.match
1811 1812 1813 1814
		color.interactive
		color.interactive.header
		color.interactive.help
		color.interactive.prompt
1815
		color.pager
1816
		color.showbranch
1817
		color.status
1818 1819
		color.status.added
		color.status.changed
1820
		color.status.header
1821
		color.status.nobranch
1822
		color.status.untracked
1823 1824 1825 1826 1827
		color.status.updated
		color.ui
		commit.template
		core.autocrlf
		core.bare
1828
		core.compression
1829
		core.createObject
1830 1831 1832
		core.deltaBaseCacheLimit
		core.editor
		core.excludesfile
1833
		core.fileMode
1834
		core.fsyncobjectfiles
1835
		core.gitProxy
1836
		core.ignoreCygwinFSTricks
1837 1838 1839 1840 1841
		core.ignoreStat
		core.logAllRefUpdates
		core.loosecompression
		core.packedGitLimit
		core.packedGitWindowSize
1842
		core.pager
1843
		core.preferSymlinkRefs
1844 1845
		core.preloadindex
		core.quotepath
1846
		core.repositoryFormatVersion
1847
		core.safecrlf
1848
		core.sharedRepository
1849 1850
		core.symlinks
		core.trustctime
1851
		core.warnAmbiguousRefs
1852 1853 1854 1855 1856
		core.whitespace
		core.worktree
		diff.autorefreshindex
		diff.external
		diff.mnemonicprefix
1857
		diff.renameLimit
1858
		diff.renameLimit.
1859
		diff.renames
1860 1861 1862
		diff.suppressBlankEmpty
		diff.tool
		diff.wordRegex
1863
		difftool.
1864
		difftool.prompt
1865
		fetch.unpackLimit
1866 1867
		format.attach
		format.cc
1868
		format.headers
1869 1870
		format.numbered
		format.pretty
1871
		format.signature
1872 1873
		format.signoff
		format.subjectprefix
1874
		format.suffix
1875
		format.thread
1876 1877 1878
		gc.aggressiveWindow
		gc.auto
		gc.autopacklimit
1879
		gc.packrefs
1880
		gc.pruneexpire
1881 1882 1883 1884
		gc.reflogexpire
		gc.reflogexpireunreachable
		gc.rerereresolved
		gc.rerereunresolved
1885
		gitcvs.allbinary
1886
		gitcvs.commitmsgannotation
1887
		gitcvs.dbTableNamePrefix
1888 1889 1890 1891 1892 1893
		gitcvs.dbdriver
		gitcvs.dbname
		gitcvs.dbpass
		gitcvs.dbuser
		gitcvs.enabled
		gitcvs.logfile
1894
		gitcvs.usecrlfattr
1895
		guitool.
1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909
		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
1910 1911
		http.lowSpeedLimit
		http.lowSpeedTime
1912
		http.maxRequests
1913
		http.noEPSV
1914
		http.proxy
1915 1916 1917 1918 1919
		http.sslCAInfo
		http.sslCAPath
		http.sslCert
		http.sslKey
		http.sslVerify
1920 1921
		i18n.commitEncoding
		i18n.logOutputEncoding
1922 1923 1924 1925 1926 1927 1928 1929
		imap.folder
		imap.host
		imap.pass
		imap.port
		imap.preformattedHTML
		imap.sslverify
		imap.tunnel
		imap.user
1930 1931 1932 1933 1934
		instaweb.browser
		instaweb.httpd
		instaweb.local
		instaweb.modulepath
		instaweb.port
1935
		interactive.singlekey
1936
		log.date
1937
		log.showroot
1938
		mailmap.file
1939
		man.
1940 1941 1942 1943 1944
		man.viewer
		merge.conflictstyle
		merge.log
		merge.renameLimit
		merge.stat
1945
		merge.tool
1946
		merge.verbosity
1947
		mergetool.
1948
		mergetool.keepBackup
1949
		mergetool.prompt
1950 1951
		pack.compression
		pack.deltaCacheLimit
1952 1953
		pack.deltaCacheSize
		pack.depth
1954 1955 1956
		pack.indexVersion
		pack.packSizeLimit
		pack.threads
1957 1958
		pack.window
		pack.windowMemory
1959
		pager.
1960 1961
		pull.octopus
		pull.twohead
1962 1963
		push.default
		rebase.stat
1964 1965
		receive.denyCurrentBranch
		receive.denyDeletes
1966
		receive.denyNonFastForwards
1967
		receive.fsckObjects
1968
		receive.unpackLimit
1969 1970 1971
		repack.usedeltabaseoffset
		rerere.autoupdate
		rerere.enabled
1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991
		sendemail.aliasesfile
		sendemail.aliasesfiletype
		sendemail.bcc
		sendemail.cc
		sendemail.cccmd
		sendemail.chainreplyto
		sendemail.confirm
		sendemail.envelopesender
		sendemail.multiedit
		sendemail.signedoffbycc
		sendemail.smtpencryption
		sendemail.smtppass
		sendemail.smtpserver
		sendemail.smtpserverport
		sendemail.smtpuser
		sendemail.suppresscc
		sendemail.suppressfrom
		sendemail.thread
		sendemail.to
		sendemail.validate
1992
		showbranch.default
1993 1994
		status.relativePaths
		status.showUntrackedFiles
1995 1996
		tar.umask
		transfer.unpackLimit
1997
		url.
1998
		user.email
1999
		user.name
2000
		user.signingkey
2001
		web.browser
2002
		branch. remote.
2003
	"
2004 2005
}

2006 2007
_git_remote ()
{
2008
	local subcommands="add rename rm show prune update set-head"
2009
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
2010
	if [ -z "$subcommand" ]; then
2011
		__gitcomp "$subcommands"
2012 2013 2014
		return
	fi

2015
	case "$subcommand" in
2016
	rename|rm|show|prune)
2017 2018
		__gitcomp "$(__git_remotes)"
		;;
2019 2020
	update)
		local i c='' IFS=$'\n'
2021 2022 2023
		for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
			i="${i#remotes.}"
			c="$c ${i/ */}"
2024 2025 2026
		done
		__gitcomp "$c"
		;;
2027 2028 2029 2030 2031 2032
	*)
		COMPREPLY=()
		;;
	esac
}

2033 2034 2035 2036 2037
_git_replace ()
{
	__gitcomp "$(__git_refs)"
}

2038 2039
_git_reset ()
{
2040 2041
	__git_has_doubledash && return

2042
	local cur="${COMP_WORDS[COMP_CWORD]}"
2043 2044
	case "$cur" in
	--*)
S
SZEDER Gábor 已提交
2045
		__gitcomp "--merge --mixed --hard --soft --patch"
2046 2047 2048 2049
		return
		;;
	esac
	__gitcomp "$(__git_refs)"
2050 2051
}

2052 2053 2054 2055 2056 2057 2058 2059 2060
_git_revert ()
{
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "--edit --mainline --no-edit --no-commit --signoff"
		return
		;;
	esac
2061
	__gitcomp "$(__git_refs)"
2062 2063
}

2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077
_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=()
}

2078 2079
_git_shortlog ()
{
2080 2081
	__git_has_doubledash && return

2082 2083 2084 2085
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--*)
		__gitcomp "
2086 2087
			$__git_log_common_options
			$__git_log_shortlog_options
2088 2089 2090 2091 2092 2093 2094 2095
			--numbered --summary
			"
		return
		;;
	esac
	__git_complete_revlist
}

2096 2097
_git_show ()
{
2098 2099
	__git_has_doubledash && return

2100 2101 2102
	local cur="${COMP_WORDS[COMP_CWORD]}"
	case "$cur" in
	--pretty=*)
2103
		__gitcomp "$__git_log_pretty_formats
2104
			" "" "${cur##--pretty=}"
2105 2106
		return
		;;
2107 2108 2109 2110 2111
	--format=*)
		__gitcomp "$__git_log_pretty_formats
			" "" "${cur##--format=}"
		return
		;;
2112
	--*)
2113
		__gitcomp "--pretty= --format= --abbrev-commit --oneline
2114 2115
			$__git_diff_common_options
			"
2116 2117 2118 2119 2120 2121
		return
		;;
	esac
	__git_complete_file
}

2122 2123 2124 2125 2126 2127 2128 2129
_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
2130
			--color --no-color
2131
			--sha1-name --sparse --topics --reflog
2132 2133 2134 2135 2136 2137 2138
			"
		return
		;;
	esac
	__git_complete_revlist
}

J
Junio C Hamano 已提交
2139 2140
_git_stash ()
{
2141 2142
	local cur="${COMP_WORDS[COMP_CWORD]}"
	local save_opts='--keep-index --no-keep-index --quiet --patch'
2143
	local subcommands='save list show apply clear drop pop create branch'
2144
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
2145
	if [ -z "$subcommand" ]; then
2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157
		case "$cur" in
		--*)
			__gitcomp "$save_opts"
			;;
		*)
			if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
				__gitcomp "$subcommands"
			else
				COMPREPLY=()
			fi
			;;
		esac
2158 2159 2160
	else
		case "$subcommand,$cur" in
		save,--*)
2161
			__gitcomp "$save_opts"
2162
			;;
2163
		apply,--*|pop,--*)
2164
			__gitcomp "--index --quiet"
2165
			;;
2166
		show,--*|drop,--*|branch,--*)
2167 2168 2169 2170 2171 2172
			COMPREPLY=()
			;;
		show,*|apply,*|drop,*|pop,*|branch,*)
			__gitcomp "$(git --git-dir="$(__gitdir)" stash list \
					| sed -n -e 's/:.*//p')"
			;;
2173 2174 2175 2176
		*)
			COMPREPLY=()
			;;
		esac
2177
	fi
J
Junio C Hamano 已提交
2178 2179
}

2180 2181
_git_submodule ()
{
2182 2183
	__git_has_doubledash && return

2184
	local subcommands="add status init update summary foreach sync"
2185
	if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
2186 2187 2188 2189 2190 2191
		local cur="${COMP_WORDS[COMP_CWORD]}"
		case "$cur" in
		--*)
			__gitcomp "--quiet --cached"
			;;
		*)
2192
			__gitcomp "$subcommands"
2193 2194 2195 2196 2197 2198
			;;
		esac
		return
	fi
}

2199 2200 2201 2202 2203
_git_svn ()
{
	local subcommands="
		init fetch clone rebase dcommit log find-rev
		set-tree commit-diff info create-ignore propget
S
SZEDER Gábor 已提交
2204
		proplist show-ignore show-externals branch tag blame
2205
		migrate mkdirs reset gc
2206
		"
2207
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
2208 2209 2210 2211 2212 2213 2214 2215
	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 已提交
2216 2217
			--repack-flags --use-log-author --localtime
			--ignore-paths= $remote_opts
2218 2219 2220 2221 2222
			"
		local init_opts="
			--template= --shared= --trunk= --tags=
			--branches= --stdlayout --minimize-url
			--no-metadata --use-svm-props --use-svnsync-props
S
SZEDER Gábor 已提交
2223 2224
			--rewrite-root= --prefix= --use-log-author
			--add-author-from $remote_opts
2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243
			"
		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 已提交
2244 2245
				--fetch-all --no-rebase --commit-url
				--revision $cmt_opts $fc_opts
2246 2247 2248 2249 2250 2251
				"
			;;
		set-tree,--*)
			__gitcomp "--stdin $cmt_opts $fc_opts"
			;;
		create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
2252
		show-externals,--*|mkdirs,--*)
2253 2254 2255 2256 2257 2258
			__gitcomp "--revision="
			;;
		log,--*)
			__gitcomp "
				--limit= --revision= --verbose --incremental
				--oneline --show-commit --non-recursive
S
SZEDER Gábor 已提交
2259
				--authors-file= --color
2260 2261 2262 2263 2264
				"
			;;
		rebase,--*)
			__gitcomp "
				--merge --verbose --strategy= --local
S
SZEDER Gábor 已提交
2265
				--fetch-all --dry-run $fc_opts
2266 2267 2268 2269 2270 2271 2272 2273
				"
			;;
		commit-diff,--*)
			__gitcomp "--message= --file= --revision= $cmt_opts"
			;;
		info,--*)
			__gitcomp "--url"
			;;
S
SZEDER Gábor 已提交
2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288
		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=
				"
			;;
2289 2290 2291
		reset,--*)
			__gitcomp "--revision= --parent"
			;;
2292 2293 2294 2295 2296 2297 2298
		*)
			COMPREPLY=()
			;;
		esac
	fi
}

2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319
_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=()
		;;
2320
	-*|tag)
2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332
		if [ $f = 1 ]; then
			__gitcomp "$(__git_tags)"
		else
			COMPREPLY=()
		fi
		;;
	*)
		__gitcomp "$(__git_refs)"
		;;
	esac
}

2333 2334 2335 2336 2337
_git_whatchanged ()
{
	_git_log
}

2338 2339
_git ()
{
2340 2341 2342 2343 2344 2345 2346
	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="." ;;
2347 2348
		--version|-p|--paginate) ;;
		--help) command="help"; break ;;
2349 2350 2351 2352 2353
		*) command="$i"; break ;;
		esac
		c=$((++c))
	done

2354
	if [ -z "$command" ]; then
2355
		case "${COMP_WORDS[COMP_CWORD]}" in
2356
		--*)   __gitcomp "
2357
			--paginate
2358 2359 2360 2361 2362
			--no-pager
			--git-dir=
			--bare
			--version
			--exec-path
2363
			--html-path
2364 2365
			--work-tree=
			--help
2366 2367
			"
			;;
J
Jonathan Nieder 已提交
2368 2369
		*)     __git_compute_porcelain_commands
		       __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2370 2371
		esac
		return
2372
	fi
2373

2374
	local completion_func="_git_${command//-/_}"
2375 2376
	declare -F $completion_func >/dev/null && $completion_func && return

2377
	local expansion=$(__git_aliased_command "$command")
2378 2379 2380 2381
	if [ -n "$expansion" ]; then
		completion_func="_git_${expansion//-/_}"
		declare -F $completion_func >/dev/null && $completion_func
	fi
2382 2383 2384 2385
}

_gitk ()
{
2386 2387
	__git_has_doubledash && return

2388
	local cur="${COMP_WORDS[COMP_CWORD]}"
2389
	local g="$(__gitdir)"
2390
	local merge=""
2391
	if [ -f "$g/MERGE_HEAD" ]; then
2392 2393
		merge="--merge"
	fi
2394 2395
	case "$cur" in
	--*)
2396 2397 2398 2399 2400
		__gitcomp "
			$__git_log_common_options
			$__git_log_gitk_options
			$merge
			"
2401 2402 2403
		return
		;;
	esac
2404
	__git_complete_revlist
2405 2406
}

2407 2408 2409 2410
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
2411 2412 2413 2414 2415

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