git-completion.bash 54.7 KB
Newer Older
1
#!bash
2
#
3
# bash/zsh completion support for core Git.
4
#
5
# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
6
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
7
# Distributed under the GNU General Public License, version 2.0.
8 9 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
#
# To use these routines:
#
#    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
21
#    2) Add the following line to your .bashrc/.zshrc:
22 23
#        source ~/.git-completion.sh
#
J
Jonathan Nieder 已提交
24
#    3) Consider changing your PS1 to also show the current branch:
25 26
#         Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
#         ZSH:  PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
27 28 29 30 31
#
#       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.
#
32 33 34 35 36
#       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.
37
#
38 39 40 41
#       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.
#
42 43 44 45
#       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.
#
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
if [[ -n ${ZSH_VERSION-} ]]; then
	autoload -U +X bashcompinit && bashcompinit
fi

68 69 70 71 72
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
esac

73 74
# __gitdir accepts 0 or 1 arguments (i.e., location)
# returns location of .git repo
75 76
__gitdir ()
{
77
	if [ -z "${1-}" ]; then
78
		if [ -n "${__git_dir-}" ]; then
79 80 81 82 83 84 85 86 87 88 89
			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
90 91
}

92 93 94 95 96
# stores the divergence from upstream in $p
# used by GIT_PS1_SHOWUPSTREAM
__git_ps1_show_upstream ()
{
	local key value
97
	local svn_remote svn_url_pattern count n
98 99
	local upstream=git legacy="" verbose=""

100
	svn_remote=()
101
	# get some config options from git-config
102
	local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
103
	while read -r key value; do
104 105 106 107 108 109 110 111 112 113 114 115 116 117
		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
118
	done <<< "$output"
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135

	# 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 \
136
					--grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
137 138 139
		if [[ 0 -ne ${#svn_upstream[@]} ]]; then
			svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
			svn_upstream=${svn_upstream%@*}
140
			local n_stop="${#svn_remote[@]}"
141
			for ((n=1; n <= n_stop; n++)); do
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
				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
170 171
				"<"*) ((behind++)) ;;
				*)    ((ahead++))  ;;
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
				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

}


212 213
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
# returns text to add to bash PS1 prompt (includes branch name)
214 215
__git_ps1 ()
{
216
	local g="$(__gitdir)"
217
	if [ -n "$g" ]; then
218 219
		local r=""
		local b=""
220
		if [ -f "$g/rebase-merge/interactive" ]; then
221
			r="|REBASE-i"
222
			b="$(cat "$g/rebase-merge/head-name")"
223
		elif [ -d "$g/rebase-merge" ]; then
224
			r="|REBASE-m"
225
			b="$(cat "$g/rebase-merge/head-name")"
226
		else
227 228 229 230 231 232 233 234 235
			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
236
				r="|MERGING"
237 238
			elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
				r="|CHERRY-PICKING"
239
			elif [ -f "$g/BISECT_LOG" ]; then
240 241
				r="|BISECTING"
			fi
242 243

			b="$(git symbolic-ref HEAD 2>/dev/null)" || {
244 245 246 247 248 249 250 251 252 253

				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 已提交
254
					git describe --tags --exact-match HEAD ;;
255 256
				esac 2>/dev/null)" ||

257 258 259 260
				b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
				b="unknown"
				b="($b)"
			}
261 262
		fi

263 264 265 266 267
		local w=""
		local i=""
		local s=""
		local u=""
		local c=""
268
		local p=""
269

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

			if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
292 293 294
				if [ -n "$(git ls-files --others --exclude-standard)" ]; then
					u="%"
				fi
295
			fi
296 297 298 299

			if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
				__git_ps1_show_upstream
			fi
300 301
		fi

302
		local f="$w$i$s$u"
303
		printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
304 305 306
	fi
}

307 308
__gitcomp_1 ()
{
309
	local c IFS=$' \t\n'
310
	for c in $1; do
311 312 313 314
		c="$c$2"
		case $c in
		--*=*|*.) ;;
		*) c="$c " ;;
315
		esac
316
		printf '%s\n' "$c"
317 318 319
	done
}

320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
# The following function is based on code from:
#
#   bash_completion - programmable completion functions for bash 3.2+
#
#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
#             © 2009-2010, Bash Completion Maintainers
#                     <bash-completion-devel@lists.alioth.debian.org>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2, or (at your option)
#   any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software Foundation,
#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#   The latest version of this software can be obtained here:
#
#   http://bash-completion.alioth.debian.org/
#
#   RELEASE: 2.x

# This function can be used to access a tokenized list of words
# on the command line:
#
#	__git_reassemble_comp_words_by_ref '=:'
#	if test "${words_[cword_-1]}" = -w
#	then
#		...
#	fi
#
# The argument should be a collection of characters from the list of
# word completion separators (COMP_WORDBREAKS) to treat as ordinary
# characters.
#
# This is roughly equivalent to going back in time and setting
# COMP_WORDBREAKS to exclude those characters.  The intent is to
# make option types like --date=<type> and <rev>:<path> easy to
# recognize by treating each shell word as a single token.
#
# It is best not to set COMP_WORDBREAKS directly because the value is
# shared with other completion scripts.  By the time the completion
# function gets called, COMP_WORDS has already been populated so local
# changes to COMP_WORDBREAKS have no effect.
#
# Output: words_, cword_, cur_.

__git_reassemble_comp_words_by_ref()
{
	local exclude i j first
	# Which word separators to exclude?
	exclude="${1//[^$COMP_WORDBREAKS]}"
	cword_=$COMP_CWORD
	if [ -z "$exclude" ]; then
		words_=("${COMP_WORDS[@]}")
		return
	fi
	# List of word completion separators has shrunk;
	# re-assemble words to complete.
	for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
		# Append each nonempty word consisting of just
		# word separator characters to the current word.
		first=t
		while
			[ $i -gt 0 ] &&
			[ -n "${COMP_WORDS[$i]}" ] &&
			# word consists of excluded word separators
			[ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
		do
			# Attach to the previous token,
			# unless the previous token is the command name.
			if [ $j -ge 2 ] && [ -n "$first" ]; then
				((j--))
			fi
			first=
			words_[$j]=${words_[j]}${COMP_WORDS[i]}
			if [ $i = $COMP_CWORD ]; then
				cword_=$j
			fi
			if (($i < ${#COMP_WORDS[@]} - 1)); then
				((i++))
			else
				# Done.
				return
			fi
		done
		words_[$j]=${words_[j]}${COMP_WORDS[i]}
		if [ $i = $COMP_CWORD ]; then
			cword_=$j
		fi
	done
}

419
if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
420
if [[ -z ${ZSH_VERSION:+set} ]]; then
421 422
_get_comp_words_by_ref ()
{
423 424 425 426 427 428 429
	local exclude cur_ words_ cword_
	if [ "$1" = "-n" ]; then
		exclude=$2
		shift 2
	fi
	__git_reassemble_comp_words_by_ref "$exclude"
	cur_=${words_[cword_]}
430 431 432
	while [ $# -gt 0 ]; do
		case "$1" in
		cur)
433
			cur=$cur_
434 435
			;;
		prev)
436
			prev=${words_[$cword_-1]}
437 438
			;;
		words)
439
			words=("${words_[@]}")
440 441
			;;
		cword)
442
			cword=$cword_
443 444 445 446 447
			;;
		esac
		shift
	done
}
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
else
_get_comp_words_by_ref ()
{
	while [ $# -gt 0 ]; do
		case "$1" in
		cur)
			cur=${COMP_WORDS[COMP_CWORD]}
			;;
		prev)
			prev=${COMP_WORDS[COMP_CWORD-1]}
			;;
		words)
			words=("${COMP_WORDS[@]}")
			;;
		cword)
			cword=$COMP_CWORD
			;;
		-n)
			# assume COMP_WORDBREAKS is already set sanely
			shift
			;;
		esac
		shift
	done
}
fi
474 475
fi

S
SZEDER Gábor 已提交
476 477 478 479 480 481 482
# Generates completion reply with compgen, appending a space to possible
# completion words, if necessary.
# It accepts 1 to 4 arguments:
# 1: List of possible completion words.
# 2: A prefix to be added to each possible completion word (optional).
# 3: Generate possible completion matches for this word (optional).
# 4: A suffix to be appended to each possible completion word (optional).
483 484
__gitcomp ()
{
485
	local cur_="${3-$cur}"
486 487

	case "$cur_" in
488 489 490 491
	--*=)
		COMPREPLY=()
		;;
	*)
492
		local IFS=$'\n'
493 494
		COMPREPLY=($(compgen -P "${2-}" \
			-W "$(__gitcomp_1 "${1-}" "${4-}")" \
495
			-- "$cur_"))
496 497
		;;
	esac
498 499
}

500 501 502 503 504 505 506 507 508 509 510
# Generates completion reply with compgen from newline-separated possible
# completion words by appending a space to all of them.
# It accepts 1 to 4 arguments:
# 1: List of possible completion words, separated by a single newline.
# 2: A prefix to be added to each possible completion word (optional).
# 3: Generate possible completion matches for this word (optional).
# 4: A suffix to be appended to each possible completion word instead of
#    the default space (optional).  If specified but empty, nothing is
#    appended.
__gitcomp_nl ()
{
511 512
	local IFS=$'\n'
	COMPREPLY=($(compgen -P "${2-}" -S "${4- }" -W "$1" -- "${3-$cur}"))
513 514
}

515 516
__git_heads ()
{
517
	local dir="$(__gitdir)"
518
	if [ -d "$dir" ]; then
519 520
		git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
			refs/heads
521 522 523 524
		return
	fi
}

525 526
__git_tags ()
{
527
	local dir="$(__gitdir)"
528
	if [ -d "$dir" ]; then
529 530
		git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
			refs/tags
531 532 533 534
		return
	fi
}

535 536 537
# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
# presence of 2nd argument means use the guess heuristic employed
# by checkout for tracking branches
538 539
__git_refs ()
{
540
	local i hash dir="$(__gitdir "${1-}")" track="${2-}"
541
	local format refs
542
	if [ -d "$dir" ]; then
S
SZEDER Gábor 已提交
543 544 545 546
		case "$cur" in
		refs|refs/*)
			format="refname"
			refs="${cur%/*}"
547
			track=""
S
SZEDER Gábor 已提交
548 549
			;;
		*)
550 551 552
			for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
				if [ -e "$dir/$i" ]; then echo $i; fi
			done
S
SZEDER Gábor 已提交
553 554 555 556 557 558
			format="refname:short"
			refs="refs/tags refs/heads refs/remotes"
			;;
		esac
		git --git-dir="$dir" for-each-ref --format="%($format)" \
			$refs
559 560 561 562 563 564 565
		if [ -n "$track" ]; then
			# employ the heuristic used by git checkout
			# Try to find a remote branch that matches the completion word
			# but only output if the branch name is unique
			local ref entry
			git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \
				"refs/remotes/" | \
566
			while read -r entry; do
567 568 569 570 571 572 573
				eval "$entry"
				ref="${ref#*/}"
				if [[ "$ref" == "$cur"* ]]; then
					echo "$ref"
				fi
			done | uniq -u
		fi
574
		return
575
	fi
576 577 578
	case "$cur" in
	refs|refs/*)
		git ls-remote "$dir" "$cur*" 2>/dev/null | \
579
		while read -r hash i; do
580 581 582 583 584 585 586 587
			case "$i" in
			*^{}) ;;
			*) echo "$i" ;;
			esac
		done
		;;
	*)
		git ls-remote "$dir" HEAD ORIG_HEAD 'refs/tags/*' 'refs/heads/*' 'refs/remotes/*' 2>/dev/null | \
588
		while read -r hash i; do
589 590 591 592 593 594 595 596
			case "$i" in
			*^{}) ;;
			refs/*) echo "${i#refs/*/}" ;;
			*) echo "$i" ;;
			esac
		done
		;;
	esac
597 598
}

599
# __git_refs2 requires 1 argument (to pass to __git_refs)
600 601
__git_refs2 ()
{
602 603 604
	local i
	for i in $(__git_refs "$1"); do
		echo "$i:$i"
605 606 607
	done
}

608
# __git_refs_remotes requires 1 argument (to pass to ls-remote)
609 610
__git_refs_remotes ()
{
611 612
	local i hash
	git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
613
	while read -r hash i; do
614
		echo "$i:refs/remotes/$1/${i#refs/heads/}"
615 616 617
	done
}

618 619
__git_remotes ()
{
620 621
	local i IFS=$'\n' d="$(__gitdir)"
	test -d "$d/remotes" && ls -1 "$d/remotes"
622 623 624
	for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
		i="${i#remote.}"
		echo "${i/.url*/}"
625
	done
626 627
}

J
Jonathan Nieder 已提交
628
__git_list_merge_strategies ()
629
{
630 631 632 633 634 635
	git merge -s help 2>&1 |
	sed -n -e '/[Aa]vailable strategies are: /,/^$/{
		s/\.$//
		s/.*://
		s/^[ 	]*//
		s/[ 	]*$//
636
		p
637
	}'
638
}
J
Jonathan Nieder 已提交
639 640 641 642 643 644 645 646 647

__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 ()
{
648 649
	test -n "$__git_merge_strategies" ||
	__git_merge_strategies=$(__git_list_merge_strategies)
J
Jonathan Nieder 已提交
650
}
651

652
__git_complete_revlist_file ()
653
{
654
	local pfx ls ref cur_="$cur"
655
	case "$cur_" in
656 657 658
	*..?*:*)
		return
		;;
659
	?*:*)
660 661 662
		ref="${cur_%%:*}"
		cur_="${cur_#*:}"
		case "$cur_" in
663
		?*/*)
664 665
			pfx="${cur_%/*}"
			cur_="${cur_##*/}"
666 667 668 669 670 671
			ls="$ref:$pfx"
			pfx="$pfx/"
			;;
		*)
			ls="$ref"
			;;
672
		esac
673 674 675 676 677 678

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

679
		__gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
680 681 682 683 684 685 686 687
				| sed '/^100... blob /{
				           s,^.*	,,
				           s,$, ,
				       }
				       /^120000 blob /{
				           s,^.*	,,
				           s,$, ,
				       }
688 689 690 691 692
				       /^040000 tree /{
				           s,^.*	,,
				           s,$,/,
				       }
				       s/^.*	//')" \
693
			"$pfx" "$cur_" ""
694
		;;
695
	*...*)
696 697
		pfx="${cur_%...*}..."
		cur_="${cur_#*...}"
698
		__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
699 700
		;;
	*..*)
701 702
		pfx="${cur_%..*}.."
		cur_="${cur_#*..}"
703
		__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
704
		;;
705
	*)
706
		__gitcomp_nl "$(__git_refs)"
707 708 709 710
		;;
	esac
}

711 712 713 714 715 716 717 718 719 720 721

__git_complete_file ()
{
	__git_complete_revlist_file
}

__git_complete_revlist ()
{
	__git_complete_revlist_file
}

722 723
__git_complete_remote_or_refspec ()
{
724
	local cur_="$cur" cmd="${words[1]}"
725
	local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
726
	if [ "$cmd" = "remote" ]; then
727
		((c++))
728
	fi
729 730
	while [ $c -lt $cword ]; do
		i="${words[c]}"
731
		case "$i" in
732 733 734 735 736 737 738 739 740 741 742
		--mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
		--all)
			case "$cmd" in
			push) no_complete_refspec=1 ;;
			fetch)
				COMPREPLY=()
				return
				;;
			*) ;;
			esac
			;;
743 744 745
		-*) ;;
		*) remote="$i"; break ;;
		esac
746
		((c++))
747 748
	done
	if [ -z "$remote" ]; then
749
		__gitcomp_nl "$(__git_remotes)"
750 751
		return
	fi
752 753 754 755
	if [ $no_complete_refspec = 1 ]; then
		COMPREPLY=()
		return
	fi
756
	[ "$remote" = "." ] && remote=
757
	case "$cur_" in
758 759 760
	*:*)
		case "$COMP_WORDBREAKS" in
		*:*) : great ;;
761
		*)   pfx="${cur_%%:*}:" ;;
762
		esac
763
		cur_="${cur_#*:}"
764 765 766 767
		lhs=0
		;;
	+*)
		pfx="+"
768
		cur_="${cur_#+}"
769 770 771 772 773
		;;
	esac
	case "$cmd" in
	fetch)
		if [ $lhs = 1 ]; then
774
			__gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
775
		else
776
			__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
777 778
		fi
		;;
779
	pull|remote)
780
		if [ $lhs = 1 ]; then
781
			__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
782
		else
783
			__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
784 785 786 787
		fi
		;;
	push)
		if [ $lhs = 1 ]; then
788
			__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
789
		else
790
			__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
791 792 793 794 795
		fi
		;;
	esac
}

796 797
__git_complete_strategy ()
{
J
Jonathan Nieder 已提交
798
	__git_compute_merge_strategies
799
	case "$prev" in
800
	-s|--strategy)
J
Jonathan Nieder 已提交
801
		__gitcomp "$__git_merge_strategies"
802 803 804 805
		return 0
	esac
	case "$cur" in
	--strategy=*)
J
Jonathan Nieder 已提交
806
		__gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
807 808 809 810 811 812
		return 0
		;;
	esac
	return 1
}

J
Jonathan Nieder 已提交
813
__git_list_all_commands ()
814 815
{
	local i IFS=" "$'\n'
816
	for i in $(git help -a|egrep '^  [a-zA-Z0-9]')
817 818 819 820 821 822 823 824
	do
		case $i in
		*--*)             : helper pattern;;
		*) echo $i;;
		esac
	done
}

J
Jonathan Nieder 已提交
825 826 827
__git_all_commands=
__git_compute_all_commands ()
{
828 829
	test -n "$__git_all_commands" ||
	__git_all_commands=$(__git_list_all_commands)
J
Jonathan Nieder 已提交
830 831 832
}

__git_list_porcelain_commands ()
833 834
{
	local i IFS=" "$'\n'
J
Jonathan Nieder 已提交
835 836
	__git_compute_all_commands
	for i in "help" $__git_all_commands
837 838
	do
		case $i in
839
		*--*)             : helper pattern;;
840 841 842
		applymbox)        : ask gittus;;
		applypatch)       : ask gittus;;
		archimport)       : import;;
843
		cat-file)         : plumbing;;
844
		check-attr)       : plumbing;;
845
		check-ref-format) : plumbing;;
846
		checkout-index)   : plumbing;;
847
		commit-tree)      : plumbing;;
848
		count-objects)    : infrequent;;
849 850
		cvsexportcommit)  : export;;
		cvsimport)        : import;;
851 852
		cvsserver)        : daemon;;
		daemon)           : daemon;;
853 854 855
		diff-files)       : plumbing;;
		diff-index)       : plumbing;;
		diff-tree)        : plumbing;;
S
Shawn O. Pearce 已提交
856
		fast-import)      : import;;
857
		fast-export)      : export;;
858
		fsck-objects)     : plumbing;;
859
		fetch-pack)       : plumbing;;
860
		fmt-merge-msg)    : plumbing;;
861
		for-each-ref)     : plumbing;;
862 863 864
		hash-object)      : plumbing;;
		http-*)           : transport;;
		index-pack)       : plumbing;;
865
		init-db)          : deprecated;;
866
		local-fetch)      : plumbing;;
867 868 869 870
		lost-found)       : infrequent;;
		ls-files)         : plumbing;;
		ls-remote)        : plumbing;;
		ls-tree)          : plumbing;;
871 872 873 874 875 876 877 878 879 880 881
		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;;
882 883 884
		prune)            : plumbing;;
		prune-packed)     : plumbing;;
		quiltimport)      : import;;
885 886
		read-tree)        : plumbing;;
		receive-pack)     : plumbing;;
887
		remote-*)         : transport;;
888
		repo-config)      : deprecated;;
889 890 891 892 893 894
		rerere)           : plumbing;;
		rev-list)         : plumbing;;
		rev-parse)        : plumbing;;
		runstatus)        : plumbing;;
		sh-setup)         : internal;;
		shell)            : daemon;;
895
		show-ref)         : plumbing;;
896 897 898 899 900
		send-pack)        : plumbing;;
		show-index)       : plumbing;;
		ssh-*)            : transport;;
		stripspace)       : plumbing;;
		symbolic-ref)     : plumbing;;
901
		tar-tree)         : deprecated;;
902 903
		unpack-file)      : plumbing;;
		unpack-objects)   : plumbing;;
904
		update-index)     : plumbing;;
905 906 907 908 909
		update-ref)       : plumbing;;
		update-server-info) : daemon;;
		upload-archive)   : plumbing;;
		upload-pack)      : plumbing;;
		write-tree)       : plumbing;;
910 911
		var)              : infrequent;;
		verify-pack)      : infrequent;;
912
		verify-tag)       : plumbing;;
913 914 915 916
		*) echo $i;;
		esac
	done
}
J
Jonathan Nieder 已提交
917 918 919 920 921

__git_porcelain_commands=
__git_compute_porcelain_commands ()
{
	__git_compute_all_commands
922 923
	test -n "$__git_porcelain_commands" ||
	__git_porcelain_commands=$(__git_list_porcelain_commands)
J
Jonathan Nieder 已提交
924
}
925

926 927 928 929 930 931 932 933 934 935 936 937 938
__git_pretty_aliases ()
{
	local i IFS=$'\n'
	for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do
		case "$i" in
		pretty.*)
			i="${i#pretty.}"
			echo "${i/ */}"
			;;
		esac
	done
}

939 940
__git_aliases ()
{
941
	local i IFS=$'\n'
942
	for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
943 944 945 946 947 948
		case "$i" in
		alias.*)
			i="${i#alias.}"
			echo "${i/ */}"
			;;
		esac
949
	done
950 951
}

952
# __git_aliased_command requires 1 argument
953 954
__git_aliased_command ()
{
955
	local word cmdline=$(git --git-dir="$(__gitdir)" \
956
		config --get "alias.$1")
957
	for word in $cmdline; do
958
		case "$word" in
959 960
		\!gitk|gitk)
			echo "gitk"
961
			return
962
			;;
963 964 965 966 967 968
		\!*)	: shell command alias ;;
		-*)	: option ;;
		*=*)	: setting env ;;
		git)	: git itself ;;
		*)
			echo "$word"
969
			return
970
		esac
971 972 973
	done
}

974 975
# __git_find_on_cmdline requires 1 argument
__git_find_on_cmdline ()
976
{
977
	local word subcommand c=1
978 979
	while [ $c -lt $cword ]; do
		word="${words[c]}"
980 981 982 983 984 985
		for subcommand in $1; do
			if [ "$subcommand" = "$word" ]; then
				echo "$subcommand"
				return
			fi
		done
986
		((c++))
987 988 989
	done
}

990 991
__git_has_doubledash ()
{
992
	local c=1
993 994
	while [ $c -lt $cword ]; do
		if [ "--" = "${words[c]}" ]; then
995 996
			return 0
		fi
997
		((c++))
998 999 1000 1001
	done
	return 1
}

1002
__git_whitespacelist="nowarn warn error error-all fix"
1003 1004 1005

_git_am ()
{
1006
	local dir="$(__gitdir)"
1007
	if [ -d "$dir"/rebase-apply ]; then
1008
		__gitcomp "--skip --continue --resolved --abort"
1009 1010 1011 1012
		return
	fi
	case "$cur" in
	--whitespace=*)
1013
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1014 1015 1016
		return
		;;
	--*)
1017
		__gitcomp "
1018
			--3way --committer-date-is-author-date --ignore-date
1019
			--ignore-whitespace --ignore-space-change
1020
			--interactive --keep --no-utf8 --signoff --utf8
1021
			--whitespace= --scissors
1022
			"
1023 1024 1025 1026 1027 1028 1029 1030 1031
		return
	esac
	COMPREPLY=()
}

_git_apply ()
{
	case "$cur" in
	--whitespace=*)
1032
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1033 1034 1035
		return
		;;
	--*)
1036
		__gitcomp "
1037 1038 1039
			--stat --numstat --summary --check --index
			--cached --index-info --reverse --reject --unidiff-zero
			--apply --no-add --exclude=
1040
			--ignore-whitespace --ignore-space-change
1041
			--whitespace= --inaccurate-eof --verbose
1042
			"
1043 1044 1045 1046 1047
		return
	esac
	COMPREPLY=()
}

1048 1049
_git_add ()
{
1050 1051
	__git_has_doubledash && return

1052 1053
	case "$cur" in
	--*)
1054 1055
		__gitcomp "
			--interactive --refresh --patch --update --dry-run
1056
			--ignore-errors --intent-to-add
1057
			"
1058 1059 1060 1061 1062
		return
	esac
	COMPREPLY=()
}

1063 1064 1065 1066 1067 1068 1069 1070
_git_archive ()
{
	case "$cur" in
	--format=*)
		__gitcomp "$(git archive --list)" "" "${cur##--format=}"
		return
		;;
	--remote=*)
1071
		__gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
		return
		;;
	--*)
		__gitcomp "
			--format= --list --verbose
			--prefix= --remote= --exec=
			"
		return
		;;
	esac
	__git_complete_file
}

1085 1086
_git_bisect ()
{
1087 1088
	__git_has_doubledash && return

1089
	local subcommands="start bad good skip reset visualize replay log run"
1090
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
1091
	if [ -z "$subcommand" ]; then
1092 1093 1094 1095 1096
		if [ -f "$(__gitdir)"/BISECT_START ]; then
			__gitcomp "$subcommands"
		else
			__gitcomp "replay start"
		fi
1097 1098 1099
		return
	fi

1100
	case "$subcommand" in
1101
	bad|good|reset|skip|start)
1102
		__gitcomp_nl "$(__git_refs)"
1103 1104 1105 1106 1107 1108 1109
		;;
	*)
		COMPREPLY=()
		;;
	esac
}

1110 1111
_git_branch ()
{
1112
	local i c=1 only_local_ref="n" has_r="n"
1113

1114 1115
	while [ $c -lt $cword ]; do
		i="${words[c]}"
1116 1117 1118 1119
		case "$i" in
		-d|-m)	only_local_ref="y" ;;
		-r)	has_r="y" ;;
		esac
1120
		((c++))
1121 1122
	done

1123
	case "$cur" in
S
SZEDER Gábor 已提交
1124 1125 1126
	--*)
		__gitcomp "
			--color --no-color --verbose --abbrev= --no-abbrev
1127
			--track --no-track --contains --merged --no-merged
1128
			--set-upstream --edit-description --list
S
SZEDER Gábor 已提交
1129 1130
			"
		;;
1131 1132
	*)
		if [ $only_local_ref = "y" -a $has_r = "n" ]; then
1133
			__gitcomp_nl "$(__git_heads)"
1134
		else
1135
			__gitcomp_nl "$(__git_refs)"
1136 1137
		fi
		;;
S
SZEDER Gábor 已提交
1138
	esac
1139 1140
}

1141 1142
_git_bundle ()
{
1143 1144
	local cmd="${words[2]}"
	case "$cword" in
1145
	2)
1146 1147
		__gitcomp "create list-heads verify unbundle"
		;;
1148
	3)
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
		# looking for a file
		;;
	*)
		case "$cmd" in
			create)
				__git_complete_revlist
			;;
		esac
		;;
	esac
}

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

1165 1166 1167 1168 1169 1170 1171
	case "$cur" in
	--conflict=*)
		__gitcomp "diff3 merge" "" "${cur##--conflict=}"
		;;
	--*)
		__gitcomp "
			--quiet --ours --theirs --track --no-track --merge
1172
			--conflict= --orphan --patch
1173 1174 1175
			"
		;;
	*)
1176 1177 1178 1179 1180 1181
		# check if --track, --no-track, or --no-guess was specified
		# if so, disable DWIM mode
		local flags="--track --no-track --no-guess" track=1
		if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
			track=''
		fi
1182
		__gitcomp_nl "$(__git_refs '' $track)"
1183 1184
		;;
	esac
1185 1186
}

1187 1188 1189 1190 1191
_git_cherry ()
{
	__gitcomp "$(__git_refs)"
}

1192 1193 1194 1195
_git_cherry_pick ()
{
	case "$cur" in
	--*)
1196
		__gitcomp "--edit --no-commit"
1197 1198
		;;
	*)
1199
		__gitcomp_nl "$(__git_refs)"
1200 1201 1202 1203
		;;
	esac
}

1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
_git_clean ()
{
	__git_has_doubledash && return

	case "$cur" in
	--*)
		__gitcomp "--dry-run --quiet"
		return
		;;
	esac
	COMPREPLY=()
}

1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
_git_clone ()
{
	case "$cur" in
	--*)
		__gitcomp "
			--local
			--no-hardlinks
			--shared
			--reference
			--quiet
			--no-checkout
			--bare
			--mirror
			--origin
			--upload-pack
			--template=
			--depth
			"
		return
		;;
	esac
	COMPREPLY=()
}

1241 1242
_git_commit ()
{
1243 1244
	__git_has_doubledash && return

1245
	case "$cur" in
1246 1247 1248 1249 1250
	--cleanup=*)
		__gitcomp "default strip verbatim whitespace
			" "" "${cur##--cleanup=}"
		return
		;;
1251 1252
	--reuse-message=*|--reedit-message=*|\
	--fixup=*|--squash=*)
1253
		__gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1254 1255 1256 1257 1258 1259
		return
		;;
	--untracked-files=*)
		__gitcomp "all no normal" "" "${cur##--untracked-files=}"
		return
		;;
1260
	--*)
1261
		__gitcomp "
1262
			--all --author= --signoff --verify --no-verify
1263
			--edit --amend --include --only --interactive
1264 1265 1266
			--dry-run --reuse-message= --reedit-message=
			--reset-author --file= --message= --template=
			--cleanup= --untracked-files --untracked-files=
1267
			--verbose --quiet --fixup= --squash=
1268
			"
1269 1270 1271 1272 1273
		return
	esac
	COMPREPLY=()
}

1274 1275
_git_describe ()
{
1276 1277 1278 1279 1280 1281 1282 1283
	case "$cur" in
	--*)
		__gitcomp "
			--all --tags --contains --abbrev= --candidates=
			--exact-match --debug --long --match --always
			"
		return
	esac
1284
	__gitcomp_nl "$(__git_refs)"
1285 1286
}

1287
__git_diff_common_options="--stat --numstat --shortstat --summary
1288 1289
			--patch-with-stat --name-only --name-status --color
			--no-color --color-words --no-renames --check
1290
			--full-index --binary --abbrev --diff-filter=
1291
			--find-copies-harder
1292 1293
			--text --ignore-space-at-eol --ignore-space-change
			--ignore-all-space --exit-code --quiet --ext-diff
1294 1295
			--no-ext-diff
			--no-prefix --src-prefix= --dst-prefix=
1296
			--inter-hunk-context=
1297
			--patience
1298
			--raw
1299 1300
			--dirstat --dirstat= --dirstat-by-file
			--dirstat-by-file= --cumulative
1301 1302 1303 1304 1305 1306 1307 1308
"

_git_diff ()
{
	__git_has_doubledash && return

	case "$cur" in
	--*)
1309
		__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1310
			--base --ours --theirs --no-index
1311
			$__git_diff_common_options
1312
			"
1313 1314 1315
		return
		;;
	esac
1316
	__git_complete_revlist_file
1317 1318
}

1319
__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
1320
			tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3
1321 1322 1323 1324
"

_git_difftool ()
{
1325 1326
	__git_has_doubledash && return

1327 1328 1329 1330 1331 1332
	case "$cur" in
	--tool=*)
		__gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
		return
		;;
	--*)
1333 1334 1335 1336 1337
		__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
			--base --ours --theirs
			--no-renames --diff-filter= --find-copies-harder
			--relative --ignore-submodules
			--tool="
1338 1339 1340
		return
		;;
	esac
1341
	__git_complete_file
1342 1343
}

1344 1345
__git_fetch_options="
	--quiet --verbose --append --upload-pack --force --keep --depth=
1346
	--tags --no-tags --all --prune --dry-run
1347 1348
"

1349 1350
_git_fetch ()
{
1351 1352 1353 1354 1355 1356
	case "$cur" in
	--*)
		__gitcomp "$__git_fetch_options"
		return
		;;
	esac
1357
	__git_complete_remote_or_refspec
1358 1359
}

1360 1361 1362
_git_format_patch ()
{
	case "$cur" in
1363 1364 1365 1366 1367 1368
	--thread=*)
		__gitcomp "
			deep shallow
			" "" "${cur##--thread=}"
		return
		;;
1369
	--*)
1370
		__gitcomp "
1371
			--stdout --attach --no-attach --thread --thread=
1372 1373
			--output-directory
			--numbered --start-number
1374
			--numbered-files
1375
			--keep-subject
1376
			--signoff --signature --no-signature
1377
			--in-reply-to= --cc=
1378
			--full-index --binary
1379
			--not --all
1380
			--cover-letter
1381
			--no-prefix --src-prefix= --dst-prefix=
1382 1383
			--inline --suffix= --ignore-if-in-upstream
			--subject-prefix=
1384
			"
1385 1386 1387 1388 1389 1390
		return
		;;
	esac
	__git_complete_revlist
}

1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
_git_fsck ()
{
	case "$cur" in
	--*)
		__gitcomp "
			--tags --root --unreachable --cache --no-reflogs --full
			--strict --verbose --lost-found
			"
		return
		;;
	esac
	COMPREPLY=()
}

1405 1406 1407 1408
_git_gc ()
{
	case "$cur" in
	--*)
1409
		__gitcomp "--prune --aggressive"
1410 1411 1412 1413 1414 1415
		return
		;;
	esac
	COMPREPLY=()
}

1416 1417 1418 1419 1420
_git_gitk ()
{
	_gitk
}

1421 1422 1423 1424
__git_match_ctag() {
	awk "/^${1////\\/}/ { print \$1 }" "$2"
}

1425 1426 1427 1428 1429 1430 1431 1432 1433
_git_grep ()
{
	__git_has_doubledash && return

	case "$cur" in
	--*)
		__gitcomp "
			--cached
			--text --ignore-case --word-regexp --invert-match
1434
			--full-name --line-number
1435
			--extended-regexp --basic-regexp --fixed-strings
M
Michał Kiedrowicz 已提交
1436
			--perl-regexp
1437 1438
			--files-with-matches --name-only
			--files-without-match
1439
			--max-depth
1440 1441 1442 1443 1444 1445
			--count
			--and --or --not --all-match
			"
		return
		;;
	esac
1446

1447 1448 1449
	case "$cword,$prev" in
	2,*|*,-*)
		if test -r tags; then
J
Junio C Hamano 已提交
1450
			__gitcomp_nl "$(__git_match_ctag "$cur" tags)"
1451 1452 1453 1454 1455
			return
		fi
		;;
	esac

1456
	__gitcomp_nl "$(__git_refs)"
1457 1458
}

1459 1460 1461 1462 1463 1464 1465 1466
_git_help ()
{
	case "$cur" in
	--*)
		__gitcomp "--all --info --man --web"
		return
		;;
	esac
J
Jonathan Nieder 已提交
1467
	__git_compute_all_commands
1468
	__gitcomp "$__git_all_commands $(__git_aliases)
1469 1470
		attributes cli core-tutorial cvs-migration
		diffcore gitk glossary hooks ignore modules
J
Josh Triplett 已提交
1471
		namespaces repository-layout tutorial tutorial-2
1472
		workflows
1473
		"
1474 1475
}

1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492
_git_init ()
{
	case "$cur" in
	--shared=*)
		__gitcomp "
			false true umask group all world everybody
			" "" "${cur##--shared=}"
		return
		;;
	--*)
		__gitcomp "--quiet --bare --template= --shared --shared="
		return
		;;
	esac
	COMPREPLY=()
}

1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511
_git_ls_files ()
{
	__git_has_doubledash && return

	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=()
}

1512 1513
_git_ls_remote ()
{
1514
	__gitcomp_nl "$(__git_remotes)"
1515 1516 1517 1518 1519 1520 1521
}

_git_ls_tree ()
{
	__git_complete_file
}

1522 1523 1524 1525
# Options that go well for log, shortlog and gitk
__git_log_common_options="
	--not --all
	--branches --tags --remotes
1526
	--first-parent --merges --no-merges
1527 1528 1529
	--max-count=
	--max-age= --since= --after=
	--min-age= --until= --before=
1530 1531
	--min-parents= --max-parents=
	--no-min-parents --no-max-parents
1532 1533 1534 1535 1536
"
# Options that go well for log and gitk (not shortlog)
__git_log_gitk_options="
	--dense --sparse --full-history
	--simplify-merges --simplify-by-decoration
1537
	--left-right --notes --no-notes
1538 1539 1540 1541 1542 1543 1544
"
# Options that go well for log and shortlog (not gitk)
__git_log_shortlog_options="
	--author= --committer= --grep=
	--all-match
"

1545
__git_log_pretty_formats="oneline short medium full fuller email raw format:"
1546
__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1547

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

1552 1553
	local g="$(git rev-parse --git-dir 2>/dev/null)"
	local merge=""
1554
	if [ -f "$g/MERGE_HEAD" ]; then
1555 1556
		merge="--merge"
	fi
1557
	case "$cur" in
1558
	--pretty=*|--format=*)
1559
		__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
1560
			" "" "${cur#*=}"
1561 1562
		return
		;;
1563
	--date=*)
1564
		__gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1565 1566
		return
		;;
1567 1568 1569 1570
	--decorate=*)
		__gitcomp "long short" "" "${cur##--decorate=}"
		return
		;;
1571
	--*)
1572
		__gitcomp "
1573 1574 1575
			$__git_log_common_options
			$__git_log_shortlog_options
			$__git_log_gitk_options
1576
			--root --topo-order --date-order --reverse
1577
			--follow --full-diff
1578
			--abbrev-commit --abbrev=
1579
			--relative-date --date=
1580
			--pretty= --format= --oneline
1581
			--cherry-pick
1582
			--graph
1583
			--decorate --decorate=
1584
			--walk-reflogs
1585
			--parents --children
1586
			$merge
1587
			$__git_diff_common_options
1588
			--pickaxe-all --pickaxe-regex
1589
			"
1590 1591 1592
		return
		;;
	esac
1593
	__git_complete_revlist
1594 1595
}

1596 1597
__git_merge_options="
	--no-commit --no-stat --log --no-log --squash --strategy
1598
	--commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit
1599 1600
"

1601 1602
_git_merge ()
{
1603 1604
	__git_complete_strategy && return

1605 1606
	case "$cur" in
	--*)
1607
		__gitcomp "$__git_merge_options"
1608 1609
		return
	esac
1610
	__gitcomp_nl "$(__git_refs)"
1611 1612
}

1613 1614 1615 1616
_git_mergetool ()
{
	case "$cur" in
	--tool=*)
1617
		__gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627
		return
		;;
	--*)
		__gitcomp "--tool="
		return
		;;
	esac
	COMPREPLY=()
}

1628 1629
_git_merge_base ()
{
1630
	__gitcomp_nl "$(__git_refs)"
1631 1632
}

1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643
_git_mv ()
{
	case "$cur" in
	--*)
		__gitcomp "--dry-run"
		return
		;;
	esac
	COMPREPLY=()
}

1644 1645
_git_name_rev ()
{
1646
	__gitcomp "--tags --all --stdin"
1647 1648
}

1649 1650
_git_notes ()
{
1651 1652
	local subcommands='add append copy edit list prune remove show'
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
1653

1654 1655 1656 1657 1658
	case "$subcommand,$cur" in
	,--*)
		__gitcomp '--ref'
		;;
	,*)
1659
		case "$prev" in
1660
		--ref)
1661
			__gitcomp_nl "$(__git_refs)"
1662 1663 1664 1665 1666 1667
			;;
		*)
			__gitcomp "$subcommands --ref"
			;;
		esac
		;;
1668
	add,--reuse-message=*|append,--reuse-message=*|\
1669
	add,--reedit-message=*|append,--reedit-message=*)
1670
		__gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682
		;;
	add,--*|append,--*)
		__gitcomp '--file= --message= --reedit-message=
				--reuse-message='
		;;
	copy,--*)
		__gitcomp '--stdin'
		;;
	prune,--*)
		__gitcomp '--dry-run --verbose'
		;;
	prune,*)
1683 1684
		;;
	*)
1685
		case "$prev" in
1686 1687 1688
		-m|-F)
			;;
		*)
1689
			__gitcomp_nl "$(__git_refs)"
1690 1691
			;;
		esac
1692 1693 1694 1695
		;;
	esac
}

1696 1697
_git_pull ()
{
1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709
	__git_complete_strategy && return

	case "$cur" in
	--*)
		__gitcomp "
			--rebase --no-rebase
			$__git_merge_options
			$__git_fetch_options
		"
		return
		;;
	esac
1710
	__git_complete_remote_or_refspec
1711 1712 1713 1714
}

_git_push ()
{
1715
	case "$prev" in
1716
	--repo)
1717
		__gitcomp_nl "$(__git_remotes)"
1718 1719 1720 1721
		return
	esac
	case "$cur" in
	--repo=*)
1722
		__gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
1723 1724 1725 1726 1727
		return
		;;
	--*)
		__gitcomp "
			--all --mirror --tags --dry-run --force --verbose
T
Teemu Matilainen 已提交
1728
			--receive-pack= --repo= --set-upstream
1729 1730 1731 1732
		"
		return
		;;
	esac
1733
	__git_complete_remote_or_refspec
1734 1735
}

1736 1737
_git_rebase ()
{
1738
	local dir="$(__gitdir)"
1739
	if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1740
		__gitcomp "--continue --skip --abort"
1741 1742
		return
	fi
1743
	__git_complete_strategy && return
1744
	case "$cur" in
1745 1746 1747 1748
	--whitespace=*)
		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
		return
		;;
1749
	--*)
1750 1751 1752 1753 1754
		__gitcomp "
			--onto --merge --strategy --interactive
			--preserve-merges --stat --no-stat
			--committer-date-is-author-date --ignore-date
			--ignore-whitespace --whitespace=
1755
			--autosquash
1756 1757
			"

1758 1759
		return
	esac
1760
	__gitcomp_nl "$(__git_refs)"
1761 1762
}

1763 1764 1765 1766 1767 1768 1769 1770
_git_reflog ()
{
	local subcommands="show delete expire"
	local subcommand="$(__git_find_on_cmdline "$subcommands")"

	if [ -z "$subcommand" ]; then
		__gitcomp "$subcommands"
	else
1771
		__gitcomp_nl "$(__git_refs)"
1772 1773 1774
	fi
}

1775
__git_send_email_confirm_options="always never auto cc compose"
1776
__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1777

1778 1779 1780
_git_send_email ()
{
	case "$cur" in
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797
	--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
		;;
1798
	--*)
1799
		__gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1800 1801
			--compose --confirm= --dry-run --envelope-sender
			--from --identity
1802 1803 1804
			--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
1805 1806
			--smtp-server-port --smtp-encryption= --smtp-user
			--subject --suppress-cc= --suppress-from --thread --to
1807
			--validate --no-validate"
1808 1809 1810 1811 1812 1813
		return
		;;
	esac
	COMPREPLY=()
}

1814 1815 1816 1817 1818
_git_stage ()
{
	_git_add
}

1819 1820
__git_config_get_set_variables ()
{
1821
	local prevword word config_file= c=$cword
1822
	while [ $c -gt 1 ]; do
1823
		word="${words[c]}"
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837
		case "$word" in
		--global|--system|--file=*)
			config_file="$word"
			break
			;;
		-f|--file)
			config_file="$word $prevword"
			break
			;;
		esac
		prevword=$word
		c=$((--c))
	done

1838
	git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1839
	while read -r line
1840 1841 1842 1843
	do
		case "$line" in
		*.*=*)
			echo "${line/=*/}"
1844 1845 1846 1847 1848
			;;
		esac
	done
}

1849
_git_config ()
1850
{
1851
	case "$prev" in
1852
	branch.*.remote)
1853
		__gitcomp_nl "$(__git_remotes)"
1854 1855 1856
		return
		;;
	branch.*.merge)
1857
		__gitcomp_nl "$(__git_refs)"
1858 1859 1860
		return
		;;
	remote.*.fetch)
1861
		local remote="${prev#remote.}"
1862
		remote="${remote%.fetch}"
1863 1864 1865 1866
		if [ -z "$cur" ]; then
			COMPREPLY=("refs/heads/")
			return
		fi
1867
		__gitcomp_nl "$(__git_refs_remotes "$remote")"
1868 1869 1870
		return
		;;
	remote.*.push)
1871
		local remote="${prev#remote.}"
1872
		remote="${remote%.push}"
1873
		__gitcomp_nl "$(git --git-dir="$(__gitdir)" \
1874
			for-each-ref --format='%(refname):%(refname)' \
1875 1876 1877 1878
			refs/heads)"
		return
		;;
	pull.twohead|pull.octopus)
J
Jonathan Nieder 已提交
1879 1880
		__git_compute_merge_strategies
		__gitcomp "$__git_merge_strategies"
1881 1882
		return
		;;
1883 1884
	color.branch|color.diff|color.interactive|\
	color.showbranch|color.status|color.ui)
1885 1886 1887
		__gitcomp "always never auto"
		return
		;;
1888 1889 1890 1891
	color.pager)
		__gitcomp "false true"
		return
		;;
1892 1893
	color.*.*)
		__gitcomp "
1894
			normal black red green yellow blue magenta cyan white
1895 1896
			bold dim ul blink reverse
			"
1897 1898
		return
		;;
1899 1900 1901 1902
	help.format)
		__gitcomp "man info web html"
		return
		;;
1903 1904 1905 1906
	log.date)
		__gitcomp "$__git_log_date_formats"
		return
		;;
1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918
	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
		;;
1919
	--get|--get-all|--unset|--unset-all)
1920
		__gitcomp_nl "$(__git_config_get_set_variables)"
1921 1922
		return
		;;
1923 1924 1925 1926 1927 1928 1929
	*.*)
		COMPREPLY=()
		return
		;;
	esac
	case "$cur" in
	--*)
1930
		__gitcomp "
1931
			--global --system --file=
1932
			--list --replace-all
1933
			--get --get-all --get-regexp
1934
			--add --unset --unset-all
1935
			--remove-section --rename-section
1936
			"
1937 1938 1939
		return
		;;
	branch.*.*)
1940 1941
		local pfx="${cur%.*}." cur_="${cur##*.}"
		__gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur_"
1942 1943 1944
		return
		;;
	branch.*)
1945
		local pfx="${cur%.*}." cur_="${cur#*.}"
1946
		__gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
1947 1948
		return
		;;
1949
	guitool.*.*)
1950
		local pfx="${cur%.*}." cur_="${cur##*.}"
1951 1952 1953
		__gitcomp "
			argprompt cmd confirm needsfile noconsole norescan
			prompt revprompt revunmerged title
1954
			" "$pfx" "$cur_"
1955 1956 1957
		return
		;;
	difftool.*.*)
1958 1959
		local pfx="${cur%.*}." cur_="${cur##*.}"
		__gitcomp "cmd path" "$pfx" "$cur_"
1960 1961 1962
		return
		;;
	man.*.*)
1963 1964
		local pfx="${cur%.*}." cur_="${cur##*.}"
		__gitcomp "cmd path" "$pfx" "$cur_"
1965 1966 1967
		return
		;;
	mergetool.*.*)
1968 1969
		local pfx="${cur%.*}." cur_="${cur##*.}"
		__gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
1970 1971 1972
		return
		;;
	pager.*)
1973
		local pfx="${cur%.*}." cur_="${cur#*.}"
J
Jonathan Nieder 已提交
1974
		__git_compute_all_commands
1975
		__gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
1976 1977
		return
		;;
1978
	remote.*.*)
1979
		local pfx="${cur%.*}." cur_="${cur##*.}"
1980
		__gitcomp "
1981
			url proxy fetch push mirror skipDefaultUpdate
1982
			receivepack uploadpack tagopt pushurl
1983
			" "$pfx" "$cur_"
1984 1985 1986
		return
		;;
	remote.*)
1987
		local pfx="${cur%.*}." cur_="${cur#*.}"
1988
		__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
1989 1990
		return
		;;
1991
	url.*.*)
1992 1993
		local pfx="${cur%.*}." cur_="${cur##*.}"
		__gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
1994 1995
		return
		;;
1996
	esac
1997
	__gitcomp "
1998 1999 2000 2001 2002 2003 2004
		add.ignoreErrors
		advice.commitBeforeMerge
		advice.detachedHead
		advice.implicitIdentity
		advice.pushNonFastForward
		advice.resolveConflict
		advice.statusHints
2005
		alias.
2006
		am.keepcr
2007
		apply.ignorewhitespace
2008
		apply.whitespace
2009 2010
		branch.autosetupmerge
		branch.autosetuprebase
2011
		browser.
2012
		clean.requireForce
2013 2014 2015 2016
		color.branch
		color.branch.current
		color.branch.local
		color.branch.plain
2017
		color.branch.remote
2018 2019 2020 2021 2022
		color.decorate.HEAD
		color.decorate.branch
		color.decorate.remoteBranch
		color.decorate.stash
		color.decorate.tag
2023
		color.diff
2024
		color.diff.commit
2025
		color.diff.frag
2026
		color.diff.func
2027
		color.diff.meta
2028
		color.diff.new
2029 2030
		color.diff.old
		color.diff.plain
2031
		color.diff.whitespace
2032
		color.grep
2033 2034 2035 2036
		color.grep.context
		color.grep.filename
		color.grep.function
		color.grep.linenumber
2037
		color.grep.match
2038 2039
		color.grep.selected
		color.grep.separator
2040
		color.interactive
2041
		color.interactive.error
2042 2043 2044
		color.interactive.header
		color.interactive.help
		color.interactive.prompt
2045
		color.pager
2046
		color.showbranch
2047
		color.status
2048 2049
		color.status.added
		color.status.changed
2050
		color.status.header
2051
		color.status.nobranch
2052
		color.status.untracked
2053 2054
		color.status.updated
		color.ui
2055
		commit.status
2056
		commit.template
2057
		core.abbrev
2058 2059
		core.askpass
		core.attributesfile
2060 2061
		core.autocrlf
		core.bare
2062
		core.bigFileThreshold
2063
		core.compression
2064
		core.createObject
2065 2066
		core.deltaBaseCacheLimit
		core.editor
2067
		core.eol
2068
		core.excludesfile
2069
		core.fileMode
2070
		core.fsyncobjectfiles
2071
		core.gitProxy
2072
		core.ignoreCygwinFSTricks
2073
		core.ignoreStat
2074
		core.ignorecase
2075 2076
		core.logAllRefUpdates
		core.loosecompression
2077
		core.notesRef
2078 2079
		core.packedGitLimit
		core.packedGitWindowSize
2080
		core.pager
2081
		core.preferSymlinkRefs
2082 2083
		core.preloadindex
		core.quotepath
2084
		core.repositoryFormatVersion
2085
		core.safecrlf
2086
		core.sharedRepository
2087
		core.sparseCheckout
2088 2089
		core.symlinks
		core.trustctime
2090
		core.warnAmbiguousRefs
2091 2092 2093
		core.whitespace
		core.worktree
		diff.autorefreshindex
2094
		diff.statGraphWidth
2095
		diff.external
2096
		diff.ignoreSubmodules
2097
		diff.mnemonicprefix
2098
		diff.noprefix
2099 2100
		diff.renameLimit
		diff.renames
2101 2102 2103
		diff.suppressBlankEmpty
		diff.tool
		diff.wordRegex
2104
		difftool.
2105
		difftool.prompt
2106
		fetch.recurseSubmodules
2107
		fetch.unpackLimit
2108 2109
		format.attach
		format.cc
2110
		format.headers
2111 2112
		format.numbered
		format.pretty
2113
		format.signature
2114 2115
		format.signoff
		format.subjectprefix
2116
		format.suffix
2117
		format.thread
2118 2119
		format.to
		gc.
2120 2121 2122
		gc.aggressiveWindow
		gc.auto
		gc.autopacklimit
2123
		gc.packrefs
2124
		gc.pruneexpire
2125 2126 2127 2128
		gc.reflogexpire
		gc.reflogexpireunreachable
		gc.rerereresolved
		gc.rerereunresolved
2129
		gitcvs.allbinary
2130
		gitcvs.commitmsgannotation
2131
		gitcvs.dbTableNamePrefix
2132 2133 2134 2135 2136 2137
		gitcvs.dbdriver
		gitcvs.dbname
		gitcvs.dbpass
		gitcvs.dbuser
		gitcvs.enabled
		gitcvs.logfile
2138
		gitcvs.usecrlfattr
2139
		guitool.
2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153
		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
2154 2155
		http.lowSpeedLimit
		http.lowSpeedTime
2156
		http.maxRequests
2157
		http.minSessions
2158
		http.noEPSV
2159
		http.postBuffer
2160
		http.proxy
2161 2162 2163
		http.sslCAInfo
		http.sslCAPath
		http.sslCert
2164
		http.sslCertPasswordProtected
2165 2166
		http.sslKey
		http.sslVerify
2167
		http.useragent
2168 2169
		i18n.commitEncoding
		i18n.logOutputEncoding
2170
		imap.authMethod
2171 2172 2173 2174 2175 2176 2177 2178
		imap.folder
		imap.host
		imap.pass
		imap.port
		imap.preformattedHTML
		imap.sslverify
		imap.tunnel
		imap.user
2179
		init.templatedir
2180 2181 2182 2183 2184
		instaweb.browser
		instaweb.httpd
		instaweb.local
		instaweb.modulepath
		instaweb.port
2185
		interactive.singlekey
2186
		log.date
2187
		log.decorate
2188
		log.showroot
2189
		mailmap.file
2190
		man.
2191
		man.viewer
2192
		merge.
2193 2194 2195
		merge.conflictstyle
		merge.log
		merge.renameLimit
2196
		merge.renormalize
2197
		merge.stat
2198
		merge.tool
2199
		merge.verbosity
2200
		mergetool.
2201
		mergetool.keepBackup
2202
		mergetool.keepTemporaries
2203
		mergetool.prompt
2204 2205 2206 2207 2208 2209
		notes.displayRef
		notes.rewrite.
		notes.rewrite.amend
		notes.rewrite.rebase
		notes.rewriteMode
		notes.rewriteRef
2210 2211
		pack.compression
		pack.deltaCacheLimit
2212 2213
		pack.deltaCacheSize
		pack.depth
2214 2215 2216
		pack.indexVersion
		pack.packSizeLimit
		pack.threads
2217 2218
		pack.window
		pack.windowMemory
2219
		pager.
2220
		pretty.
2221 2222
		pull.octopus
		pull.twohead
2223
		push.default
2224
		rebase.autosquash
2225
		rebase.stat
2226
		receive.autogc
2227
		receive.denyCurrentBranch
2228
		receive.denyDeleteCurrent
2229
		receive.denyDeletes
2230
		receive.denyNonFastForwards
2231
		receive.fsckObjects
2232
		receive.unpackLimit
2233 2234
		receive.updateserverinfo
		remotes.
2235 2236 2237
		repack.usedeltabaseoffset
		rerere.autoupdate
		rerere.enabled
2238
		sendemail.
2239
		sendemail.aliasesfile
2240
		sendemail.aliasfiletype
2241 2242 2243 2244 2245 2246
		sendemail.bcc
		sendemail.cc
		sendemail.cccmd
		sendemail.chainreplyto
		sendemail.confirm
		sendemail.envelopesender
2247 2248
		sendemail.from
		sendemail.identity
2249 2250
		sendemail.multiedit
		sendemail.signedoffbycc
2251
		sendemail.smtpdomain
2252 2253 2254
		sendemail.smtpencryption
		sendemail.smtppass
		sendemail.smtpserver
2255
		sendemail.smtpserveroption
2256 2257 2258 2259 2260 2261 2262
		sendemail.smtpserverport
		sendemail.smtpuser
		sendemail.suppresscc
		sendemail.suppressfrom
		sendemail.thread
		sendemail.to
		sendemail.validate
2263
		showbranch.default
2264 2265
		status.relativePaths
		status.showUntrackedFiles
2266 2267
		status.submodulesummary
		submodule.
2268 2269
		tar.umask
		transfer.unpackLimit
2270
		url.
2271
		user.email
2272
		user.name
2273
		user.signingkey
2274
		web.browser
2275
		branch. remote.
2276
	"
2277 2278
}

2279 2280
_git_remote ()
{
2281
	local subcommands="add rename rm set-head set-branches set-url show prune update"
2282
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
2283
	if [ -z "$subcommand" ]; then
2284
		__gitcomp "$subcommands"
2285 2286 2287
		return
	fi

2288
	case "$subcommand" in
2289
	rename|rm|set-url|show|prune)
2290
		__gitcomp_nl "$(__git_remotes)"
2291
		;;
2292 2293 2294
	set-head|set-branches)
		__git_complete_remote_or_refspec
		;;
2295 2296
	update)
		local i c='' IFS=$'\n'
2297 2298 2299
		for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
			i="${i#remotes.}"
			c="$c ${i/ */}"
2300 2301 2302
		done
		__gitcomp "$c"
		;;
2303 2304 2305 2306 2307 2308
	*)
		COMPREPLY=()
		;;
	esac
}

2309 2310
_git_replace ()
{
2311
	__gitcomp_nl "$(__git_refs)"
2312 2313
}

2314 2315
_git_reset ()
{
2316 2317
	__git_has_doubledash && return

2318 2319
	case "$cur" in
	--*)
S
SZEDER Gábor 已提交
2320
		__gitcomp "--merge --mixed --hard --soft --patch"
2321 2322 2323
		return
		;;
	esac
2324
	__gitcomp_nl "$(__git_refs)"
2325 2326
}

2327 2328 2329 2330 2331 2332 2333 2334
_git_revert ()
{
	case "$cur" in
	--*)
		__gitcomp "--edit --mainline --no-edit --no-commit --signoff"
		return
		;;
	esac
2335
	__gitcomp_nl "$(__git_refs)"
2336 2337
}

2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
_git_rm ()
{
	__git_has_doubledash && return

	case "$cur" in
	--*)
		__gitcomp "--cached --dry-run --ignore-unmatch --quiet"
		return
		;;
	esac
	COMPREPLY=()
}

2351 2352
_git_shortlog ()
{
2353 2354
	__git_has_doubledash && return

2355 2356 2357
	case "$cur" in
	--*)
		__gitcomp "
2358 2359
			$__git_log_common_options
			$__git_log_shortlog_options
2360 2361 2362 2363 2364 2365 2366 2367
			--numbered --summary
			"
		return
		;;
	esac
	__git_complete_revlist
}

2368 2369
_git_show ()
{
2370 2371
	__git_has_doubledash && return

2372
	case "$cur" in
2373
	--pretty=*|--format=*)
2374
		__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
2375
			" "" "${cur#*=}"
2376 2377
		return
		;;
2378
	--*)
2379
		__gitcomp "--pretty= --format= --abbrev-commit --oneline
2380 2381
			$__git_diff_common_options
			"
2382 2383 2384 2385 2386 2387
		return
		;;
	esac
	__git_complete_file
}

2388 2389 2390 2391 2392 2393 2394
_git_show_branch ()
{
	case "$cur" in
	--*)
		__gitcomp "
			--all --remotes --topo-order --current --more=
			--list --independent --merge-base --no-name
2395
			--color --no-color
2396
			--sha1-name --sparse --topics --reflog
2397 2398 2399 2400 2401 2402 2403
			"
		return
		;;
	esac
	__git_complete_revlist
}

J
Junio C Hamano 已提交
2404 2405
_git_stash ()
{
2406
	local save_opts='--keep-index --no-keep-index --quiet --patch'
2407
	local subcommands='save list show apply clear drop pop create branch'
2408
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
2409
	if [ -z "$subcommand" ]; then
2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421
		case "$cur" in
		--*)
			__gitcomp "$save_opts"
			;;
		*)
			if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
				__gitcomp "$subcommands"
			else
				COMPREPLY=()
			fi
			;;
		esac
2422 2423 2424
	else
		case "$subcommand,$cur" in
		save,--*)
2425
			__gitcomp "$save_opts"
2426
			;;
2427
		apply,--*|pop,--*)
2428
			__gitcomp "--index --quiet"
2429
			;;
2430
		show,--*|drop,--*|branch,--*)
2431 2432 2433
			COMPREPLY=()
			;;
		show,*|apply,*|drop,*|pop,*|branch,*)
2434
			__gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
2435 2436
					| sed -n -e 's/:.*//p')"
			;;
2437 2438 2439 2440
		*)
			COMPREPLY=()
			;;
		esac
2441
	fi
J
Junio C Hamano 已提交
2442 2443
}

2444 2445
_git_submodule ()
{
2446 2447
	__git_has_doubledash && return

2448
	local subcommands="add status init update summary foreach sync"
2449
	if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
2450 2451 2452 2453 2454
		case "$cur" in
		--*)
			__gitcomp "--quiet --cached"
			;;
		*)
2455
			__gitcomp "$subcommands"
2456 2457 2458 2459 2460 2461
			;;
		esac
		return
	fi
}

2462 2463 2464 2465 2466
_git_svn ()
{
	local subcommands="
		init fetch clone rebase dcommit log find-rev
		set-tree commit-diff info create-ignore propget
S
SZEDER Gábor 已提交
2467
		proplist show-ignore show-externals branch tag blame
2468
		migrate mkdirs reset gc
2469
		"
2470
	local subcommand="$(__git_find_on_cmdline "$subcommands")"
2471 2472 2473 2474 2475 2476 2477 2478
	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 已提交
2479 2480
			--repack-flags --use-log-author --localtime
			--ignore-paths= $remote_opts
2481 2482 2483 2484 2485
			"
		local init_opts="
			--template= --shared= --trunk= --tags=
			--branches= --stdlayout --minimize-url
			--no-metadata --use-svm-props --use-svnsync-props
S
SZEDER Gábor 已提交
2486 2487
			--rewrite-root= --prefix= --use-log-author
			--add-author-from $remote_opts
2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505
			"
		local cmt_opts="
			--edit --rmdir --find-copies-harder --copy-similarity=
			"

		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 已提交
2506
				--fetch-all --no-rebase --commit-url
2507
				--revision --interactive $cmt_opts $fc_opts
2508 2509 2510 2511 2512 2513
				"
			;;
		set-tree,--*)
			__gitcomp "--stdin $cmt_opts $fc_opts"
			;;
		create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
2514
		show-externals,--*|mkdirs,--*)
2515 2516 2517 2518 2519 2520
			__gitcomp "--revision="
			;;
		log,--*)
			__gitcomp "
				--limit= --revision= --verbose --incremental
				--oneline --show-commit --non-recursive
S
SZEDER Gábor 已提交
2521
				--authors-file= --color
2522 2523 2524 2525 2526
				"
			;;
		rebase,--*)
			__gitcomp "
				--merge --verbose --strategy= --local
S
SZEDER Gábor 已提交
2527
				--fetch-all --dry-run $fc_opts
2528 2529 2530 2531 2532 2533 2534 2535
				"
			;;
		commit-diff,--*)
			__gitcomp "--message= --file= --revision= $cmt_opts"
			;;
		info,--*)
			__gitcomp "--url"
			;;
S
SZEDER Gábor 已提交
2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550
		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=
				"
			;;
2551 2552 2553
		reset,--*)
			__gitcomp "--revision= --parent"
			;;
2554 2555 2556 2557 2558 2559 2560
		*)
			COMPREPLY=()
			;;
		esac
	fi
}

2561 2562 2563
_git_tag ()
{
	local i c=1 f=0
2564 2565
	while [ $c -lt $cword ]; do
		i="${words[c]}"
2566 2567
		case "$i" in
		-d|-v)
2568
			__gitcomp_nl "$(__git_tags)"
2569 2570 2571 2572 2573 2574
			return
			;;
		-f)
			f=1
			;;
		esac
2575
		((c++))
2576 2577
	done

2578
	case "$prev" in
2579 2580 2581
	-m|-F)
		COMPREPLY=()
		;;
2582
	-*|tag)
2583
		if [ $f = 1 ]; then
2584
			__gitcomp_nl "$(__git_tags)"
2585 2586 2587 2588 2589
		else
			COMPREPLY=()
		fi
		;;
	*)
2590
		__gitcomp_nl "$(__git_refs)"
2591 2592 2593 2594
		;;
	esac
}

2595 2596 2597 2598 2599
_git_whatchanged ()
{
	_git_log
}

2600
_main_git ()
2601
{
2602 2603
	local i c=1 command __git_dir

2604 2605
	while [ $c -lt $cword ]; do
		i="${words[c]}"
2606 2607 2608
		case "$i" in
		--git-dir=*) __git_dir="${i#--git-dir=}" ;;
		--bare)      __git_dir="." ;;
2609
		--help) command="help"; break ;;
2610 2611
		-c) c=$((++c)) ;;
		-*) ;;
2612 2613
		*) command="$i"; break ;;
		esac
2614
		((c++))
2615 2616
	done

2617
	if [ -z "$command" ]; then
2618
		case "$cur" in
2619
		--*)   __gitcomp "
2620
			--paginate
2621 2622 2623 2624 2625
			--no-pager
			--git-dir=
			--bare
			--version
			--exec-path
2626
			--exec-path=
2627
			--html-path
2628
			--info-path
2629
			--work-tree=
J
Josh Triplett 已提交
2630
			--namespace=
2631
			--no-replace-objects
2632
			--help
2633 2634
			"
			;;
J
Jonathan Nieder 已提交
2635 2636
		*)     __git_compute_porcelain_commands
		       __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2637 2638
		esac
		return
2639
	fi
2640

2641
	local completion_func="_git_${command//-/_}"
2642
	declare -f $completion_func >/dev/null && $completion_func && return
2643

2644
	local expansion=$(__git_aliased_command "$command")
2645 2646
	if [ -n "$expansion" ]; then
		completion_func="_git_${expansion//-/_}"
2647
		declare -f $completion_func >/dev/null && $completion_func
2648
	fi
2649 2650
}

2651
_main_gitk ()
2652
{
2653 2654
	__git_has_doubledash && return

2655
	local g="$(__gitdir)"
2656
	local merge=""
2657
	if [ -f "$g/MERGE_HEAD" ]; then
2658 2659
		merge="--merge"
	fi
2660 2661
	case "$cur" in
	--*)
2662 2663 2664 2665 2666
		__gitcomp "
			$__git_log_common_options
			$__git_log_gitk_options
			$merge
			"
2667 2668 2669
		return
		;;
	esac
2670
	__git_complete_revlist
2671 2672
}

2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702
__git_func_wrap ()
{
	if [[ -n ${ZSH_VERSION-} ]]; then
		emulate -L bash
		setopt KSH_TYPESET

		# workaround zsh's bug that leaves 'words' as a special
		# variable in versions < 4.3.12
		typeset -h words

		# workaround zsh's bug that quotes spaces in the COMPREPLY
		# array if IFS doesn't contain spaces.
		typeset -h IFS
	fi
	local cur words cword prev
	_get_comp_words_by_ref -n =: cur words cword prev
	$1
}

# Setup completion for certain functions defined above by setting common
# variables and workarounds.
# This is NOT a public function; use at your own risk.
__git_complete ()
{
	local wrapper="__git_wrap${2}"
	eval "$wrapper () { __git_func_wrap $2 ; }"
	complete -o bashdefault -o default -o nospace -F $wrapper $1 2>/dev/null \
		|| complete -o default -o nospace -F $wrapper $1
}

2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714
# wrapper for backwards compatibility
_git ()
{
	__git_wrap_main_git
}

# wrapper for backwards compatibility
_gitk ()
{
	__git_wrap_main_gitk
}

2715 2716
__git_complete git _main_git
__git_complete gitk _main_gitk
2717 2718 2719 2720 2721

# 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.
#
2722
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
2723
__git_complete git.exe _main_git
2724
fi